Index: sbuild =================================================================== --- sbuild (revision 1019) +++ sbuild (working copy) @@ -1519,6 +1519,11 @@ } my $status = get_dpkg_status( keys %names ); + my %policy; + if ($conf::apt_policy) { + %policy = get_apt_policy( keys %names ); + } + foreach $dep (@$dependencies) { $name = $dep->{'Package'}; next if !$name; @@ -1572,6 +1577,23 @@ if (!$stat->{'Installed'}) { print "$name: pos dep, not installed\n" if $conf::debug; print PLOG "$name: missing\n"; + if ($conf::apt_policy && $rel) { + if (!WannaBuild::version_compare($policy{$name}->{defversion}, $rel, $vers)) { + print PLOG "Default version of $name not sufficient, "; + foreach my $cvers (@{$policy{$name}->{versions}}) { + if (WannaBuild::version_compare($cvers, $rel, $vers)) { + print PLOG "using version $cvers\n"; + $installable = $name . "=" . $cvers if !$installable; + last; + } + } + if(!$installable) { + print PLOG "no suitable version found. Skipping for now, maybe there are alternatives.\n" if !$installable; + } + } else { + print PLOG "Using default version " . $policy{$name}->{defversion} . "\n"; + } + } $installable = $name if !$installable; next; } @@ -1596,6 +1618,20 @@ print PLOG "$name: would have to downgrade!\n"; } else { + if ($conf::apt_policy && !WannaBuild::version_compare($policy{$name}->{defversion}, $rel, $vers)) { + print PLOG "Default version of $name not sufficient, "; + foreach my $cvers (@{$policy{$name}->{versions}}) { + if(WannaBuild::version_compare($cvers, $rel, $vers)) { + print PLOG "using version $cvers\n"; + $upgradeable = $name if ! $upgradeable; + last; + } + } + print PLOG "no suitable alternative found. I probably should dep-wait this one.\n" if !$upgradeable; + return 0; + } else { + print PLOG "Using default version " . $policy{$name}->{defversion} . "\n"; + } $upgradeable = $name if !$upgradeable; } } @@ -1609,9 +1645,9 @@ push( @$pos_list, $installable ); } else { - print PLOG "To satisfy this dependency the package(s) would ", - "have\n", - "to be downgraded; this is not implemented.\n"; + print PLOG "This dependency could not be satisfied. Possible reasons:\n"; + print PLOG "* The package has a versioned dependency that is not yet available.\n"; + print PLOG "* The package has a versioned dependency on a package version that is\n older than the currently-installed package. Downgrades are not implemented.\n"; return 0; } } @@ -1696,6 +1732,28 @@ return $fail; } +sub get_apt_policy { + my @interest = @_; + my $package; + my %packages; + + $ENV{LC_ALL}='C'; + + my $command = get_apt_command("$conf::apt_cache", "policy @interest", $main::username, 0); + + open(APTCACHE, "$command |" ) + or die "Cannot start $conf::apt_cache $!\n"; + while() { + $package=$1 if /^([0-9a-z+.-]+):$/; + $packages{$package}->{curversion}=$1 if /^ {2}Installed: ([0-9a-zA-Z-.:+]*)$/; + $packages{$package}->{defversion}=$1 if /^ {2}Candidate: ([0-9a-zA-Z-.:+]*)$/; + push @{$packages{$package}->{versions}}, "$2" if /^ (\*{3}| {3}) ([0-9a-zA-Z-.:+]*) 0$/; + } + die "$conf::apt_cache exit status $?\n" if $?; + + return %packages; +} + sub get_dpkg_status { my @interest = @_; my %result; Index: Sbuild/Conf.pm =================================================================== --- Sbuild/Conf.pm (revision 1018) +++ Sbuild/Conf.pm (working copy) @@ -32,7 +32,7 @@ @ISA = qw(Exporter); - @EXPORT = qw($HOME $cwd $username $verbose $nolog + @EXPORT = qw($HOME $apt_policy $cwd $username $verbose $nolog $source_dependencies $mailprog $dpkg $sudo $su $schroot $schroot_options $fakeroot $apt_get $apt_cache $dpkg_source $md5sum $avg_time_db @@ -81,6 +81,7 @@ our $srcdep_lock_wait = 1; # minutes our $chroot_only = 1; our $chroot_mode = "split"; +our $apt_policy = 1; our @ignore_watches_no_build_deps = qw(); our $build_dir = undef; our $sbuild_mode = "buildd"; Index: sbuild.conf.local =================================================================== --- sbuild.conf.local (revision 1018) +++ sbuild.conf.local (working copy) @@ -30,5 +30,12 @@ # Require chrooted building? #$chroot_only=1; +# APT policy. 1 to enable additional checking of package versions +# available in the APT cache, or 0 to disable. 0 is the traditional +# sbuild behaviour; 1 is needed to build from additional repositories +# such as sarge-backports or experimental, and has a small performance +# cost. +#$apt_policy = 1; + # don't remove this, Perl needs it: 1;