Package: debhelper
Version: 7.2.6
Severity: normal
Tags: patch

Hello,

consider the following debian/rules snippet:

override_dh_makeshlibs:
        dh_makeshlibs -pliba -V'liba (>= 0.1)'
        dh_makeshlibs -plibb -V'libb (>= 0.1)'

When this override is called via `dh binary-arch`, DH_INTERNAL_OPTIONS contains
-a. Hence both dh_makeshlibs calls apply to *all* arch:any packages regardless
of the -p option specified on the command line.  I strongly believe that this
is not what most developers would except. What is more, most would be very
confused as DH_INTERNAL_OPTIONS is sort of black magic and is not visible in
the output. Currently, it is possible to workaround this by:

1) override_dh_makeshlibs: export DH_INTERNAL_OPTIONS=
   I believe this is very ugly "solution". Package maintainers are not
   supposed to care about DH_INTERNAL_OPTIONS which is not even documented;
2) doing some -Npackage magic on the command line. Ugly;
3) adding another option, e.g. --reset-package-list  or -Ppackage, which would
   delete DOPACKAGES/DOINDEP/DOARCH/DOSAME  before adding the package specified.
   Less ugly but still rather hackish and not very straightfoward and intuitive;
4) ignoring -a/-i/-s/-p passed via DH_INTERNAL_OPTIONS if either of these 
options
   is specified on the command line. That's what the attached 0001 patch is
   about. You could simplify the patch a bit (i.e. avoid backup_hash() /
   restore_hash()) if you moved DH_INTERNAL_OPTIONS processing before
   DH_OPTIONS processing. Then it would be possible get away with a bunch of
   deletes instead of backup/restore.  I don't really know if -N options passed
   via DH_INTERNAL_OPTIONS should be "cancelled" either. I believe not hence my
   patch does not do it.
5) it might be a good idea to make DH_INTERNAL_OPTIONS package list supervisory 
for
   the package list initialized from the command line, i.e. ignore those
   packages specified on the command line which are not in the set of
   DOPACKAGES constructed from DH_INTERNAL_OPTIONS. This way the same override
   would always process a proper set of packages under both `dh binary-indep`
   and `dh binary-arch`, e.g.:

override_dh_install:
        dh_install -ppkg-data debian/icon.xpm # becomes noop under `dh 
