123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #!/usr/bin/perl
- #
- # 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;
- s/\015$//;
- 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 extract dependencies
- if (@{$pkg->{edep}}) {
- my @edep = map { by_path($_, $name) } @{$pkg->{edep}};
- $pkg->{edep} = \@edep;
- }
- # then the patch dependencies
- if (@{$pkg->{pdep}}) {
- my @pdep = map { by_path($_, $name) } @{$pkg->{pdep}};
- $pkg->{pdep} = \@pdep;
- }
- # then the fetch dependencies
- if (@{$pkg->{fdep}}) {
- my @fdep = map { by_path($_, $name) } @{$pkg->{fdep}};
- $pkg->{fdep} = \@fdep;
- }
- # then the build dependencies
- if (@{$pkg->{bdep}}) {
- my @bdep = map { by_path($_, $name) } @{$pkg->{bdep}};
- $pkg->{bdep} = \@bdep;
- }
- # then the run 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'};
- }
- }
|