make_index 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #!/usr/bin/perl
  2. #
  3. # INDEX builds visit each port once and write out each port's
  4. # *-depends as a list of directories, using 'make describe'. This
  5. # script goes back in and maps the directories back to pkgnames,
  6. # fixes up the *-depends list, and writes out the new INDEX file.
  7. require 5.002;
  8. # Helper function to map a directory to a pkgname.
  9. sub by_path {
  10. my ($name, $port) = @_;
  11. # If a direct mapping exists, then use it.
  12. return $by_path{$name} if (defined $by_path{$name});
  13. # Make sure we have /usr/ports at the beginning.
  14. $name =~ s!^$pwd!/usr/ports!o;
  15. return $by_path{$name} if (defined $by_path{$name});
  16. # Collapse all the '..' sequences.
  17. my @f = split('/', $name), @p = ();
  18. foreach (@f) { (/\.\./) ? pop(@p) : push(@p, $_); }
  19. $name = join('/', @p);
  20. return $by_path{$name} if (defined $by_path{$name});
  21. print STDERR "make_index: $port: no entry for $name\n";
  22. return undef;
  23. }
  24. # This routine replaces what used to be the time-consuming
  25. # recursive 'depends-list' and 'package-depends' targets.
  26. sub recurse {
  27. my $pkg = shift(@_);
  28. return if $pkg->{checked};
  29. # extract-depends = extract-depends + recursive list of run-depends
  30. # for each extract-depends
  31. my @deps = ();
  32. foreach $name (@{$pkg->{edep}}) {
  33. recurse($index{$name});
  34. push(@deps, @{$index{$name}->{rdep}});
  35. }
  36. $pkg->{edep} = uniqify(@{$pkg->{edep}}, @deps);
  37. # same as above except for patch-depends this time
  38. @deps = ();
  39. foreach $name (@{$pkg->{pdep}}) {
  40. recurse($index{$name});
  41. push(@deps, @{$index{$name}->{rdep}});
  42. }
  43. $pkg->{pdep} = uniqify(@{$pkg->{pdep}}, @deps);
  44. # same as above except for fetch-depends this time
  45. @deps = ();
  46. foreach $name (@{$pkg->{fdep}}) {
  47. recurse($index{$name});
  48. push(@deps, @{$index{$name}->{rdep}});
  49. }
  50. $pkg->{fdep} = uniqify(@{$pkg->{fdep}}, @deps);
  51. $pkg->{checked} = 1;
  52. # same as above except for build-depends this time
  53. @deps = ();
  54. foreach $name (@{$pkg->{bdep}}) {
  55. recurse($index{$name});
  56. push(@deps, @{$index{$name}->{rdep}});
  57. }
  58. $pkg->{bdep} = uniqify(@{$pkg->{bdep}}, @deps);
  59. $pkg->{checked} = 1;
  60. # same as above except for run-depends this time
  61. @deps = ();
  62. foreach $name (@{$pkg->{rdep}}) {
  63. recurse($index{$name});
  64. push(@deps, @{$index{$name}->{rdep}});
  65. }
  66. $pkg->{rdep} = uniqify(@{$pkg->{rdep}}, @deps);
  67. $pkg->{checked} = 1;
  68. }
  69. # Given one or more lists as arguments return the set
  70. # of unique elements among them.
  71. sub uniqify {
  72. my %seen = ();
  73. my @unique = grep {! $seen{$_}++} (@_);
  74. return \@unique;
  75. }
  76. # Save where we are so that we can map all directories formed
  77. # from ${PORTSDIR} to their canonical location '/usr/ports/...'.
  78. chomp($pwd = `pwd`);
  79. # Read each line of output generated by the 'index' target.
  80. while (<>) {
  81. chomp;
  82. s/\015$//;
  83. my @f = split(/\|/);
  84. # Force to canonical form.
  85. $f[1] =~ s!^$pwd!/usr/ports!o;
  86. $f[4] =~ s!^$pwd!/usr/ports!o;
  87. # Save directory -> pkgname relationship.
  88. # Note: $f[0] gets clobbered by the splice below so we'll save
  89. # it to a new $name first.
  90. $by_path{$f[1]} = $name = $f[0];
  91. # Create a hash table of the infomation we need about this port.
  92. my $pkg = {
  93. 'edep' => [split(/ /, $f[7])],
  94. 'pdep' => [split(/ /, $f[8])],
  95. 'fdep' => [split(/ /, $f[9])],
  96. 'bdep' => [split(/ /, $f[10])],
  97. 'rdep' => [split(/ /, $f[11])],
  98. 'rest' => join('|', splice(@f, 12)),
  99. 'text' => join('|', splice(@f, 0, 7))
  100. };
  101. $index{$name} = $pkg;
  102. # This is a cheap way of preserving the order of the entries.
  103. push(@names, $name);
  104. }
  105. # For each port perform the mapping between directory and pkgnames.
  106. foreach $name (keys %index) {
  107. my $pkg = $index{$name};
  108. # first the extract dependencies
  109. if (@{$pkg->{edep}}) {
  110. my @edep = map { by_path($_, $name) } @{$pkg->{edep}};
  111. $pkg->{edep} = \@edep;
  112. }
  113. # then the patch dependencies
  114. if (@{$pkg->{pdep}}) {
  115. my @pdep = map { by_path($_, $name) } @{$pkg->{pdep}};
  116. $pkg->{pdep} = \@pdep;
  117. }
  118. # then the fetch dependencies
  119. if (@{$pkg->{fdep}}) {
  120. my @fdep = map { by_path($_, $name) } @{$pkg->{fdep}};
  121. $pkg->{fdep} = \@fdep;
  122. }
  123. # then the build dependencies
  124. if (@{$pkg->{bdep}}) {
  125. my @bdep = map { by_path($_, $name) } @{$pkg->{bdep}};
  126. $pkg->{bdep} = \@bdep;
  127. }
  128. # then the run dependencies
  129. if (@{$pkg->{rdep}}) {
  130. my @rdep = map { by_path($_, $name) } @{$pkg->{rdep}};
  131. $pkg->{rdep} = \@rdep;
  132. }
  133. }
  134. # With all that done we're finally ready to write out the new
  135. # INDEX file one port at a time.
  136. foreach $name (@names) {
  137. my $pkg = $index{$name};
  138. if (exists $pkg->{'PRINTED'}) {
  139. print STDERR "Warning: Duplicate INDEX entry: $name\n";
  140. } else {
  141. recurse($pkg);
  142. print "$pkg->{text}|";
  143. print join(' ', sort(@{$pkg->{bdep}})) if @{$pkg->{bdep}};
  144. print "|";
  145. print join(' ', sort(@{$pkg->{rdep}})) if @{$pkg->{rdep}};
  146. print "|$pkg->{rest}|";
  147. print join(' ', sort(@{$pkg->{edep}})) if @{$pkg->{edep}};
  148. print "|";
  149. print join(' ', sort(@{$pkg->{pdep}})) if @{$pkg->{pdep}};
  150. print "|";
  151. print join(' ', sort(@{$pkg->{fdep}})) if @{$pkg->{fdep}};
  152. print "\n";
  153. ++$pkg->{'PRINTED'};
  154. }
  155. }