binary-arch` run
    dh_install -ppkg # becomes noop under `dh binary-indep`

  That's what patch 0002 is about.


-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (101, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.28-1-amd64 (SMP w/1 CPU core)
Locale: LANG=lt_LT.UTF-8, LC_CTYPE=lt_LT.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages debhelper depends on:
ii  binutils                      2.19.1-1   The GNU assembler, linker and bina
ii  dpkg-dev                      1.15.0     Debian package development tools
ii  file                          4.26-2     Determines file type using "magic"
ii  html2text                     1.3.2a-13  advanced HTML to text converter
ii  man-db                        2.5.5-1    on-line manual pager
ii  perl                          5.10.0-19  Larry Wall's Practical Extraction 
ii  po-debconf                    1.0.15     manage translated Debconf template

debhelper recommends no packages.

Versions of packages debhelper suggests:
pn  dh-make                       <none>     (no description available)

-- no debconf information
>From 85e2abd25243dd0ddd0a7d08c475877f002b10c1 Mon Sep 17 00:00:00 2001
From: Modestas Vainius <modes...@vainius.eu>
Date: Sat, 21 Mar 2009 01:06:11 +0200
Subject: [PATCH 1/2] Make cmdline -a/-i/-s/-p override these options from 
DH_INTERNAL_OPTIONS.

Ignore -a/-i/-s/-p options speficied via DH_INTERNAL_OPTIONS
when either of them is passed via command line. This makes it
possible to call the same helper a few times from the override
for different set(s) of packages.

Signed-off-by: Modestas Vainius <modes...@vainius.eu>
---
 Debian/Debhelper/Dh_Getopt.pm |   49 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/Debian/Debhelper/Dh_Getopt.pm b/Debian/Debhelper/Dh_Getopt.pm
index afad4b3..a1e1a7d 100644
--- a/Debian/Debhelper/Dh_Getopt.pm
+++ b/Debian/Debhelper/Dh_Getopt.pm
@@ -11,6 +11,7 @@ use Debian::Debhelper::Dh_Lib;
 use Getopt::Long;
 
 my %exclude_package;
+my $pre_internal_dh_backup;
 
 sub showhelp {
        my $prog=basename($0);
@@ -20,10 +21,48 @@ sub showhelp {
        exit(1);
 }
 
+sub backup_hash {
+       my $orig = shift;
+       my %backup;
+       @_ = keys(%$orig) if (!...@_);
+
+       for my $k (@_) {
+               next if (!exists $orig->{$k});
+
+               if (ref($orig->{$k}) eq 'ARRAY') {
+                       push @{$backup{$k}}, @{$orig->{$k}};
+               } else {
+                       $backup{$k} = $orig->{$k};
+               }
+       }
+       return \%backup;
+}
+
+sub restore_hash {
+       my $dst = shift;
+       my $src = shift;
+       @_ = keys(%$src) if (!...@_);
+
+       for my $k (@_) {
+               if (exists $src->{$k}) {
+                       $dst->{$k} = $src->{$k};
+               }
+               elsif (exists $dst->{$k}) {
+                       delete $dst->{$k};
+               }
+       }
+}
+
 # Passed an option name and an option value, adds packages to the list
 # of packages. We need this so the list will be built up in the right
 # order.
 sub AddPackage { my($option,$value)=...@_;
+       if (defined $pre_internal_dh_backup) {
+               # Rollback package list related options to
+               # pre DH_INTERNAL_OPTIONS state
+               restore_hash(\%dh, $pre_internal_dh_backup, qw(DOINDEP DOARCH 
DOSAME DOPACKAGES));
+               $pre_internal_dh_backup = undef;
+       }
        if ($option eq 'i' or $option eq 'indep') {
                push @{$dh{DOPACKAGES}}, getpackages('indep');
                $dh{DOINDEP}=1;
@@ -164,7 +203,15 @@ sub parseopts {
        if (defined $ENV{DH_INTERNAL_OPTIONS}) {
                $ENV{DH_INTERNAL_OPTIONS}=~s/^\s+//;
                $ENV{DH_INTERNAL_OPTIONS}=~s/\s+$//;
-               unshift @ARGV, split(/\s+/,$ENV{DH_INTERNAL_OPTIONS});
+               my @ARGV_internal = split(/\s+/,$ENV{DH_INTERNAL_OPTIONS});
+
+               # Backup package list related dh options in case we need to
+               # rollback them later (see sub AddPackage)
+               my $backup = backup_hash(\%dh, qw(DOINDEP DOARCH DOSAME 
DOPACKAGES));
+               if (!getoptions(\...@argv_internal, $options)) {
+                       error("error: unrecognized internal option(s)");
+               }
+               $pre_internal_dh_backup = $backup;
        }
 
        my $ret=getoptions(\...@argv, $options);
-- 
1.6.2.1

>From 8e9b05fa953557cee1ce1c737cea7c6ed2f259d4 Mon Sep 17 00:00:00 2001
From: Modestas Vainius <modes...@vainius.eu>
Date: Sat, 21 Mar 2009 01:06:11 +0200
Subject: [PATCH 2/2] Limit command line package list with DH_INTERNAL_OPTIONS 
package list.

Ensure that -a/-i/-s/-p speficied on the command line is less than package
list speficied via DH_INTERNAL_OPTIONS (if any).

Signed-off-by: Modestas Vainius <modes...@vainius.eu>
---
 Debian/Debhelper/Dh_Getopt.pm |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/Debian/Debhelper/Dh_Getopt.pm b/Debian/Debhelper/Dh_Getopt.pm
index a1e1a7d..73f57bc 100644
--- a/Debian/Debhelper/Dh_Getopt.pm
+++ b/Debian/Debhelper/Dh_Getopt.pm
@@ -12,6 +12,7 @@ use Getopt::Long;
 
 my %exclude_package;
 my $pre_internal_dh_backup;
+my %allowed_dopackages;
 
 sub showhelp {
        my $prog=basename($0);
@@ -208,9 +209,20 @@ sub parseopts {
                # Backup package list related dh options in case we need to
                # rollback them later (see sub AddPackage)
                my $backup = backup_hash(\%dh, qw(DOINDEP DOARCH DOSAME 
DOPACKAGES));
+               # This is needed to prevent contents of DH_OPTIONS from 
triggering
+               # allowed_dopackages creation below.
+               delete $dh{DOPACKAGES} if (exists $dh{DOPACKAGES});
                if (!getoptions(\...@argv_internal, $options)) {
                        error("error: unrecognized internal option(s)");
                }
+               # Fill allowed_dopackages from the list that was generated 
during
+               # processing of both DH_OPTIONS and DH_INTERNAL_OPTIONS
+               if (exists $dh{DOPACKAGES}) {
+                       if (exists $backup->{DOPACKAGES}) {
+                               unshift @{$dh{DOPACKAGES}}, 
@{$backup->{DOPACKAGES}};
+                       }
+                       map { $allowed_dopackages{$_} = 1 } @{$dh{DOPACKAGES}};
+               }
                $pre_internal_dh_backup = $backup;
        }
 
@@ -246,7 +258,8 @@ sub parseopts {
        my $package;
        my %packages_seen;
        foreach $package (@{$dh{DOPACKAGES}}) {
-               if (! $exclude_package{$package}) {
+               if (! $exclude_package{$package} &&
+                   (! %allowed_dopackages || exists 
$allowed_dopackages{$package})) {
                        if (! exists $packages_seen{$package}) {
                                $packages_seen{$package}=1;
                                push @package_list, $package;   
-- 
1.6.2.1

Reply via email to