aboutsummaryrefslogtreecommitdiffstats
path: root/Tools/make_index
diff options
context:
space:
mode:
authorbdrewery <bdrewery@FreeBSD.org>2013-10-08 05:32:30 +0800
committerbdrewery <bdrewery@FreeBSD.org>2013-10-08 05:32:30 +0800
commitc28390824a2e6cee9831139c143bc0d1b750496d (patch)
treef579f2042e188d1d5826465461f06337f7728b5b /Tools/make_index
parent95207e85bfb4daf0f2b2d385b2ea51f62ba6f754 (diff)
downloadfreebsd-ports-gnome-c28390824a2e6cee9831139c143bc0d1b750496d.tar.gz
freebsd-ports-gnome-c28390824a2e6cee9831139c143bc0d1b750496d.tar.zst
freebsd-ports-gnome-c28390824a2e6cee9831139c143bc0d1b750496d.zip
- Fix 'make index' when system is built with WITHOUT_PORTSNAP by
falling back on the perl make_index if needed. With hat: portmgr Reported by: ade
Diffstat (limited to 'Tools/make_index')
-rw-r--r--Tools/make_index180
1 files changed, 180 insertions, 0 deletions
diff --git a/Tools/make_index b/Tools/make_index
new file mode 100644
index 000000000000..7bb9b5af8bfa
--- /dev/null
+++ b/Tools/make_index
@@ -0,0 +1,180 @@
+#!/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;
+ 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'};
+ }
+}