diff mbox

0008-First-attempt-to-add-Xapt-as-dependency-resolver.patch

Message ID 20111214180830.GV28260@dream.aleph1.co.uk
State Accepted
Headers show

Commit Message

Wookey Dec. 14, 2011, 6:08 p.m. UTC
From d6b46bd8d71468ee135d336fedcbbb05aba92290 Mon Sep 17 00:00:00 2001
From: Hector Oron <hector.oron@toby-churchill.com>
Date: Mon, 12 Dec 2011 19:21:29 +0000
Subject: [PATCH 08/17] First attempt to add Xapt as dependency resolver.

Signed-off-by: Hector Oron <hector.oron@toby-churchill.com>
---
 lib/Sbuild/Conf.pm         |    8 +++-
 lib/Sbuild/Resolver.pm     |    2 +
 lib/Sbuild/ResolverBase.pm |   54 +++++++++++++++++++++++
 lib/Sbuild/XaptResolver.pm |  102 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 164 insertions(+), 2 deletions(-)
 create mode 100644 lib/Sbuild/XaptResolver.pm
diff mbox

Patch

diff --git a/lib/Sbuild/Conf.pm b/lib/Sbuild/Conf.pm
index b2820af..b5b962a 100644
--- a/lib/Sbuild/Conf.pm
+++ b/lib/Sbuild/Conf.pm
@@ -253,6 +253,10 @@  sub setup ($) {
 	    DEFAULT => 'aptitude',
 	    HELP => 'Path to aptitude binary'
 	},
+	'XAPT'				=> {
+	    CHECK => $validate_program,
+	    DEFAULT => 'xapt'
+	},
 	'DPKG_BUILDPACKAGE_USER_OPTIONS'	=> {
 	    TYPE => 'ARRAY:STRING',
 	    GROUP => '__INTERNAL',
@@ -873,9 +877,9 @@  sub setup ($) {
 
 		die '$key: Invalid build-dependency resolver \'' .
 		    $conf->get($key) .
-		    "'\nValid algorthms are 'internal', 'apt' and 'aptitude'\n"
+		    "'\nValid algorithms are 'internal', 'xapt', 'apt' and 'aptitude'\n"
 		    if !isin($conf->get($key),
-			     qw(internal apt aptitude));
+			     qw(internal xapt apt aptitude));
 	    },
 	    HELP => 'Build dependency resolver.  The \'apt\' resolver is currently the default, and recommended for most users.  This resolver uses apt-get to resolve dependencies.  Alternative resolvers are \'apt\' and \'aptitude\', which use a built-in resolver module and aptitude to resolve build dependencies, respectively.  The internal resolver is not capable of resolving complex alternative and virtual package dependencies, but is otherwise equivalent to apt.  The aptitude resolver is similar to apt, but is useful in more complex situations, such as where multiple distributions are required, for example when building from experimental, where packages are needed from both unstable and experimental, but defaulting to unstable.'
 	},
