Package: devscripts
Version: 2.10.41
Severity: wishlist
Tags: patch

For complex multi-binary packages, I don't always want to install all
the binaries when testing my latest build. For example, ssh-krb5 is a
transitional package that rarely changes and that I don't need to have
installed myself, but I want to test the rest of openssh. Until now I've
just used 'dpkg -l' to remind myself of which binaries I have installed
and then used 'sudo dpkg -i' to install them by hand, but it would be
nice if debi could work that out for me.

The attached patch adds a new option, --upgrade, that uses dpkg-query to
figure out which packages are half-installed or better, and installs
only those.

Thanks,

-- 
Colin Watson                                       [EMAIL PROTECTED]
Index: scripts/debi.pl
===================================================================
--- scripts/debi.pl	(revision 1743)
+++ scripts/debi.pl	(working copy)
@@ -30,6 +30,9 @@
 use File::Basename;
 use filetest 'access';
 use Cwd;
+use File::Spec;
+use IPC::Open3;
+use Symbol 'gensym';
 
 my $progname = basename($0,'.pl');  # the '.pl' is for when we're debugging
 my $modified_conf_msg;
@@ -48,6 +51,7 @@
     --debs-dir DIR    Look for the changes and debs files in DIR instead of
                       the parent of the current package directory
     --multi           Search for multiarch .changes file made by dpkg-cross
+    --upgrade         Only upgrade packages; don't install new ones.
     --check-dirname-level N
                       How much to check directory names:
                       N=0   never
@@ -171,6 +175,7 @@
 
 # Command line options next
 my ($opt_help, $opt_version, $opt_a, $opt_t, $opt_debsdir, $opt_multi);
+my $opt_upgrade;
 my ($opt_ignore, $opt_level, $opt_regex, $opt_noconf);
 GetOptions("help" => \$opt_help,
 	   "version" => \$opt_version,
@@ -178,6 +183,7 @@
 	   "t=s" => \$opt_t,
 	   "debs-dir=s" => \$opt_debsdir,
 	   "multi" => \$opt_multi,
+	   "upgrade" => \$opt_upgrade,
 	   "ignore-dirname" => \$opt_ignore,
 	   "check-dirname-level=s" => \$opt_level,
 	   "check-dirname-regex=s" => \$opt_regex,
@@ -379,6 +385,42 @@
 }
 close CHANGES;
 
+if ($progname eq 'debi' and $opt_upgrade and @debs) {
+    my %installed;
+    my @cmd = ('dpkg-query', '-W', '-f', '${Package} ${Status}\n');
+    for my $deb (@debs) {
+	(my $pkg = $deb) =~ s/_.*//;
+	push @cmd, $pkg;
+    }
+    local (*NULL, *QUERY);
+    open NULL, '>', File::Spec->devnull;
+    my $pid = open3(gensym, \*QUERY, '>&NULL', @cmd)
+	or die "$progname: dpkg-query failed\n";
+    while (<QUERY>) {
+	my ($pkg, $want, $eflag, $status) = split;
+	if ($status and $status ne 'not-installed' and
+	    $status ne 'config-files') {
+	    $installed{$pkg} = 1;
+	}
+    }
+    close QUERY;
+    waitpid $pid, 0;
+    my @new_debs;
+    for my $deb (@debs) {
+	(my $pkg = $deb) =~ s/_.*//;
+	if ($installed{$pkg}) {
+	    push @new_debs, $deb;
+	} elsif (@ARGV) {
+	    if (exists $pkgs{$pkg}) {
+		$pkgs{$pkg}--;
+	    } elsif (exists $pkgs{$deb}) {
+		$pkgs{$deb}--;
+	    }
+	}
+    }
+    @debs = @new_debs;
+}
+
 if (! @debs) {
     die "$progname: no appropriate .debs found in the changes file $changes!\n";
 }
Index: scripts/debi.1
===================================================================
--- scripts/debi.1	(revision 1743)
+++ scripts/debi.1	(working copy)
@@ -76,6 +76,12 @@
 either be an absolute path or relative to the top of the source
 directory.
 .TP
+\fB\-\-upgrade\fR
+Only upgrade packages already installed on the system, rather than
+installing all packages listed in the \fI.changes\fR file.
+Useful for multi-binary packages when you don't want to have all the
+binaries installed at once.
+.TP
 \fB\-\-check-dirname-level\fR \fIN\fR
 See the above section "Directory name checking" for an explanation of
 this option.

Reply via email to