summaryrefslogtreecommitdiff
path: root/dh
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2013-05-05 13:32:18 -0400
committerJoey Hess <joey@kitenet.net>2013-05-05 13:32:18 -0400
commitfd04390350046c0edc8f21c0c8baf4ae0313a00a (patch)
tree1ec6446e5dbf49d1c7ec4b589e365b4b756a324b /dh
parent89c2e3111c13cd85942dd1063ae5a3ab365278e2 (diff)
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.
Diffstat (limited to 'dh')
-rwxr-xr-xdh53
1 files changed, 53 insertions, 0 deletions
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<dh> 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<debhelper(7)>