mirror of
https://git.FreeBSD.org/ports.git
synced 2025-01-23 09:10:43 +00:00
Rework the dependency discovery and update code, as well as the handling
of installed ports and status (up-to-date / out-of-date) reporting. This should make porteasy slightly more consistent, and up to 25% faster.
This commit is contained in:
parent
b4ea2e3445
commit
53901eee90
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=105970
@ -8,8 +8,7 @@
|
||||
#
|
||||
|
||||
PORTNAME= porteasy
|
||||
PORTVERSION= 2.7.12
|
||||
PORTREVISION= 1
|
||||
PORTVERSION= 2.7.13
|
||||
CATEGORIES= misc
|
||||
MASTER_SITES= # none
|
||||
DISTFILES= # none
|
||||
|
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 2, 2004
|
||||
.Dd April 02, 2004
|
||||
.Dt PORTEASY 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -89,7 +89,25 @@ Specify the ports directory (normally
|
||||
.It Fl r Ar dir
|
||||
Specify the CVS root directory.
|
||||
.It Fl s
|
||||
List installed ports and their status.
|
||||
Indicate the installation status of the selected ports.
|
||||
Each selected port is listed with a symbol indicating its status:
|
||||
.Bl -tag -width 3n
|
||||
.It Ql \&!
|
||||
Not installed.
|
||||
.It Ql " "
|
||||
Up-to-date.
|
||||
.It Ql \&<
|
||||
Older than the version in the ports tree.
|
||||
.It Ql \&>
|
||||
Newer than the version in the ports tree.
|
||||
.El
|
||||
.Pp
|
||||
If the
|
||||
.Fl s
|
||||
option is specified and no ports are specified on the command line,
|
||||
all installed ports are selected as if the
|
||||
.Fl I
|
||||
option had been specified.
|
||||
.It Fl t Ar tag
|
||||
Specify a tag to use for
|
||||
.Xr cvs 1
|
||||
@ -153,8 +171,10 @@ If a certain match is not found,
|
||||
.Nm
|
||||
prints a list of possible matches and exits.
|
||||
.Pp
|
||||
All direct and indirect dependencies of the ports listed on the
|
||||
command line are also selected and marked as dependencies.
|
||||
All direct and indirect dependencies (except, if the
|
||||
.Fl e option was specified,
|
||||
those that are already installed) are also selected and marked as
|
||||
dependencies.
|
||||
.It Update ports tree and discover dependencies
|
||||
If the
|
||||
.Fl u
|
||||
@ -172,8 +192,8 @@ option was specified,
|
||||
.Nm
|
||||
checks to see if any of the selected ports are already installed;
|
||||
those that are are deselected.
|
||||
This process is not very accurate, as it will not detect if an older
|
||||
or alternate version of a selected port is installed.
|
||||
This process is not very accurate, as it sometimes fails to detect
|
||||
that an older or alternate version of a selected port is installed.
|
||||
.It List selected ports
|
||||
If the
|
||||
.Fl l
|
||||
@ -183,9 +203,7 @@ Explicitly selected ports are indicated with a star.
|
||||
.It List installed ports
|
||||
If the
|
||||
.Fl s
|
||||
option was specified, all installed ports are listed with their status
|
||||
('<' for ports that are older than the version in the tree, '>' for
|
||||
those that are newer, '?' for those that could not be identified).
|
||||
option was specified, all selected ports are listed with their status.
|
||||
.It Show packing lists
|
||||
If the
|
||||
.Fk L
|
||||
|
@ -26,14 +26,14 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
use strict;
|
||||
use Fcntl;
|
||||
use Getopt::Long;
|
||||
|
||||
my $VERSION = "2.7.12";
|
||||
my $VERSION = "2.7.13";
|
||||
my $COPYRIGHT = "Copyright (c) 2000-2004 Dag-Erling Smørgrav. " .
|
||||
"All rights reserved.";
|
||||
|
||||
@ -41,7 +41,6 @@ my $COPYRIGHT = "Copyright (c) 2000-2004 Dag-Erling Sm
|
||||
sub ANONCVS_ROOT { ":pserver:anoncvs\@anoncvs.FreeBSD.org:/home/ncvs" }
|
||||
sub REQ_EXPLICIT { 1 }
|
||||
sub REQ_IMPLICIT { 2 }
|
||||
sub REQ_MASTER { 4 }
|
||||
|
||||
sub CVS_PASSFILE { "%%PREFIX%%/share/porteasy/cvspass" }
|
||||
|
||||
@ -459,8 +458,8 @@ sub add_port($$) {
|
||||
} else {
|
||||
$realport = find_port($port);
|
||||
}
|
||||
$realport = find_moved($realport);
|
||||
}
|
||||
$realport = find_moved($realport);
|
||||
if (!$realport) {
|
||||
return 1;
|
||||
}
|
||||
@ -495,13 +494,15 @@ sub get_origin($) {
|
||||
warn("$port has no known origin\n");
|
||||
return undef;
|
||||
}
|
||||
info("$port -> $origin\n");
|
||||
$origin = find_moved($origin);
|
||||
return $origin;
|
||||
}
|
||||
|
||||
#
|
||||
# Select installed ports
|
||||
# Get list of installed ports
|
||||
#
|
||||
sub add_installed() {
|
||||
sub get_installed() {
|
||||
|
||||
local *DIR; # Directory handle
|
||||
my $port; # Installed port
|
||||
@ -514,8 +515,13 @@ sub add_installed() {
|
||||
if (!defined($origin = get_origin($port))) {
|
||||
bsd::warnx("$port has no known origin");
|
||||
} else {
|
||||
$installed{$port} = $origin;
|
||||
add_port($origin, &REQ_EXPLICIT);
|
||||
if ($installed{$origin}) {
|
||||
bsd::warnx("$origin is already installed as " .
|
||||
join(', ', @{$installed{$origin}}));
|
||||
} else {
|
||||
$installed{$origin} = [ ];
|
||||
}
|
||||
push(@{$installed{$origin}}, $port);
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
@ -536,7 +542,7 @@ sub find_master($) {
|
||||
# Look for MASTERDIR in the Makefile. We can't use 'make -V'
|
||||
# because the Makefile might try to include the master port's
|
||||
# Makefile, which might not be checked out yet.
|
||||
open(FILE, "$portsdir/$port/Makefile")
|
||||
sysopen(FILE, "$portsdir/$port/Makefile", O_RDONLY)
|
||||
or bsd::err(1, "unable to read Makefile for $port");
|
||||
while (<FILE>) {
|
||||
my $master; # Master directory
|
||||
@ -589,20 +595,23 @@ sub find_library($) {
|
||||
}
|
||||
|
||||
#
|
||||
# Find a binary
|
||||
# Find a file
|
||||
#
|
||||
sub find_binary($) {
|
||||
my $binary = shift; # Binary to find
|
||||
sub find_file($) {
|
||||
my $file = shift; # File to find
|
||||
|
||||
my $dir; # Directory
|
||||
|
||||
if ($binary =~ m|^/|) {
|
||||
info("$binary is installed as $binary");
|
||||
return (-x $binary);
|
||||
if ($file =~ m|^/|) {
|
||||
if (-e $file) {
|
||||
info("$file is installed");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
foreach $dir (split(/:/, $ENV{'PATH'})) {
|
||||
if (-x "$dir/$binary") {
|
||||
info("$binary is installed as $dir/$binary");
|
||||
if (-x "$dir/$file") {
|
||||
info("$file is installed as $dir/$file");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -670,29 +679,60 @@ sub find_dependencies($) {
|
||||
"-VDEPENDS"));
|
||||
defined($dependvars)
|
||||
or bsd::errx(1, "failed to obtain dependency list");
|
||||
add_dependencies($port, \&find_binary, split(' ', $dependvars));
|
||||
add_dependencies($port, \&find_file, split(' ', $dependvars));
|
||||
}
|
||||
return keys(%{$port_dep{$port}});
|
||||
}
|
||||
|
||||
#
|
||||
# Update a batch of port directories
|
||||
#
|
||||
my %have_updated;
|
||||
sub update_ports(@) {
|
||||
my @origins = @_;
|
||||
|
||||
my %need_update;
|
||||
my @updated;
|
||||
|
||||
foreach my $origin (@origins) {
|
||||
my ($category, $port) = split('/', $origin);
|
||||
if (!exists($have_updated{$category}) ||
|
||||
!exists($have_updated{$category}->{$port})) {
|
||||
if (!exists($need_update{$category})) {
|
||||
$need_update{$category} = { };
|
||||
}
|
||||
$need_update{$category}->{$port} = 1;
|
||||
}
|
||||
}
|
||||
if (keys(%need_update)) {
|
||||
cd($portsdir);
|
||||
cvs("update", "-l", keys(%need_update))
|
||||
or bsd::errx(1, "error updating categories");
|
||||
foreach my $category (keys(%need_update)) {
|
||||
if (!exists($have_updated{$category})) {
|
||||
$have_updated{$category} = { };
|
||||
}
|
||||
cd("$portsdir/$category");
|
||||
cvs("update", keys(%{$need_update{$category}}))
|
||||
or bsd::errx(1, "error updating $category ports");
|
||||
foreach my $port (keys(%{$need_update{$category}})) {
|
||||
$have_updated{$category}->{$port} = 1;
|
||||
push(@updated, "$category/$port");
|
||||
}
|
||||
}
|
||||
}
|
||||
return @updated;
|
||||
}
|
||||
|
||||
#
|
||||
# Update all necessary files to build the specified ports
|
||||
#
|
||||
sub update_ports_tree(@) {
|
||||
my @ports = @_; # Ports to update
|
||||
|
||||
my $port; # Port name
|
||||
my $category; # Category name
|
||||
my %upd_cat; # Hash of updated categories
|
||||
my %upd_port; # Hash of updated ports
|
||||
my %processed; # Hash of processed ports
|
||||
my @additional; # Additional dependencies
|
||||
my $n; # Pass count
|
||||
my $makev; # Output from 'make -v'
|
||||
|
||||
foreach $port (@ports) {
|
||||
push(@additional, $port);
|
||||
}
|
||||
for ($n = 0; ; ++$n) {
|
||||
my @update_now; # Ports that need updating now
|
||||
my $item; # Iterator
|
||||
@ -701,59 +741,24 @@ sub update_ports_tree(@) {
|
||||
|
||||
setproctitle("updating");
|
||||
|
||||
# Determine which ports need updating
|
||||
foreach $item (@additional) {
|
||||
next if $processed{$item};
|
||||
($category, $port) = split(/\//, $item);
|
||||
if (!exists($upd_port{$category})) {
|
||||
$upd_port{$category} = {};
|
||||
}
|
||||
if (!exists($upd_port{$category}->{$port})) {
|
||||
$upd_port{$category}->{$port} = 0;
|
||||
}
|
||||
push(@update_now, $item);
|
||||
}
|
||||
last unless @update_now;
|
||||
@update_now = update_ports(@ports);
|
||||
last unless (@update_now);
|
||||
info("Pass $n:", @update_now);
|
||||
|
||||
# Update the relevant sections of the ports tree
|
||||
foreach $category (keys(%upd_port)) {
|
||||
my @ports; # Ports to update
|
||||
|
||||
if (!$upd_cat{$category}) {
|
||||
cd($portsdir);
|
||||
cvs("update", "-l", $category)
|
||||
or bsd::errx(1, "error updating the '$category' category");
|
||||
$upd_cat{$category} = 1;
|
||||
}
|
||||
foreach $port (keys(%{$upd_port{$category}})) {
|
||||
next if ($upd_port{$category}->{$port});
|
||||
push(@ports, $port);
|
||||
$upd_port{$category}->{$port} = 1;
|
||||
}
|
||||
if (@ports) {
|
||||
cd("$portsdir/$category");
|
||||
cvs("update", @ports)
|
||||
or bsd::errx(1, "error updating the '$category' category");
|
||||
}
|
||||
}
|
||||
|
||||
# Process all unprocessed ports we know of so far
|
||||
foreach $port (@update_now) {
|
||||
foreach my $port (@update_now) {
|
||||
next if ($processed{$port});
|
||||
setproctitle("updating $port");
|
||||
|
||||
# See if the port has an unprocessed master port
|
||||
# XXX what if the master has a master?
|
||||
if (($master = find_master($port)) && !$processed{$master}) {
|
||||
add_port($master, &REQ_MASTER);
|
||||
info("Adding $master to head of line\n");
|
||||
unshift(@additional, $master);
|
||||
# Need to process master before we continue
|
||||
next;
|
||||
update_ports($master);
|
||||
}
|
||||
|
||||
# Find the port's package name
|
||||
if (!exists($pkgname{$port})) {
|
||||
$makev = capture(\&make, ($port, "-VPKGNAME"));
|
||||
my $makev = capture(\&make, ($port, "-VPKGNAME"));
|
||||
if ($makev =~ m/^\s*(\S+)\s*$/s) {
|
||||
$pkgname{$port} = $1;
|
||||
} else {
|
||||
@ -764,13 +769,9 @@ sub update_ports_tree(@) {
|
||||
# Find the port's dependencies
|
||||
foreach $dependency (find_dependencies($port)) {
|
||||
next if ($processed{$dependency});
|
||||
if ($reqd{$port} == &REQ_MASTER) {
|
||||
add_port($dependency, &REQ_MASTER);
|
||||
} else {
|
||||
add_port($dependency, &REQ_IMPLICIT);
|
||||
}
|
||||
add_port($dependency, &REQ_IMPLICIT);
|
||||
info("Adding $dependency to back of line\n");
|
||||
push(@additional, $dependency);
|
||||
push(@ports, $dependency);
|
||||
}
|
||||
|
||||
# Mark port as processed
|
||||
@ -892,28 +893,26 @@ sub show_port_plist($) {
|
||||
#
|
||||
sub cmp_version($$) {
|
||||
my $inst = shift; # Installed package
|
||||
my $port = shift; # Origin port
|
||||
|
||||
my $tree; # Version in tree
|
||||
my $port = shift; # Newest version
|
||||
|
||||
# Shortcut
|
||||
if (($tree = $pkgname{$port}) eq $inst) {
|
||||
if ($inst eq $port) {
|
||||
return '=';
|
||||
}
|
||||
|
||||
# Compare port epochs
|
||||
my ($inst_epoch, $tree_epoch) = (0, 0);
|
||||
my ($inst_epoch, $port_epoch) = (0, 0);
|
||||
$inst =~ s/,(\d+)$//
|
||||
and $inst_epoch = $1;
|
||||
$tree =~ s/,(\d+)$//
|
||||
and $tree_epoch = $1;
|
||||
if ($inst_epoch != $tree_epoch) {
|
||||
return ($inst_epoch > $tree_epoch) ? '>' : '<';
|
||||
$port =~ s/,(\d+)$//
|
||||
and $port_epoch = $1;
|
||||
if ($inst_epoch != $port_epoch) {
|
||||
return ($inst_epoch > $port_epoch) ? '>' : '<';
|
||||
}
|
||||
|
||||
# Split it into components
|
||||
my @a = split(/[\._-]/, $inst);
|
||||
my @b = split(/[\._-]/, $tree);
|
||||
my @b = split(/[\._-]/, $port);
|
||||
|
||||
# Compare the components one by one
|
||||
while (@a && @b) {
|
||||
@ -935,26 +934,24 @@ sub cmp_version($$) {
|
||||
}
|
||||
|
||||
#
|
||||
# List installed ports
|
||||
# Show port status
|
||||
#
|
||||
sub list_installed() {
|
||||
sub show_port_status($) {
|
||||
my $port = shift; # Port to show status for
|
||||
|
||||
my $pkg; # Installed package
|
||||
my $origin; # Origin
|
||||
my $cmp; # Comparator
|
||||
|
||||
foreach $pkg (sort(keys(%installed))) {
|
||||
$origin = find_moved($installed{$pkg});
|
||||
if (!defined($origin) || !defined($pkgname{$origin})) {
|
||||
print(" ? $pkg\n");
|
||||
} else {
|
||||
$cmp = cmp_version($pkg, $origin);
|
||||
if ($installed{$port}) {
|
||||
foreach my $pkg (@{$installed{$port}}) {
|
||||
$cmp = cmp_version($pkg, $pkgname{$port});
|
||||
if ($cmp eq '=') {
|
||||
print(" $pkg\n");
|
||||
} else {
|
||||
printf(" $cmp $pkg ($pkgname{$origin})\n");
|
||||
printf(" $cmp $pkg ($pkgname{$port})\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf(" ! $port\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1155,11 +1152,6 @@ MAIN:{
|
||||
$build = 1;
|
||||
}
|
||||
|
||||
# 'status' implies 'installed'
|
||||
if ($status) {
|
||||
$installed = 1;
|
||||
}
|
||||
|
||||
# Set and check CVS root
|
||||
if ($anoncvs && !$cvsroot) {
|
||||
$cvsroot = &ANONCVS_ROOT;
|
||||
@ -1201,8 +1193,13 @@ MAIN:{
|
||||
if ($err) {
|
||||
bsd::errx(1, "some required ports were not found.");
|
||||
}
|
||||
if ($installed) {
|
||||
add_installed();
|
||||
if ($installed || $status || $exclude) {
|
||||
get_installed();
|
||||
}
|
||||
if ($installed || ($status && $requested == 0)) {
|
||||
foreach $port (keys(%installed)) {
|
||||
add_port($port, &REQ_EXPLICIT);
|
||||
}
|
||||
}
|
||||
|
||||
# Step 3: update port directories and discover dependencies
|
||||
@ -1212,8 +1209,7 @@ MAIN:{
|
||||
# Step 4: deselect ports which are already installed
|
||||
if ($exclude) {
|
||||
foreach $port (keys(%reqd)) {
|
||||
if ((exists($installed{$port}) && $installed{$port} > 0) ||
|
||||
-d "$dbdir/$pkgname{$port}") {
|
||||
if (defined($installed{$port})) {
|
||||
info("$port is already installed");
|
||||
delete $reqd{$port};
|
||||
}
|
||||
@ -1223,7 +1219,6 @@ MAIN:{
|
||||
# Step 5: list selected ports
|
||||
if ($list) {
|
||||
foreach $port (sort(keys(%reqd))) {
|
||||
next if ($reqd{$port} == &REQ_MASTER);
|
||||
print((($reqd{$port} & &REQ_EXPLICIT) ? " * " : " "),
|
||||
"$port ($pkgname{$port})\n");
|
||||
}
|
||||
@ -1231,7 +1226,9 @@ MAIN:{
|
||||
|
||||
# Step 6: list installed ports
|
||||
if ($status) {
|
||||
list_installed();
|
||||
foreach $port (keys(%reqd)) {
|
||||
show_port_status($port);
|
||||
}
|
||||
}
|
||||
|
||||
# Step 7: show info
|
||||
@ -1277,9 +1274,7 @@ MAIN:{
|
||||
# Step B: fetch distfiles
|
||||
if ($fetch) {
|
||||
foreach $port (keys(%reqd)) {
|
||||
if ($reqd{$port} != &REQ_MASTER) {
|
||||
fetch_port($port);
|
||||
}
|
||||
fetch_port($port);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,7 @@
|
||||
#
|
||||
|
||||
PORTNAME= porteasy
|
||||
PORTVERSION= 2.7.12
|
||||
PORTREVISION= 1
|
||||
PORTVERSION= 2.7.13
|
||||
CATEGORIES= misc
|
||||
MASTER_SITES= # none
|
||||
DISTFILES= # none
|
||||
|
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 2, 2004
|
||||
.Dd April 02, 2004
|
||||
.Dt PORTEASY 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -89,7 +89,25 @@ Specify the ports directory (normally
|
||||
.It Fl r Ar dir
|
||||
Specify the CVS root directory.
|
||||
.It Fl s
|
||||
List installed ports and their status.
|
||||
Indicate the installation status of the selected ports.
|
||||
Each selected port is listed with a symbol indicating its status:
|
||||
.Bl -tag -width 3n
|
||||
.It Ql \&!
|
||||
Not installed.
|
||||
.It Ql " "
|
||||
Up-to-date.
|
||||
.It Ql \&<
|
||||
Older than the version in the ports tree.
|
||||
.It Ql \&>
|
||||
Newer than the version in the ports tree.
|
||||
.El
|
||||
.Pp
|
||||
If the
|
||||
.Fl s
|
||||
option is specified and no ports are specified on the command line,
|
||||
all installed ports are selected as if the
|
||||
.Fl I
|
||||
option had been specified.
|
||||
.It Fl t Ar tag
|
||||
Specify a tag to use for
|
||||
.Xr cvs 1
|
||||
@ -153,8 +171,10 @@ If a certain match is not found,
|
||||
.Nm
|
||||
prints a list of possible matches and exits.
|
||||
.Pp
|
||||
All direct and indirect dependencies of the ports listed on the
|
||||
command line are also selected and marked as dependencies.
|
||||
All direct and indirect dependencies (except, if the
|
||||
.Fl e option was specified,
|
||||
those that are already installed) are also selected and marked as
|
||||
dependencies.
|
||||
.It Update ports tree and discover dependencies
|
||||
If the
|
||||
.Fl u
|
||||
@ -172,8 +192,8 @@ option was specified,
|
||||
.Nm
|
||||
checks to see if any of the selected ports are already installed;
|
||||
those that are are deselected.
|
||||
This process is not very accurate, as it will not detect if an older
|
||||
or alternate version of a selected port is installed.
|
||||
This process is not very accurate, as it sometimes fails to detect
|
||||
that an older or alternate version of a selected port is installed.
|
||||
.It List selected ports
|
||||
If the
|
||||
.Fl l
|
||||
@ -183,9 +203,7 @@ Explicitly selected ports are indicated with a star.
|
||||
.It List installed ports
|
||||
If the
|
||||
.Fl s
|
||||
option was specified, all installed ports are listed with their status
|
||||
('<' for ports that are older than the version in the tree, '>' for
|
||||
those that are newer, '?' for those that could not be identified).
|
||||
option was specified, all selected ports are listed with their status.
|
||||
.It Show packing lists
|
||||
If the
|
||||
.Fk L
|
||||
|
@ -26,14 +26,14 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
use strict;
|
||||
use Fcntl;
|
||||
use Getopt::Long;
|
||||
|
||||
my $VERSION = "2.7.12";
|
||||
my $VERSION = "2.7.13";
|
||||
my $COPYRIGHT = "Copyright (c) 2000-2004 Dag-Erling Smørgrav. " .
|
||||
"All rights reserved.";
|
||||
|
||||
@ -41,7 +41,6 @@ my $COPYRIGHT = "Copyright (c) 2000-2004 Dag-Erling Sm
|
||||
sub ANONCVS_ROOT { ":pserver:anoncvs\@anoncvs.FreeBSD.org:/home/ncvs" }
|
||||
sub REQ_EXPLICIT { 1 }
|
||||
sub REQ_IMPLICIT { 2 }
|
||||
sub REQ_MASTER { 4 }
|
||||
|
||||
sub CVS_PASSFILE { "%%PREFIX%%/share/porteasy/cvspass" }
|
||||
|
||||
@ -459,8 +458,8 @@ sub add_port($$) {
|
||||
} else {
|
||||
$realport = find_port($port);
|
||||
}
|
||||
$realport = find_moved($realport);
|
||||
}
|
||||
$realport = find_moved($realport);
|
||||
if (!$realport) {
|
||||
return 1;
|
||||
}
|
||||
@ -495,13 +494,15 @@ sub get_origin($) {
|
||||
warn("$port has no known origin\n");
|
||||
return undef;
|
||||
}
|
||||
info("$port -> $origin\n");
|
||||
$origin = find_moved($origin);
|
||||
return $origin;
|
||||
}
|
||||
|
||||
#
|
||||
# Select installed ports
|
||||
# Get list of installed ports
|
||||
#
|
||||
sub add_installed() {
|
||||
sub get_installed() {
|
||||
|
||||
local *DIR; # Directory handle
|
||||
my $port; # Installed port
|
||||
@ -514,8 +515,13 @@ sub add_installed() {
|
||||
if (!defined($origin = get_origin($port))) {
|
||||
bsd::warnx("$port has no known origin");
|
||||
} else {
|
||||
$installed{$port} = $origin;
|
||||
add_port($origin, &REQ_EXPLICIT);
|
||||
if ($installed{$origin}) {
|
||||
bsd::warnx("$origin is already installed as " .
|
||||
join(', ', @{$installed{$origin}}));
|
||||
} else {
|
||||
$installed{$origin} = [ ];
|
||||
}
|
||||
push(@{$installed{$origin}}, $port);
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
@ -536,7 +542,7 @@ sub find_master($) {
|
||||
# Look for MASTERDIR in the Makefile. We can't use 'make -V'
|
||||
# because the Makefile might try to include the master port's
|
||||
# Makefile, which might not be checked out yet.
|
||||
open(FILE, "$portsdir/$port/Makefile")
|
||||
sysopen(FILE, "$portsdir/$port/Makefile", O_RDONLY)
|
||||
or bsd::err(1, "unable to read Makefile for $port");
|
||||
while (<FILE>) {
|
||||
my $master; # Master directory
|
||||
@ -589,20 +595,23 @@ sub find_library($) {
|
||||
}
|
||||
|
||||
#
|
||||
# Find a binary
|
||||
# Find a file
|
||||
#
|
||||
sub find_binary($) {
|
||||
my $binary = shift; # Binary to find
|
||||
sub find_file($) {
|
||||
my $file = shift; # File to find
|
||||
|
||||
my $dir; # Directory
|
||||
|
||||
if ($binary =~ m|^/|) {
|
||||
info("$binary is installed as $binary");
|
||||
return (-x $binary);
|
||||
if ($file =~ m|^/|) {
|
||||
if (-e $file) {
|
||||
info("$file is installed");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
foreach $dir (split(/:/, $ENV{'PATH'})) {
|
||||
if (-x "$dir/$binary") {
|
||||
info("$binary is installed as $dir/$binary");
|
||||
if (-x "$dir/$file") {
|
||||
info("$file is installed as $dir/$file");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -670,29 +679,60 @@ sub find_dependencies($) {
|
||||
"-VDEPENDS"));
|
||||
defined($dependvars)
|
||||
or bsd::errx(1, "failed to obtain dependency list");
|
||||
add_dependencies($port, \&find_binary, split(' ', $dependvars));
|
||||
add_dependencies($port, \&find_file, split(' ', $dependvars));
|
||||
}
|
||||
return keys(%{$port_dep{$port}});
|
||||
}
|
||||
|
||||
#
|
||||
# Update a batch of port directories
|
||||
#
|
||||
my %have_updated;
|
||||
sub update_ports(@) {
|
||||
my @origins = @_;
|
||||
|
||||
my %need_update;
|
||||
my @updated;
|
||||
|
||||
foreach my $origin (@origins) {
|
||||
my ($category, $port) = split('/', $origin);
|
||||
if (!exists($have_updated{$category}) ||
|
||||
!exists($have_updated{$category}->{$port})) {
|
||||
if (!exists($need_update{$category})) {
|
||||
$need_update{$category} = { };
|
||||
}
|
||||
$need_update{$category}->{$port} = 1;
|
||||
}
|
||||
}
|
||||
if (keys(%need_update)) {
|
||||
cd($portsdir);
|
||||
cvs("update", "-l", keys(%need_update))
|
||||
or bsd::errx(1, "error updating categories");
|
||||
foreach my $category (keys(%need_update)) {
|
||||
if (!exists($have_updated{$category})) {
|
||||
$have_updated{$category} = { };
|
||||
}
|
||||
cd("$portsdir/$category");
|
||||
cvs("update", keys(%{$need_update{$category}}))
|
||||
or bsd::errx(1, "error updating $category ports");
|
||||
foreach my $port (keys(%{$need_update{$category}})) {
|
||||
$have_updated{$category}->{$port} = 1;
|
||||
push(@updated, "$category/$port");
|
||||
}
|
||||
}
|
||||
}
|
||||
return @updated;
|
||||
}
|
||||
|
||||
#
|
||||
# Update all necessary files to build the specified ports
|
||||
#
|
||||
sub update_ports_tree(@) {
|
||||
my @ports = @_; # Ports to update
|
||||
|
||||
my $port; # Port name
|
||||
my $category; # Category name
|
||||
my %upd_cat; # Hash of updated categories
|
||||
my %upd_port; # Hash of updated ports
|
||||
my %processed; # Hash of processed ports
|
||||
my @additional; # Additional dependencies
|
||||
my $n; # Pass count
|
||||
my $makev; # Output from 'make -v'
|
||||
|
||||
foreach $port (@ports) {
|
||||
push(@additional, $port);
|
||||
}
|
||||
for ($n = 0; ; ++$n) {
|
||||
my @update_now; # Ports that need updating now
|
||||
my $item; # Iterator
|
||||
@ -701,59 +741,24 @@ sub update_ports_tree(@) {
|
||||
|
||||
setproctitle("updating");
|
||||
|
||||
# Determine which ports need updating
|
||||
foreach $item (@additional) {
|
||||
next if $processed{$item};
|
||||
($category, $port) = split(/\//, $item);
|
||||
if (!exists($upd_port{$category})) {
|
||||
$upd_port{$category} = {};
|
||||
}
|
||||
if (!exists($upd_port{$category}->{$port})) {
|
||||
$upd_port{$category}->{$port} = 0;
|
||||
}
|
||||
push(@update_now, $item);
|
||||
}
|
||||
last unless @update_now;
|
||||
@update_now = update_ports(@ports);
|
||||
last unless (@update_now);
|
||||
info("Pass $n:", @update_now);
|
||||
|
||||
# Update the relevant sections of the ports tree
|
||||
foreach $category (keys(%upd_port)) {
|
||||
my @ports; # Ports to update
|
||||
|
||||
if (!$upd_cat{$category}) {
|
||||
cd($portsdir);
|
||||
cvs("update", "-l", $category)
|
||||
or bsd::errx(1, "error updating the '$category' category");
|
||||
$upd_cat{$category} = 1;
|
||||
}
|
||||
foreach $port (keys(%{$upd_port{$category}})) {
|
||||
next if ($upd_port{$category}->{$port});
|
||||
push(@ports, $port);
|
||||
$upd_port{$category}->{$port} = 1;
|
||||
}
|
||||
if (@ports) {
|
||||
cd("$portsdir/$category");
|
||||
cvs("update", @ports)
|
||||
or bsd::errx(1, "error updating the '$category' category");
|
||||
}
|
||||
}
|
||||
|
||||
# Process all unprocessed ports we know of so far
|
||||
foreach $port (@update_now) {
|
||||
foreach my $port (@update_now) {
|
||||
next if ($processed{$port});
|
||||
setproctitle("updating $port");
|
||||
|
||||
# See if the port has an unprocessed master port
|
||||
# XXX what if the master has a master?
|
||||
if (($master = find_master($port)) && !$processed{$master}) {
|
||||
add_port($master, &REQ_MASTER);
|
||||
info("Adding $master to head of line\n");
|
||||
unshift(@additional, $master);
|
||||
# Need to process master before we continue
|
||||
next;
|
||||
update_ports($master);
|
||||
}
|
||||
|
||||
# Find the port's package name
|
||||
if (!exists($pkgname{$port})) {
|
||||
$makev = capture(\&make, ($port, "-VPKGNAME"));
|
||||
my $makev = capture(\&make, ($port, "-VPKGNAME"));
|
||||
if ($makev =~ m/^\s*(\S+)\s*$/s) {
|
||||
$pkgname{$port} = $1;
|
||||
} else {
|
||||
@ -764,13 +769,9 @@ sub update_ports_tree(@) {
|
||||
# Find the port's dependencies
|
||||
foreach $dependency (find_dependencies($port)) {
|
||||
next if ($processed{$dependency});
|
||||
if ($reqd{$port} == &REQ_MASTER) {
|
||||
add_port($dependency, &REQ_MASTER);
|
||||
} else {
|
||||
add_port($dependency, &REQ_IMPLICIT);
|
||||
}
|
||||
add_port($dependency, &REQ_IMPLICIT);
|
||||
info("Adding $dependency to back of line\n");
|
||||
push(@additional, $dependency);
|
||||
push(@ports, $dependency);
|
||||
}
|
||||
|
||||
# Mark port as processed
|
||||
@ -892,28 +893,26 @@ sub show_port_plist($) {
|
||||
#
|
||||
sub cmp_version($$) {
|
||||
my $inst = shift; # Installed package
|
||||
my $port = shift; # Origin port
|
||||
|
||||
my $tree; # Version in tree
|
||||
my $port = shift; # Newest version
|
||||
|
||||
# Shortcut
|
||||
if (($tree = $pkgname{$port}) eq $inst) {
|
||||
if ($inst eq $port) {
|
||||
return '=';
|
||||
}
|
||||
|
||||
# Compare port epochs
|
||||
my ($inst_epoch, $tree_epoch) = (0, 0);
|
||||
my ($inst_epoch, $port_epoch) = (0, 0);
|
||||
$inst =~ s/,(\d+)$//
|
||||
and $inst_epoch = $1;
|
||||
$tree =~ s/,(\d+)$//
|
||||
and $tree_epoch = $1;
|
||||
if ($inst_epoch != $tree_epoch) {
|
||||
return ($inst_epoch > $tree_epoch) ? '>' : '<';
|
||||
$port =~ s/,(\d+)$//
|
||||
and $port_epoch = $1;
|
||||
if ($inst_epoch != $port_epoch) {
|
||||
return ($inst_epoch > $port_epoch) ? '>' : '<';
|
||||
}
|
||||
|
||||
# Split it into components
|
||||
my @a = split(/[\._-]/, $inst);
|
||||
my @b = split(/[\._-]/, $tree);
|
||||
my @b = split(/[\._-]/, $port);
|
||||
|
||||
# Compare the components one by one
|
||||
while (@a && @b) {
|
||||
@ -935,26 +934,24 @@ sub cmp_version($$) {
|
||||
}
|
||||
|
||||
#
|
||||
# List installed ports
|
||||
# Show port status
|
||||
#
|
||||
sub list_installed() {
|
||||
sub show_port_status($) {
|
||||
my $port = shift; # Port to show status for
|
||||
|
||||
my $pkg; # Installed package
|
||||
my $origin; # Origin
|
||||
my $cmp; # Comparator
|
||||
|
||||
foreach $pkg (sort(keys(%installed))) {
|
||||
$origin = find_moved($installed{$pkg});
|
||||
if (!defined($origin) || !defined($pkgname{$origin})) {
|
||||
print(" ? $pkg\n");
|
||||
} else {
|
||||
$cmp = cmp_version($pkg, $origin);
|
||||
if ($installed{$port}) {
|
||||
foreach my $pkg (@{$installed{$port}}) {
|
||||
$cmp = cmp_version($pkg, $pkgname{$port});
|
||||
if ($cmp eq '=') {
|
||||
print(" $pkg\n");
|
||||
} else {
|
||||
printf(" $cmp $pkg ($pkgname{$origin})\n");
|
||||
printf(" $cmp $pkg ($pkgname{$port})\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf(" ! $port\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1155,11 +1152,6 @@ MAIN:{
|
||||
$build = 1;
|
||||
}
|
||||
|
||||
# 'status' implies 'installed'
|
||||
if ($status) {
|
||||
$installed = 1;
|
||||
}
|
||||
|
||||
# Set and check CVS root
|
||||
if ($anoncvs && !$cvsroot) {
|
||||
$cvsroot = &ANONCVS_ROOT;
|
||||
@ -1201,8 +1193,13 @@ MAIN:{
|
||||
if ($err) {
|
||||
bsd::errx(1, "some required ports were not found.");
|
||||
}
|
||||
if ($installed) {
|
||||
add_installed();
|
||||
if ($installed || $status || $exclude) {
|
||||
get_installed();
|
||||
}
|
||||
if ($installed || ($status && $requested == 0)) {
|
||||
foreach $port (keys(%installed)) {
|
||||
add_port($port, &REQ_EXPLICIT);
|
||||
}
|
||||
}
|
||||
|
||||
# Step 3: update port directories and discover dependencies
|
||||
@ -1212,8 +1209,7 @@ MAIN:{
|
||||
# Step 4: deselect ports which are already installed
|
||||
if ($exclude) {
|
||||
foreach $port (keys(%reqd)) {
|
||||
if ((exists($installed{$port}) && $installed{$port} > 0) ||
|
||||
-d "$dbdir/$pkgname{$port}") {
|
||||
if (defined($installed{$port})) {
|
||||
info("$port is already installed");
|
||||
delete $reqd{$port};
|
||||
}
|
||||
@ -1223,7 +1219,6 @@ MAIN:{
|
||||
# Step 5: list selected ports
|
||||
if ($list) {
|
||||
foreach $port (sort(keys(%reqd))) {
|
||||
next if ($reqd{$port} == &REQ_MASTER);
|
||||
print((($reqd{$port} & &REQ_EXPLICIT) ? " * " : " "),
|
||||
"$port ($pkgname{$port})\n");
|
||||
}
|
||||
@ -1231,7 +1226,9 @@ MAIN:{
|
||||
|
||||
# Step 6: list installed ports
|
||||
if ($status) {
|
||||
list_installed();
|
||||
foreach $port (keys(%reqd)) {
|
||||
show_port_status($port);
|
||||
}
|
||||
}
|
||||
|
||||
# Step 7: show info
|
||||
@ -1277,9 +1274,7 @@ MAIN:{
|
||||
# Step B: fetch distfiles
|
||||
if ($fetch) {
|
||||
foreach $port (keys(%reqd)) {
|
||||
if ($reqd{$port} != &REQ_MASTER) {
|
||||
fetch_port($port);
|
||||
}
|
||||
fetch_port($port);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user