From bd244cd5d5699e8ece1713398c0bb4c732f60932 Mon Sep 17 00:00:00 2001 From: Raphael Hertzog Date: Sun, 2 Mar 2008 16:37:27 +0100 Subject: [PATCH] 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. --- ChangeLog | 17 +++++++++++++++++ debian/changelog | 9 +++++++++ man/dpkg-gencontrol.1 | 13 ++++++++----- scripts/Dpkg/Deps.pm | 14 +++++++++++++- scripts/dpkg-gencontrol.pl | 2 +- scripts/dpkg-shlibdeps.pl | 5 ++++- scripts/dpkg-source.pl | 4 ++-- scripts/t/400_Dpkg_Deps.t | 6 +++++- 8 files changed, 59 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8615cd80..ec9e52d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-03-02 Raphael Hertzog + + * 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 * scripts/Dpkg/Changelog/Debian.pm (parse): diff --git a/debian/changelog b/debian/changelog index 225ea6a3..10083745 100644 --- a/debian/changelog +++ b/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 diff --git a/man/dpkg-gencontrol.1 b/man/dpkg-gencontrol.1 index c90f3cea..61ef136b 100644 --- a/man/dpkg-gencontrol.1 +++ b/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. diff --git a/scripts/Dpkg/Deps.pm b/scripts/Dpkg/Deps.pm index 4ceceb5f..b012d92f 100644 --- a/scripts/Dpkg/Deps.pm +++ b/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 ]; diff --git a/scripts/dpkg-gencontrol.pl b/scripts/dpkg-gencontrol.pl index 93aca3f1..584c9c91 100755 --- a/scripts/dpkg-gencontrol.pl +++ b/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 } diff --git a/scripts/dpkg-shlibdeps.pl b/scripts/dpkg-shlibdeps.pl index e60ed7f5..92655f94 100755 --- a/scripts/dpkg-shlibdeps.pl +++ b/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"; } } diff --git a/scripts/dpkg-source.pl b/scripts/dpkg-source.pl index b63aedba..cea50033 100755 --- a/scripts/dpkg-source.pl +++ b/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; diff --git a/scripts/t/400_Dpkg_Deps.t b/scripts/t/400_Dpkg_Deps.t index 47517542..8490c169 100644 --- a/scripts/t/400_Dpkg_Deps.t +++ b/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"); -- 2.39.5