diff --git a/lib/Sbuild/Resolver.pm b/lib/Sbuild/Resolver.pm
index 7c51a95..9437aa1 100644
--- a/lib/Sbuild/Resolver.pm
+++ b/lib/Sbuild/Resolver.pm
@@ -46,6 +46,8 @@  sub get_resolver ($$$) {
     my $resolver;
     if ($conf->get('BUILD_DEP_RESOLVER') eq "apt") {
 	$resolver = Sbuild::AptResolver->new($conf, $session, $host);
+    } elsif ($conf->get('BUILD_DEP_RESOLVER') eq "xapt") {
+	$resolver = Sbuild::XaptResolver->new($conf, $session, $host);
     } elsif ($conf->get('BUILD_DEP_RESOLVER') eq "aptitude") {
 	$resolver = Sbuild::AptitudeResolver->new($conf, $session, $host);
     } else {
diff --git a/lib/Sbuild/ResolverBase.pm b/lib/Sbuild/ResolverBase.pm
index 3f003c8..d2362bd 100644
--- a/lib/Sbuild/ResolverBase.pm
+++ b/lib/Sbuild/ResolverBase.pm
@@ -433,6 +433,60 @@  sub run_apt {
     return $mode eq "-s" || $status == 0;
 }
 
+sub run_xapt {
+    my $self = shift;
+    my $mode = shift;
+    my $inst_ret = shift;
+    my $rem_ret = shift;
+    my $action = shift;
+    my @packages = @_;
+    my( $msgs, $status, $pkgs, $rpkgs );
+
+    $msgs = "";
+    # redirection of stdin from /dev/null so that conffile question
+    # are treated as if RETURN was pressed.
+    # dpkg since 1.4.1.18 issues an error on the conffile question if
+    # it reads EOF -- hardwire the new --force-confold option to avoid
+    # the questions.
+    my @xapt_command = ($self->get_conf('XAPT'),
+	'-a', $self->get_conf('HOST_ARCH'));
+    # FIXME?:push @xapt_command, "$mode", $action, @packages;
+    push @xapt_command, @packages;
+    my $pipe =
+	$self->pipe_xapt_command(
+	    { COMMAND => \@xapt_command,
+	      ENV => {'DEBIAN_FRONTEND' => 'noninteractive'},
+	      USER => 'root',
+	      PRIORITY => 0,
+	      DIR => '/' });
+    if (!$pipe) {
+	$self->log("Can't open pipe to xapt: $!\n");
+	return 0;
+    }
+
+    while(<$pipe>) {
+	$msgs .= $_;
+	$self->log($_) if $mode ne "-s" || debug($_);
+    }
+    close($pipe);
+    $status = $?;
+
+    $pkgs = $rpkgs = "";
+    if ($msgs =~ /NEW packages will be installed:\n((^[ 	].*\n)*)/mi) {
+	($pkgs = $1) =~ s/^[ 	]*((.|\n)*)\s*$/$1/m;
+	$pkgs =~ s/\*//g;
+    }
+    if ($msgs =~ /packages will be REMOVED:\n((^[ 	].*\n)*)/mi) {
+	($rpkgs = $1) =~ s/^[ 	]*((.|\n)*)\s*$/$1/m;
+	$rpkgs =~ s/\*//g;
+    }
+    @$inst_ret = split( /\s+/, $pkgs );
+    @$rem_ret = split( /\s+/, $rpkgs );
+
+    $self->log("xapt failed.\n") if $status && $mode ne "-s";
+    return $mode eq "-s" || $status == 0;
+}
+
 sub format_deps {
     my $self = shift;
 
diff --git a/lib/Sbuild/XaptResolver.pm b/lib/Sbuild/XaptResolver.pm
new file mode 100644
index 0000000..6bc9309
--- /dev/null
+++ b/lib/Sbuild/XaptResolver.pm
@@ -0,0 +1,102 @@ 
+# ResolverBase.pm: build library for sbuild
+# Copyright © 2005      Ryan Murray <rmurray@debian.org>
+# Copyright © 2005-2008 Roger Leigh <rleigh@debian.org>
+# Copyright © 2008      Simon McVittie <smcv@debian.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#######################################################################
+
+package Sbuild::XaptResolver;
+
+use strict;
+use warnings;
+
+use Sbuild qw(debug);
+use Sbuild::Base;
+use Sbuild::ResolverBase;
+
+BEGIN {
+    use Exporter ();
+    our (@ISA, @EXPORT);
+
+    @ISA = qw(Exporter Sbuild::ResolverBase);
+
+    @EXPORT = qw();
+}
+
+sub new {
+    my $class = shift;
+    my $conf = shift;
+    my $session = shift;
+    my $host = shift;
+
+    my $self = $class->SUPER::new($conf, $session, $host);
+    bless($self, $class);
+
+    return $self;
+}
+
+sub install_deps {
+    my $self = shift;
+    my $name = shift;
+    my @pkgs = @_;
+
+    my $status = 0;
+    my $session = $self->get('Session');
+    my $dummy_pkg_name = 'sbuild-build-depends-' . $name. '-dummy';
+
+    # Call functions to setup an archive to install dummy package.
+    return 0 unless ($self->setup_apt_archive($dummy_pkg_name, @pkgs));
+    return 0 unless (!$self->update_archive());
+
+
+    $self->log_subsection("Install $name cross-build dependencies (xapt-based resolver)");
+
+    # Install the dummy package
+    my (@instd, @rmvd);
+    $self->log("Installing cross-build dependencies\n");
+    if (!$self->run_apt("-yf", \@instd, \@rmvd, 'install', $dummy_pkg_name)) {
+	$self->log("Package installation failed\n");
+	if (defined ($self->get('Session')->get('Session Purged')) &&
+	    $self->get('Session')->get('Session Purged') == 1) {
+	    $self->log("Not removing build depends: cloned chroot in use\n");
+	} else {
+	    $self->set_installed(@instd);
+	    $self->set_removed(@rmvd);
+	    goto package_cleanup;
+	}
+	return 0;
+    }
+    $self->set_installed(@instd);
+    $self->set_removed(@rmvd);
+    $status = 1;
+
+  package_cleanup:
+    if ($status == 0) {
+	if (defined ($session->get('Session Purged')) &&
+	    $session->get('Session Purged') == 1) {
+	    $self->log("Not removing installed packages: cloned chroot in use\n");
+	} else {
+	    $self->uninstall_deps();
+	}
+    }
+
+    $self->cleanup_apt_archive();
+
+    return $status;
+}
+
+1;