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