mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
6.5 KiB

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use English;
  4. my (@pkg, %opr, %pri, %dep, %rep, %rdp, %ign, %lop, %deldeps, %bas);
  5. my @useddeps; # deps used for visualization of cross dependencies
  6. my %pkg_redone; # packages built in stages 6-8
  7. my $config = "";
  8. while ($_ = shift @ARGV) {
  9. if ( $_ eq "-cfg" ) {
  10. $config = shift @ARGV;
  11. } elsif ( /^-/ ) {
  12. print "\n";
  13. print "Usgage: scripts/Check-Deps-2 [ -cfg config-name ]\n";
  14. print "\n";
  15. print "This script does some dependency checking and suggests\n";
  16. print "package priority reorderings (if neccessary).\n";
  17. print "\n";
  18. print "The data from scripts/dep_db.txt and scripts/dep_fixes.txt\n";
  19. print "is used for the dependency analysis.\n";
  20. print "\n";
  21. exit 1;
  22. } else {
  23. $ign{$_} = 1;
  24. }
  25. }
  26. unlink $_ foreach qw/dependencies.dbg dependencies.dot dependencies.patch dependencies.png dependencies.ps/;
  27. print "Reading package priorities ...\n";
  28. if ( $config eq "" ) {
  29. open(F, "./scripts/Create-PkgList |") || die $!;
  30. } else {
  31. open(F, "< config/$config/packages") || die $!;
  32. }
  33. while (<F>) {
  34. @_ = split /\s+/;
  35. next if $_[1] =~ /[1234]/ or $_[1] !~ /5/;
  36. $pkg_redone{$_[4]} = 1 if $_[1] =~ /[678]/;
  37. next if defined $ign{$_[3]} || defined $ign{$_[4]};
  38. my ($b, $p) = ($_[4], $_[4]);
  39. ($b, $p) = ($1, $2) if $_[4] =~ /(.*)=(.*)/;
  40. $opr{$p} = $_[2];
  41. $pri{$p} = $_[2];
  42. $rep{$p} = $_[3];
  43. $bas{$p} = $b;
  44. $pkg[$#pkg+1] = $p;
  45. }
  46. close F;
  47. print "Reading dependency fixes ...\n";
  48. open(F, "scripts/dep_fixes.txt") or die $!;
  49. while (<F>) {
  50. chomp;
  51. if (/^([^#\s]\S*)\s+del\s+(.*)$/) {
  52. my ($p, $l) = ($1, $2);
  53. $deldeps{$p}{$_} = 1 foreach (split /\s+/, $l);
  54. next;
  55. }
  56. if (/^([^#\s]\S*)\s+add\s+(.*)$/) {
  57. my ($p, $l) = ($1, $2);
  58. foreach ( split /\s+/, $l ) {
  59. push @{$dep{$p}}, $_;
  60. push @{$rdp{$_}}, $p;
  61. }
  62. next;
  63. }
  64. }
  65. close F;
  66. print "Reading package dependencies ...\n";
  67. open(F, "scripts/dep_db.txt") || die $!;
  68. while (<F>) {
  69. chomp;
  70. if ( ! /^(\S+): \d+ \d+ (.*)$/ ) {
  71. print "Format Error: $_\n";
  72. exit 1;
  73. }
  74. my ($p, $l) = ($1, $2);
  75. next if defined $pkg_redone{$p};
  76. foreach ( split /\s+/, $l ) {
  77. next if defined $deldeps{$p}{$_};
  78. push @{$dep{$p}}, $_;
  79. push @{$rdp{$_}}, $p;
  80. }
  81. }
  82. close F;
  83. sub count_errs($) {
  84. my $package = $_[0];
  85. my $dependency;
  86. my $errors = 0;
  87. foreach $dependency (@{$dep{$package}}) {
  88. next unless defined $pri{$dependency};
  89. $errors++ if $pri{$package} < $pri{$dependency};
  90. }
  91. foreach $dependency (@{$rdp{$package}}) {
  92. next unless defined $pri{$dependency};
  93. $errors++ if $pri{$package} > $pri{$dependency};
  94. }
  95. return $errors;
  96. }
  97. my ($iteration, $package, $dependency, $a, $b);
  98. my $did_something=0;
  99. print "\nLoop Old/New Errors Package Dependency\n".
  100. "------------------------------------------------------------------------\n";
  101. for $iteration (1..99) {
  102. my $looplog = '';
  103. foreach $package (@pkg) {
  104. foreach $dependency (@{$dep{$package}}) {
  105. next unless defined $pri{$dependency};
  106. if ( $pri{$package} < $pri{$dependency} ) {
  107. $a = count_errs($package) + count_errs($dependency);
  108. $_ = $pri{$dependency};
  109. $pri{$dependency} = $pri{$package};
  110. $pri{$package} = $_;
  111. $b = count_errs($package) + count_errs($dependency);
  112. $looplog.="[$package,$dependency]";
  113. $_ = sprintf "[%02d] %-7d %-7d %-25s %s\n",
  114. $iteration, $a, $b, $pri{$dependency}." ".$package,
  115. $pri{$package}." ".$dependency;
  116. $useddeps[$iteration]{$package}{$dependency} = 1;
  117. s/ / . /g; s/\. /.. /g; s/\. /.. /g;
  118. s/\. (\s*)\./..$1./g; s/\. (\s*)\./..$1./g;
  119. print; $did_something=1;
  120. }
  121. }
  122. }
  123. last if $looplog eq "";
  124. if (defined $lop{$looplog}) {
  125. my %crossdeps;
  126. print "[XX] Detected endless-loop ".
  127. "(cross-dependency) -> Aborting now.\n";
  128. print "[XX] Debug graph printed to dependencies.dot.\n";
  129. foreach my $i ($lop{$looplog} .. $iteration) {
  130. foreach my $p (keys %{$useddeps[$i]}) {
  131. foreach my $d (keys %{$useddeps[$i]{$p}}) {
  132. $crossdeps{$d}{$p} = 1;
  133. }
  134. }
  135. }
  136. open(F, ">dependencies.dot") || die $!;
  137. print F "# run this thru e.g. 'dot -Tps dependencies.dot -o dependencies.ps'\n";
  138. print F "digraph \"Cross-Dependencies Graph\" {\n";
  139. print F " Package_X -> Has_X_in_Dep_List;\n";
  140. foreach my $p (sort keys %crossdeps) {
  141. foreach my $d (sort keys %{$crossdeps{$p}})
  142. {
  143. my $pt = `gawk '/^.TIMESTAMP/ && !/ERROR/ { print \$2; exit; }' package/*/$p/*.cache 2> /dev/null`;
  144. my $dt = `gawk '/^.TIMESTAMP/ && !/ERROR/ { print \$2; exit; }' package/*/$d/*.cache 2> /dev/null`;
  145. chomp $pt; chomp $dt;
  146. my $p_ = $p; $p_ =~ s/[^a-z0-9]/_/g;
  147. my $d_ = $d; $d_ =~ s/[^a-z0-9]/_/g;
  148. if ( $pt eq "" || $dt eq "" || $pt < $dt ) {
  149. print F "\t$p_ -> $d_;\n";
  150. } else {
  151. print F "#\t$p = ($pt), $d = ($dt)\n";
  152. print F "\t$p_ -> $d_ [color=red];\n";
  153. }
  154. }
  155. }
  156. print F "}\n";
  157. close F;
  158. open(F, ">dependencies.dbg") || die $!;
  159. foreach my $p (sort keys %crossdeps) {
  160. foreach my $d (sort keys %{$crossdeps{$p}}) {
  161. print F "$p $d\n";
  162. }
  163. }
  164. close F;
  165. system("dot -Tps dependencies.dot -o dependencies.ps");
  166. system("convert dependencies.ps dependencies.png");
  167. last;
  168. }
  169. $lop{$looplog} = $iteration;
  170. }
  171. sub patchfile($$$$) {
  172. my ($tmpfile, $descfile, $re1, $re2) = @_;
  173. if ( ! open(IN, $descfile) )
  174. { print "ERROR: $descfile: $!\n"; return; }
  175. if ( ! open(OUT, ">$tmpfile") )
  176. { print "ERROR: $descfile: $!\n"; close IN; return; }
  177. $did_something = 0;
  178. while (<IN>) {
  179. $did_something = 1 if eval "s/$re1/$re2/i";
  180. print OUT;
  181. }
  182. close IN; close OUT;
  183. if (not $did_something) {
  184. print "ERROR: Can't patch $descfile!\n";
  185. print "ERROR: Regex was s/$re1/$re2/\n";
  186. }
  187. system("diff -U 0 ./$descfile $tmpfile >> dependencies.patch");
  188. }
  189. sub setpri($$$$$$) {
  190. my ($pri, $opr, $rep, $bas, $package, $tmpfile) = @_;
  191. if ($bas eq "cpan") {
  192. my $r = $package; $r =~ s/^cpan-//g; $r =~ s/-/(-|::)/g;
  193. patchfile($tmpfile, "package/import/cpan/hosted_cpan.txt",
  194. "$opr ($r)", "$pri \$1");
  195. patchfile($tmpfile, "package/import/cpan/hosted_cpan.cfg",
  196. "(pkgfork cpan $package .*) $opr;", "\$1 $pri;");
  197. return;
  198. }
  199. patchfile($tmpfile, "package/$rep/$bas/$package.desc",
  200. "(\\[P\\] . \\S+) $opr", "\$1 $pri");
  201. }
  202. if ( $did_something ) {
  203. print "\nCreate dependencies.patch ...\n";
  204. my $tmpfile = `mktemp`; chomp $tmpfile;
  205. foreach $package (@pkg) {
  206. if ($pri{$package} != $opr{$package}) {
  207. print "Setting priority $pri{$package} on package $rep{$package}/$bas{$package}=$package.\n";
  208. setpri($pri{$package}, $opr{$package}, $rep{$package}, $bas{$package}, $package, $tmpfile);
  209. }
  210. }
  211. unlink $tmpfile;
  212. print "Done. Please check moves manually before applying the patch.\n";
  213. } else {
  214. print "No unresolved dependencies found.\n";
  215. }