From fd04390350046c0edc8f21c0c8baf4ae0313a00a Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 5 May 2013 13:32:18 -0400 Subject: dh: Skips running commands that it can tell do nothing. This is determined by the presence of special PROMISE directives within commands that provide a high-level description of the command. Note that when dh is passed additional debhelper options, it cannot tell if these change the behavior of commands, and so it stops skipping any commands. --- debian/changelog | 3 +++ dh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dh_bugfiles | 4 +++- dh_gconf | 2 ++ dh_icons | 1 + dh_install | 2 ++ dh_installcatalogs | 2 ++ dh_installcron | 2 ++ dh_installdebconf | 2 ++ dh_installemacsen | 2 ++ dh_installexamples | 2 ++ dh_installgsettings | 2 ++ dh_installifupdown | 2 ++ dh_installinfo | 2 ++ dh_installinit | 3 ++- dh_installlogcheck | 2 ++ dh_installlogrotate | 2 ++ dh_installmenu | 2 ++ dh_installmime | 5 +++-- dh_installmodules | 15 +++------------ dh_installpam | 2 ++ dh_installppp | 2 ++ dh_installudev | 2 ++ dh_installwm | 2 ++ dh_installxfonts | 2 ++ dh_lintian | 2 ++ dh_ucf | 2 ++ dh_usrlocal | 2 ++ doc/PROGRAMMING | 10 ++++++++++ 29 files changed, 120 insertions(+), 16 deletions(-) diff --git a/debian/changelog b/debian/changelog index 62ae85d3..181beb01 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,8 @@ debhelper (9.20130505) UNRELEASED; urgency=low + * dh: Skips running commands that it can tell do nothing. Closes: #560423 + (This is determined by the presence of special PROMISE directives + within commands that provide a high-level description of the command.) * perl_makemaker: Unset INSTALL_BASE in case the user has it set. Closes: #705141 diff --git a/dh b/dh index 17919dce..acff00b3 100755 --- a/dh +++ b/dh @@ -67,6 +67,9 @@ List all available addons. Prints commands that would run for a given sequence, but does not run them. +Note that dh normally skips running commands that it knows will do nothing. +With --no-act, the full list of commands in a sequence is printed. + =back Other options passed to B are passed on to each command it runs. This @@ -545,6 +548,7 @@ my @packages=@{$dh{DOPACKAGES}}; # Get the options to pass to commands in the sequence. # Filter out options intended only for this program. my @options; +my $user_specified_options=0; if ($sequence eq 'build-arch' || $sequence eq 'install-arch' || $sequence eq 'binary-arch') { @@ -573,8 +577,10 @@ while (@ARGV_orig) { } elsif ($opt=~/^-/) { push @options, "-O".$opt; + $user_specified_options=1; } elsif (@options) { + $user_specified_options=1; if ($options[$#options]=~/^-O--/) { $options[$#options].="=".$opt; } @@ -668,6 +674,8 @@ foreach my $i (0..$stoppoint) { } next unless @todo; + next if can_skip($command, @todo) && ! $dh{NO_ACT}; + # No need to run the command for any packages handled by the # override targets. my %todo=map { $_ => 1 } @todo; @@ -900,6 +908,51 @@ sub command_pos { } } +my %skipinfo; +sub can_skip { + my $command=shift; + my @packages=@_; + + return 0 if $user_specified_options; + + if (! defined $skipinfo{$command}) { + $skipinfo{$command}=[extract_skipinfo($command)]; + } + my @skipinfo=@{$skipinfo{$command}}; + return 0 unless @skipinfo; + + foreach my $package (@packages) { + foreach my $skipinfo (@skipinfo) { + if ($skipinfo=~/^tmp(.*)$/) { + my $need=$1; + my $tmp=tmpdir($package); + return 0 if -e "$tmp/$need"; + } + elsif (pkgfile($package, $skipinfo) ne '') { + return 0; + } + } + } + return 1; +} + +sub extract_skipinfo { + my $command=shift; + + foreach my $dir (split (':', $ENV{PATH})) { + if (open (my $h, "<", "$dir/$command")) { + while (<$h>) { + if (m/PROMISE: DH NOOP WITHOUT\s+(.*)/) { + close $h; + return split(' ', $1); + } + } + close $h; + return (); + } + } +} + =head1 SEE ALSO L diff --git a/dh_bugfiles b/dh_bugfiles index 4444f0fc..83428f51 100755 --- a/dh_bugfiles +++ b/dh_bugfiles @@ -71,6 +71,7 @@ my %bugfile_types = ( "control" => "bug-control", "presubj" => "bug-presubj", ); +# PROMISE: DH NOOP WITHOUT bug-script bug-control bug-presubj foreach my $package (@{$dh{DOPACKAGES}}) { next if is_udeb($package); @@ -85,7 +86,8 @@ foreach my $package (@{$dh{DOPACKAGES}}) { my $file=pkgfile($package,$pkgfilename); if ($file) { $bugfiles{$type}=$file; - } elsif (-f "debian/$pkgfilename" && $dh{PARAMS_ALL}) { + } + elsif (-f "debian/$pkgfilename" && $dh{PARAMS_ALL}) { $bugfiles{$type}="debian/$pkgfilename"; } } diff --git a/dh_gconf b/dh_gconf index 1f3070e3..48b05ba2 100755 --- a/dh_gconf +++ b/dh_gconf @@ -58,6 +58,8 @@ if (defined $dh{PRIORITY}) { $priority=$dh{PRIORITY}; } +# PROMISE: DH NOOP WITHOUT gconf-mandatory gconf-defaults tmp(etc/gconf/schemas) tmp(usr/share/gconf/schemas) + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_icons b/dh_icons index d3182668..916f1885 100755 --- a/dh_icons +++ b/dh_icons @@ -41,6 +41,7 @@ Do not modify maintainer scripts. init(); +# PROMISE: DH NOOP WITHOUT tmp(usr/share/icons) my $baseicondir="/usr/share/icons"; foreach my $package (@{$dh{DOPACKAGES}}) { diff --git a/dh_install b/dh_install index fad3d922..7a6cc61d 100755 --- a/dh_install +++ b/dh_install @@ -126,6 +126,8 @@ my @installed; my $srcdir = '.'; $srcdir = $dh{SOURCEDIR} if defined $dh{SOURCEDIR}; +# PROMISE: DH NOOP WITHOUT install + foreach my $package (getpackages()) { # Look at the install files for all packages to handle # list-missing/fail-missing, but skip really installing for diff --git a/dh_installcatalogs b/dh_installcatalogs index b3aaf5e6..f65ab7cb 100755 --- a/dh_installcatalogs +++ b/dh_installcatalogs @@ -66,6 +66,8 @@ multiple instances of the same text to be added to maintainer scripts. init(); +# PROMISE: DH NOOP WITHOUT sgmlcatalogs + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmpdir = tmpdir($package); my $sgmlcatlistfile = pkgfile($package, "sgmlcatalogs"); diff --git a/dh_installcron b/dh_installcron index 694e288c..5e5851c1 100755 --- a/dh_installcron +++ b/dh_installcron @@ -53,6 +53,8 @@ as the package name. init(); +# PROMISE: DH NOOP WITHOUT cron.hourly cron.daily cron.weekly cron.monthly cron.d + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); foreach my $type (qw{hourly daily weekly monthly}) { diff --git a/dh_installdebconf b/dh_installdebconf index 5a20ed79..3eac7c99 100755 --- a/dh_installdebconf +++ b/dh_installdebconf @@ -81,6 +81,8 @@ if (defined($dh{U_PARAMS})) { @extraparams=@{$dh{U_PARAMS}}; } +# PROMISE: DH NOOP WITHOUT config templates + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $config=pkgfile($package,"config"); diff --git a/dh_installemacsen b/dh_installemacsen index ee642122..92037f20 100755 --- a/dh_installemacsen +++ b/dh_installemacsen @@ -83,6 +83,8 @@ if (! defined $dh{FLAVOR}) { $dh{FLAVOR}='emacs'; } +# PROMISE: DH NOOP WITHOUT emacsen-install emacsen-remove emacsen-startup + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_installexamples b/dh_installexamples index a39aa593..448678ad 100755 --- a/dh_installexamples +++ b/dh_installexamples @@ -60,6 +60,8 @@ directory, it will install the complete contents of the directory. init(); +# PROMISE: DH NOOP WITHOUT examples + foreach my $package (@{$dh{DOPACKAGES}}) { next if is_udeb($package); diff --git a/dh_installgsettings b/dh_installgsettings index 8500706c..dac471d5 100755 --- a/dh_installgsettings +++ b/dh_installgsettings @@ -59,6 +59,8 @@ if (defined $dh{PRIORITY}) { $priority=$dh{PRIORITY}; } +# PROMISE: DH NOOP WITHOUT gsettings-override tmp(usr/share/glib-2.0/schemas) + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_installifupdown b/dh_installifupdown index 2ea74f43..7b7c2ecf 100755 --- a/dh_installifupdown +++ b/dh_installifupdown @@ -52,6 +52,8 @@ as the package name. init(); +# PROMISE: DH NOOP WITHOUT if-pre-up if-up if-down if-post-down + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_installinfo b/dh_installinfo index 91ca96bb..c707a830 100755 --- a/dh_installinfo +++ b/dh_installinfo @@ -48,6 +48,8 @@ all packages if B<-A> is specified). init(); +# PROMISE: DH NOOP WITHOUT info + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $file=pkgfile($package,"info"); diff --git a/dh_installinit b/dh_installinit index 29937c5e..e4b67d01 100755 --- a/dh_installinit +++ b/dh_installinit @@ -155,6 +155,8 @@ init(options => { "remove-d" => \$dh{D_FLAG}, }); +# PROMISE: DH NOOP WITHOUT service tmpfile upstart init init.d + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); @@ -204,7 +206,6 @@ foreach my $package (@{$dh{DOPACKAGES}}) { } my $job=pkgfile($package,"upstart"); - if ($job ne '' && ! $dh{ONLYSCRIPTS}) { if (! -d "$tmp/etc/init") { doit("install","-d","$tmp/etc/init"); diff --git a/dh_installlogcheck b/dh_installlogcheck index 9bae597a..0821f1d5 100755 --- a/dh_installlogcheck +++ b/dh_installlogcheck @@ -55,6 +55,8 @@ use the specified name instead of that of the package. init(); +# PROMISE: DH NOOP WITHOUT logcheck.cracking logcheck.violations logcheck.violations.ignore logcheck.ignore.workstation logcheck.ignore.server logcheck.ignore.paranoid + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_installlogrotate b/dh_installlogrotate index 17b2a5ab..da14688c 100755 --- a/dh_installlogrotate +++ b/dh_installlogrotate @@ -35,6 +35,8 @@ as the package name. init(); +# PROMISE: DH NOOP WITHOUT logrotate + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $file=pkgfile($package,"logrotate"); diff --git a/dh_installmenu b/dh_installmenu index 689c0b2a..f5eae5db 100755 --- a/dh_installmenu +++ b/dh_installmenu @@ -52,6 +52,8 @@ Do not modify F/F scripts. init(); +# PROMISE: DH NOOP WITHOUT menu menu-method + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $menu=pkgfile($package,"menu"); diff --git a/dh_installmime b/dh_installmime index d44c9150..3360250f 100755 --- a/dh_installmime +++ b/dh_installmime @@ -38,10 +38,12 @@ directory. init(); +# PROMISE: DH NOOP WITHOUT mime sharedmimeinfo + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); + my $mime=pkgfile($package,"mime"); - if ($mime ne '') { if (! -d "$tmp/usr/lib/mime/packages") { doit("install","-d","$tmp/usr/lib/mime/packages"); @@ -50,7 +52,6 @@ foreach my $package (@{$dh{DOPACKAGES}}) { } my $sharedmimeinfo=pkgfile($package,"sharedmimeinfo"); - if ($sharedmimeinfo ne '') { if (! -d "$tmp/usr/share/mime/packages") { doit("install", "-d", "$tmp/usr/share/mime/packages"); diff --git a/dh_installmodules b/dh_installmodules index 9b3fc203..be31676f 100755 --- a/dh_installmodules +++ b/dh_installmodules @@ -2,8 +2,7 @@ =head1 NAME -dh_installmodules - register modules with modutils - +dh_installmodules - register kernel modules =cut @@ -34,11 +33,6 @@ L. Installed to etc/modprobe.d/I.conf in the package build directory. -=item debian/I.modules - -These files were installed for use by modutils, but are now not used -and B will warn if these files are present. - =back =head1 OPTIONS @@ -89,19 +83,16 @@ sub find_kernel_modules { return keys %versions; } +# PROMISE: DH NOOP WITHOUT modprobe tmp(lib/modules) + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); - my $modutils_file=pkgfile($package,"modules"); my $modprobe_file=pkgfile($package,"modprobe"); if (! -e $tmp) { doit("install","-d",$tmp); } - if ($modutils_file) { - warning("ignoring $modutils_file, since modutils is no longer in Debian"); - } - if ($modprobe_file) { if (! -e "$tmp/etc/modprobe.d") { doit("install","-d","$tmp/etc/modprobe.d"); diff --git a/dh_installpam b/dh_installpam index c7073863..80748818 100755 --- a/dh_installpam +++ b/dh_installpam @@ -44,6 +44,8 @@ using the package name. init(); +# PROMISE: DH NOOP WITHOUT pam + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $pam=pkgfile($package,"pam"); diff --git a/dh_installppp b/dh_installppp index 6762d143..dad24cd7 100755 --- a/dh_installppp +++ b/dh_installppp @@ -48,6 +48,8 @@ as the package name. init(); +# PROMISE: DH NOOP WITHOUT ppp.ip-up ppp.ip-down + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_installudev b/dh_installudev index fa369a02..6bac6f7c 100755 --- a/dh_installudev +++ b/dh_installudev @@ -81,6 +81,8 @@ if ($dh{PRIORITY}) { $old_priority.="_"; } +# PROMISE: DH NOOP WITHOUT udev + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $rules_file=pkgfile($package,"udev"); diff --git a/dh_installwm b/dh_installwm index a0f5f704..c3190e0b 100755 --- a/dh_installwm +++ b/dh_installwm @@ -73,6 +73,8 @@ if (@ARGV) { } } +# PROMISE: DH NOOP WITHOUT wm + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $file=pkgfile($package,"wm"); diff --git a/dh_installxfonts b/dh_installxfonts index d247bfad..c8ee5b34 100755 --- a/dh_installxfonts +++ b/dh_installxfonts @@ -46,6 +46,8 @@ way. init(); +# PROMISE: DH NOOP WITHOUT tmp(usr/share/fonts/X11) + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); diff --git a/dh_lintian b/dh_lintian index f7541df7..6e6ace0e 100755 --- a/dh_lintian +++ b/dh_lintian @@ -39,6 +39,8 @@ overrides for the source package. init(); +# PROMISE: DH NOOP WITHOUT lintian-overrides + foreach my $package (@{$dh{DOPACKAGES}}) { next if is_udeb($package); diff --git a/dh_ucf b/dh_ucf index 40a71c2b..98fc4ae9 100755 --- a/dh_ucf +++ b/dh_ucf @@ -54,6 +54,8 @@ instances of the same text to be added to maintainer scripts. init(); +# PROMISE: DH NOOP WITHOUT ucf + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp=tmpdir($package); my $file=pkgfile($package,"ucf"); diff --git a/dh_usrlocal b/dh_usrlocal index e92d909c..4ccc601b 100755 --- a/dh_usrlocal +++ b/dh_usrlocal @@ -60,6 +60,8 @@ Debian policy, version 2.2 init(); +# PROMISE: DH NOOP WITHOUT tmp(usr/local) + foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp = tmpdir($package); diff --git a/doc/PROGRAMMING b/doc/PROGRAMMING index e1440c91..e7b6e355 100644 --- a/doc/PROGRAMMING +++ b/doc/PROGRAMMING @@ -181,6 +181,16 @@ pkgfile($package, $basename) package. The convention is that the files are named debian/package.filename, and debian/filename is also allowable for the $dh{MAINPACKAGE}. If the file does not exist, nothing is returned. + + If the *entire* behavior of a command, when run without any special + options, is determined by the existence of 1 or more pkgfiles, + or by the existence of a file or directory in a location in the + tmpdir, it can be marked as such, which allows dh to automatically + skip running it. This is done by inserting a special comment, + of the form: + + # PROMISE: DH NOOP WITHOUT pkgfilea pkgfileb tmp(need/this) + pkgext($package) Pass this command the name of a binary package, and it will return the name to prefix to files in debian/ for this package. For the -- cgit v1.2.3