179 lines
5.0 KiB
Perl
179 lines
5.0 KiB
Perl
#!/usr/bin/perl
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
# INDEX builds visit each port once and write out each port's
|
|
# *-depends as a list of directories, using 'make describe'. This
|
|
# script goes back in and maps the directories back to pkgnames,
|
|
# fixes up the *-depends list, and writes out the new INDEX file.
|
|
|
|
require 5.002;
|
|
|
|
# Helper function to map a directory to a pkgname.
|
|
sub by_path {
|
|
my ($name, $port) = @_;
|
|
|
|
# If a direct mapping exists, then use it.
|
|
return $by_path{$name} if (defined $by_path{$name});
|
|
|
|
# Make sure we have /usr/ports at the beginning.
|
|
$name =~ s!^$pwd!/usr/ports!o;
|
|
return $by_path{$name} if (defined $by_path{$name});
|
|
|
|
# Collapse all the '..' sequences.
|
|
my @f = split('/', $name), @p = ();
|
|
foreach (@f) { (/\.\./) ? pop(@p) : push(@p, $_); }
|
|
$name = join('/', @p);
|
|
return $by_path{$name} if (defined $by_path{$name});
|
|
|
|
print STDERR "make_index: $port: no entry for $name\n";
|
|
return undef;
|
|
}
|
|
|
|
# This routine replaces what used to be the time-consuming
|
|
# recursive 'depends-list' and 'package-depends' targets.
|
|
sub recurse {
|
|
my $pkg = shift(@_);
|
|
return if $pkg->{checked};
|
|
|
|
# extract-depends = extract-depends + recursive list of run-depends
|
|
# for each extract-depends
|
|
my @deps = ();
|
|
foreach $name (@{$pkg->{edep}}) {
|
|
recurse($index{$name});
|
|
push(@deps, @{$index{$name}->{rdep}});
|
|
}
|
|
$pkg->{edep} = uniqify(@{$pkg->{edep}}, @deps);
|
|
|
|
# same as above except for patch-depends this time
|
|
@deps = ();
|
|
foreach $name (@{$pkg->{pdep}}) {
|
|
recurse($index{$name});
|
|
push(@deps, @{$index{$name}->{rdep}});
|
|
}
|
|
$pkg->{pdep} = uniqify(@{$pkg->{pdep}}, @deps);
|
|
|
|
# same as above except for fetch-depends this time
|
|
@deps = ();
|
|
foreach $name (@{$pkg->{fdep}}) {
|
|
recurse($index{$name});
|
|
push(@deps, @{$index{$name}->{rdep}});
|
|
}
|
|
$pkg->{fdep} = uniqify(@{$pkg->{fdep}}, @deps);
|
|
$pkg->{checked} = 1;
|
|
|
|
# same as above except for build-depends this time
|
|
@deps = ();
|
|
foreach $name (@{$pkg->{bdep}}) {
|
|
recurse($index{$name});
|
|
push(@deps, @{$index{$name}->{rdep}});
|
|
}
|
|
$pkg->{bdep} = uniqify(@{$pkg->{bdep}}, @deps);
|
|
$pkg->{checked} = 1;
|
|
|
|
# same as above except for run-depends this time
|
|
@deps = ();
|
|
foreach $name (@{$pkg->{rdep}}) {
|
|
recurse($index{$name});
|
|
push(@deps, @{$index{$name}->{rdep}});
|
|
}
|
|
$pkg->{rdep} = uniqify(@{$pkg->{rdep}}, @deps);
|
|
$pkg->{checked} = 1;
|
|
|
|
}
|
|
|
|
# Given one or more lists as arguments return the set
|
|
# of unique elements among them.
|
|
sub uniqify {
|
|
my %seen = ();
|
|
my @unique = grep {! $seen{$_}++} (@_);
|
|
return \@unique;
|
|
}
|
|
|
|
# Save where we are so that we can map all directories formed
|
|
# from ${PORTSDIR} to their canonical location '/usr/ports/...'.
|
|
chomp($pwd = `pwd`);
|
|
|
|
# Read each line of output generated by the 'index' target.
|
|
while (<>) {
|
|
chomp;
|
|
my @f = split(/\|/);
|
|
|
|
# Force to canonical form.
|
|
$f[1] =~ s!^$pwd!/usr/ports!o;
|
|
$f[4] =~ s!^$pwd!/usr/ports!o;
|
|
|
|
# Save directory -> pkgname relationship.
|
|
# Note: $f[0] gets clobbered by the splice below so we'll save
|
|
# it to a new $name first.
|
|
$by_path{$f[1]} = $name = $f[0];
|
|
|
|
# Create a hash table of the infomation we need about this port.
|
|
my $pkg = {
|
|
'edep' => [split(/ /, $f[7])],
|
|
'pdep' => [split(/ /, $f[8])],
|
|
'fdep' => [split(/ /, $f[9])],
|
|
'bdep' => [split(/ /, $f[10])],
|
|
'rdep' => [split(/ /, $f[11])],
|
|
'rest' => join('|', splice(@f, 12)),
|
|
'text' => join('|', splice(@f, 0, 7))
|
|
};
|
|
$index{$name} = $pkg;
|
|
|
|
# This is a cheap way of preserving the order of the entries.
|
|
push(@names, $name);
|
|
}
|
|
|
|
# For each port perform the mapping between directory and pkgnames.
|
|
foreach $name (keys %index) {
|
|
my $pkg = $index{$name};
|
|
# first the build dependencies
|
|
if (@{$pkg->{edep}}) {
|
|
my @edep = map { by_path($_, $name) } @{$pkg->{edep}};
|
|
$pkg->{edep} = \@edep;
|
|
}
|
|
#
|
|
if (@{$pkg->{pdep}}) {
|
|
my @pdep = map { by_path($_, $name) } @{$pkg->{pdep}};
|
|
$pkg->{pdep} = \@pdep;
|
|
}
|
|
# first the build dependencies
|
|
if (@{$pkg->{fdep}}) {
|
|
my @fdep = map { by_path($_, $name) } @{$pkg->{fdep}};
|
|
$pkg->{fdep} = \@fdep;
|
|
}
|
|
# first the build dependencies
|
|
if (@{$pkg->{bdep}}) {
|
|
my @bdep = map { by_path($_, $name) } @{$pkg->{bdep}};
|
|
$pkg->{bdep} = \@bdep;
|
|
}
|
|
# first the build dependencies
|
|
if (@{$pkg->{rdep}}) {
|
|
my @rdep = map { by_path($_, $name) } @{$pkg->{rdep}};
|
|
$pkg->{rdep} = \@rdep;
|
|
}
|
|
}
|
|
|
|
# With all that done we're finally ready to write out the new
|
|
# INDEX file one port at a time.
|
|
foreach $name (@names) {
|
|
my $pkg = $index{$name};
|
|
if (exists $pkg->{'PRINTED'}) {
|
|
print STDERR "Warning: Duplicate INDEX entry: $name\n";
|
|
} else {
|
|
recurse($pkg);
|
|
print "$pkg->{text}|";
|
|
print join(' ', sort(@{$pkg->{bdep}})) if @{$pkg->{bdep}};
|
|
print "|";
|
|
print join(' ', sort(@{$pkg->{rdep}})) if @{$pkg->{rdep}};
|
|
print "|$pkg->{rest}|";
|
|
print join(' ', sort(@{$pkg->{edep}})) if @{$pkg->{edep}};
|
|
print "|";
|
|
print join(' ', sort(@{$pkg->{pdep}})) if @{$pkg->{pdep}};
|
|
print "|";
|
|
print join(' ', sort(@{$pkg->{fdep}})) if @{$pkg->{fdep}};
|
|
print "\n";
|
|
++$pkg->{'PRINTED'};
|
|
}
|
|
}
|