freebsd-ports/Tools/make_index
Steve Price f91ad808b3 Tweak to catch missing directories from the Makefiles in the various
categories which were failing to be mapped from directory to port name
because 'make index' can't know to run 'make describe' in directories
it doesn't know exist.
2001-03-08 02:28:44 +00:00

125 lines
3.5 KiB
Perl

#!/usr/bin/perl
#
# $FreeBSD$
#
# Written to speed-up INDEX file generation. The new scheme
# basically visits each port once and writes out each port's
# build-depends and run-depends as a list of directories. This
# script goes back in and maps the directories back to pkgnames,
# fixes up the build-depends and run-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 = shift;
# 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: 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};
# build-depends = build-depends + recursive list of run-depends
# for each build-depends
my @deps = ();
foreach $name (@{$pkg->{bdep}}) {
recurse($index{$name});
push(@deps, @{$index{$name}->{rdep}});
}
$pkg->{bdep} = uniqify(@{$pkg->{bdep}}, @deps);
# 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 = {
'bdep' => [split(/ /, $f[7])],
'rdep' => [split(/ /, $f[8])],
'rest' => join('|', splice(@f, 9)),
'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->{bdep}}) {
my @bdep = map { by_path($_) } @{$pkg->{bdep}};
$pkg->{bdep} = \@bdep;
}
# and now the run dependencies
if (@{$pkg->{rdep}}) {
my @rdep = map { by_path($_) } @{$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};
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}\n";
}