Преглед изворни кода

Preserve the order of dependencies and build-dependencies

* scripts/dpkg-gencontrol.pl, scripts/dpkg-source.pl:
Do not sort the dependency fields as order matters given
the greedy algorithm that APT uses when trying to resolve
dependencies. See discussion on debian-devel:
http://lists.debian.org/debian-devel/2008/02/msg00893.html
* man/dpkg-gencontrol.1: Document the above changes.

* scripts/Dpkg/Deps.pm (simplify_deps): Tries to respect order put
by the maintainer when simplifying dependencies.
* scripts/t/400_Dpkg_Deps.t: Add a test-case to ensure that
further changes respect this constraint.

* scripts/dpkg-shlibdeps.pl: Sort generated dependencies to
have a deterministic output.
Raphael Hertzog пре 18 година
родитељ
комит
bd244cd5d5

+ 17 - 0
ChangeLog

@@ -1,3 +1,20 @@
+2008-03-02  Raphael Hertzog  <hertzog@debian.org>
+
+	* scripts/dpkg-gencontrol.pl, scripts/dpkg-source.pl:
+	Do not sort the dependency fields as order matters given
+	the greedy algorithm that APT uses when trying to resolve
+	dependencies. See discussion on debian-devel:
+	http://lists.debian.org/debian-devel/2008/02/msg00893.html
+	* man/dpkg-gencontrol.1: Document the above changes.
+
+	* scripts/Dpkg/Deps.pm (simplify_deps): Tries to respect order put
+	by the maintainer when simplifying dependencies.
+	* scripts/t/400_Dpkg_Deps.t: Add a test-case to ensure that
+	further changes respect this constraint.
+
+	* scripts/dpkg-shlibdeps.pl: Sort generated dependencies to
+	have a deterministic output.
+
 2008-02-29  Frank Lichtenheld  <djpig@debian.org>
 
 	* scripts/Dpkg/Changelog/Debian.pm (parse):

+ 9 - 0
debian/changelog

@@ -46,6 +46,15 @@ dpkg (1.14.17) UNRELEASED; urgency=low
     concerns upgrading from dpkg version older than the one in oldstable
     already. And thus we get rid of old the last usage of read in those
     scripts (fixes lintian's warning read-in-maintainer-script).
+  * Removed sorting of dependencies in dpkg-gencontrol and dpkg-source. But
+    kept it for all other fields (Enhances, Conflicts, Replaces, Breaks,
+    Build-Conflicts and Build-Conflicts-Indep).
+  * Instead changed dpkg-shlibdeps to sort the dependencies generated in
+    ${shlibs:*} variables.
+  * Changed the logic of simplification of dependencies: if any dependency
+    must be discarded due to another dependency appearing further
+    in the field, the superseding dependency will take the place of the
+    discarded one. Added a test case for this.
 
   [ Frank Lichtenheld ]
   * Add a warning in dpkg-buildpackage if the build-dependencies are not

+ 8 - 5
man/dpkg-gencontrol.1

@@ -1,4 +1,4 @@
-.TH dpkg\-gencontrol 1 "2007-06-12" "Debian Project" "dpkg utilities"
+.TH dpkg\-gencontrol 1 "2008-03-02" "Debian Project" "dpkg utilities"
 .SH NAME
 dpkg\-gencontrol \- generate Debian control files
 .
@@ -10,8 +10,7 @@ dpkg\-gencontrol \- generate Debian control files
 .B dpkg\-gencontrol
 reads information from an unpacked Debian source tree and generates a
 binary package control file (which defaults to debian/tmp/DEBIAN/control);
-during this process it will simplify the relation fields and rewrite them
-in a sorted manner.
+during this process it will simplify the relation fields.
 .sp
 Thus
 .IR Pre-Depends ", " Depends ", " Recommends " and " Suggests
@@ -20,7 +19,11 @@ order by removing dependencies which are known to be true according to the
 stronger dependencies already parsed. It will also remove any self-dependency
 (in fact it will remove any dependency which evaluates to true given the
 current version of the package as installed). Logically it keeps the
-intersection of multiple dependencies on the same package.
+intersection of multiple dependencies on the same package. The order
+of dependencies is preserved as best as possible: if any dependency
+must be discarded due to another dependency appearing further
+in the field, the superseding dependency will take the place of the
+discarded one.
 .sp
 The other relation fields
 .RI ( Enhances ", " Conflicts ", " Breaks ", " Replaces " and " Provides )
@@ -139,7 +142,7 @@ Copyright (C) 1995-1996 Ian Jackson
 .br
 Copyright (C) 2000 Wichert Akkerman
 .br
-Copyright (C) 2007 Rapha\[:e]l Hertzog
+Copyright (C) 2007-2008 Rapha\[:e]l Hertzog
 .sp
 This is free software; see the GNU General Public Licence version 2 or later
 for copying conditions. There is NO WARRANTY.

+ 13 - 1
scripts/Dpkg/Deps.pm

@@ -912,9 +912,21 @@ WHILELOOP:
 	my $dep = shift @{$self->{list}};
 	my $eval = $dep->get_evaluation($facts);
 	next if defined($eval) and $eval == 1;
-	foreach my $odep (@knowndeps, @new, @{$self->{list}}) {
+	foreach my $odep (@knowndeps, @new) {
 	    next WHILELOOP if $odep->implies($dep);
 	}
+        # When a dependency is implied by another dependency that
+        # follows, then invert them
+        # "a | b, c, a"  becomes "a, c" and not "c, a"
+        my $i = 0;
+	foreach my $odep (@{$self->{list}}) {
+            if (defined $odep and $odep->implies($dep)) {
+                splice @{$self->{list}}, $i, 1;
+                unshift @{$self->{list}}, $odep;
+                next WHILELOOP;
+            }
+            $i++;
+	}
 	push @new, $dep;
     }
     $self->{list} = [ @new ];

+ 1 - 1
scripts/dpkg-gencontrol.pl

@@ -250,8 +250,8 @@ foreach my $field (@pkg_dep_fields) {
                                      reduce_arch => 1, union => 1);
 	    error(_g("error occurred while parsing %s"), $field_value) unless defined $dep;
 	    $dep->simplify_deps($facts);
+            $dep->sort();
 	}
