mirror of
https://git.FreeBSD.org/ports.git
synced 2024-12-26 05:02:18 +00:00
b6461b0294
This will make a number of things easier in the future, as well as (finally!) avoiding the Id-smashing problem which has plagued developers for so long. Boy, I'm glad we're not using sup anymore. This update would have been insane otherwise.
121 lines
3.4 KiB
Perl
121 lines
3.4 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, $_); }
|
|
return $by_path{join('/', @p)};
|
|
}
|
|
|
|
# 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";
|
|
}
|