+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):
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
-.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
.
.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
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 )
.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.
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 ];
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
}
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";
}
}
} 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;
# -*- mode: cperl;-*-
-use Test::More tests => 14;
+use Test::More tests => 15;
use strict;
use warnings;
$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");