-	$dep->sort();
 	$fields->{$field} = $dep->dump();
 	delete $fields->{$field} unless $fields->{$field}; # Delete empty field
     }

+ 4 - 1
scripts/dpkg-shlibdeps.pl

@@ -375,7 +375,10 @@ foreach my $field (reverse @depfields) {
 	    keys %{$dependencies{$field}};
     }
     if ($dep) {
-	print $fh "$varnameprefix:$field=$dep\n";
+        my $obj = Dpkg::Deps::parse($dep);
+        error(_g("invalid dependency got generated: %s"), $dep) unless defined $obj;
+        $obj->sort();
+	print $fh "$varnameprefix:$field=" . $obj->dump() . "\n";
     }
 }
 

+ 2 - 2
scripts/dpkg-source.pl

@@ -322,11 +322,11 @@ if ($opmode eq 'build') {
 	} elsif (m/^Build-(Depends|Conflicts)(-Indep)?$/i) {
 	    my $dep;
 	    my $type = $dep_field_type{capit($_)};
-	    $dep = Dpkg::Deps::parse($v, union =>  $type eq 'union');
+	    $dep = Dpkg::Deps::parse($v, union => $type eq 'union');
 	    error(_g("error occurred while parsing %s"), $_) unless defined $dep;
 	    my $facts = Dpkg::Deps::KnownFacts->new();
 	    $dep->simplify_deps($facts);
-	    $dep->sort();
+	    $dep->sort() if $type eq 'union';
 	    $fields->{$_} = $dep->dump();
 	} elsif (s/^X[BC]*S[BC]*-//i) { # Include XS-* fields
 	    $fields->{$_} = $v;

+ 5 - 1
scripts/t/400_Dpkg_Deps.t

@@ -1,6 +1,6 @@
 # -*- mode: cperl;-*-
 
-use Test::More tests => 14;
+use Test::More tests => 15;
 
 use strict;
 use warnings;
@@ -53,6 +53,10 @@ my $dep_dup_union = Dpkg::Deps::parse($field_dup_union, union => 1);
 $dep_dup_union->simplify_deps($facts);
 is($dep_dup_union->dump(), "libc6 (>> 2.3), fake (<< 2.0), fake (>> 3.0), fake (= 2.5), python (<< 2.5)", "Simplify union deps");
 
+my $dep_red = Dpkg::Deps::parse("abc | xyz, two, abc");
+$dep_red->simplify_deps($facts, $dep_opposite);
+is($dep_red->dump(), "abc, two", "Simplification respect order");
+
 my $dep_empty1 = Dpkg::Deps::parse("");
 is($dep_empty1->dump(), "", "Empty dependency");