3 # $FreeBSD: head/Tools/make_index 340851 2014-01-23 19:55:14Z mat $
5 # INDEX builds visit each port once and write out each port's
6 # *-depends as a list of directories, using 'make describe'. This
7 # script goes back in and maps the directories back to pkgnames,
8 # fixes up the *-depends list, and writes out the new INDEX file.
12 # Helper function to map a directory to a pkgname.
14 my ($name, $port) = @_;
16 # If a direct mapping exists, then use it.
17 return $by_path{$name} if (defined $by_path{$name});
19 # Make sure we have /usr/ports at the beginning.
20 $name =~ s!^$pwd!/usr/ports!o;
21 return $by_path{$name} if (defined $by_path{$name});
23 # Collapse all the '..' sequences.
24 my @f = split('/', $name), @p = ();
25 foreach (@f) { (/\.\./) ? pop(@p) : push(@p, $_); }
26 $name = join('/', @p);
27 return $by_path{$name} if (defined $by_path{$name});
29 print STDERR "make_index: $port: no entry for $name\n";
33 # This routine replaces what used to be the time-consuming
34 # recursive 'depends-list' and 'package-depends' targets.
37 return if $pkg->{checked};
39 # extract-depends = extract-depends + recursive list of run-depends
40 # for each extract-depends
42 foreach $name (@{$pkg->{edep}}) {
43 recurse($index{$name});
44 push(@deps, @{$index{$name}->{rdep}});
46 $pkg->{edep} = uniqify(@{$pkg->{edep}}, @deps);
48 # same as above except for patch-depends this time
50 foreach $name (@{$pkg->{pdep}}) {
51 recurse($index{$name});
52 push(@deps, @{$index{$name}->{rdep}});
54 $pkg->{pdep} = uniqify(@{$pkg->{pdep}}, @deps);
56 # same as above except for fetch-depends this time
58 foreach $name (@{$pkg->{fdep}}) {
59 recurse($index{$name});
60 push(@deps, @{$index{$name}->{rdep}});
62 $pkg->{fdep} = uniqify(@{$pkg->{fdep}}, @deps);
65 # same as above except for build-depends this time
67 foreach $name (@{$pkg->{bdep}}) {
68 recurse($index{$name});
69 push(@deps, @{$index{$name}->{rdep}});
71 $pkg->{bdep} = uniqify(@{$pkg->{bdep}}, @deps);
74 # same as above except for run-depends this time
76 foreach $name (@{$pkg->{rdep}}) {
77 recurse($index{$name});
78 push(@deps, @{$index{$name}->{rdep}});
80 $pkg->{rdep} = uniqify(@{$pkg->{rdep}}, @deps);
85 # Given one or more lists as arguments return the set
86 # of unique elements among them.
89 my @unique = grep {! $seen{$_}++} (@_);
93 # Save where we are so that we can map all directories formed
94 # from ${PORTSDIR} to their canonical location '/usr/ports/...'.
97 # Read each line of output generated by the 'index' target.
104 # Force to canonical form.
105 $f[1] =~ s!^$pwd!/usr/ports!o;
106 $f[4] =~ s!^$pwd!/usr/ports!o;
108 # Save directory -> pkgname relationship.
109 # Note: $f[0] gets clobbered by the splice below so we'll save
110 # it to a new $name first.
111 $by_path{$f[1]} = $name = $f[0];
113 # Create a hash table of the infomation we need about this port.
115 'edep' => [split(/ /, $f[7])],
116 'pdep' => [split(/ /, $f[8])],
117 'fdep' => [split(/ /, $f[9])],
118 'bdep' => [split(/ /, $f[10])],
119 'rdep' => [split(/ /, $f[11])],
120 'rest' => join('|', splice(@f, 12)),
121 'text' => join('|', splice(@f, 0, 7))
123 $index{$name} = $pkg;
125 # This is a cheap way of preserving the order of the entries.
129 # For each port perform the mapping between directory and pkgnames.
130 foreach $name (keys %index) {
131 my $pkg = $index{$name};
132 # first the extract dependencies
133 if (@{$pkg->{edep}}) {
134 my @edep = map { by_path($_, $name) } @{$pkg->{edep}};
135 $pkg->{edep} = \@edep;
137 # then the patch dependencies
138 if (@{$pkg->{pdep}}) {
139 my @pdep = map { by_path($_, $name) } @{$pkg->{pdep}};
140 $pkg->{pdep} = \@pdep;
142 # then the fetch dependencies
143 if (@{$pkg->{fdep}}) {
144 my @fdep = map { by_path($_, $name) } @{$pkg->{fdep}};
145 $pkg->{fdep} = \@fdep;
147 # then the build dependencies
148 if (@{$pkg->{bdep}}) {
149 my @bdep = map { by_path($_, $name) } @{$pkg->{bdep}};
150 $pkg->{bdep} = \@bdep;
152 # then the run dependencies
153 if (@{$pkg->{rdep}}) {
154 my @rdep = map { by_path($_, $name) } @{$pkg->{rdep}};
155 $pkg->{rdep} = \@rdep;
159 # With all that done we're finally ready to write out the new
160 # INDEX file one port at a time.
161 foreach $name (@names) {
162 my $pkg = $index{$name};
163 if (exists $pkg->{'PRINTED'}) {
164 print STDERR "Warning: Duplicate INDEX entry: $name\n";
167 print "$pkg->{text}|";
168 print join(' ', sort(@{$pkg->{bdep}})) if @{$pkg->{bdep}};
170 print join(' ', sort(@{$pkg->{rdep}})) if @{$pkg->{rdep}};
171 print "|$pkg->{rest}|";
172 print join(' ', sort(@{$pkg->{edep}})) if @{$pkg->{edep}};
174 print join(' ', sort(@{$pkg->{pdep}})) if @{$pkg->{pdep}};
176 print join(' ', sort(@{$pkg->{fdep}})) if @{$pkg->{fdep}};