]> git.donarmstrong.com Git - debhelper.git/commitdiff
dh override targets
authorJoey Hess <joey@gnu.kitenet.net>
Fri, 27 Feb 2009 20:11:25 +0000 (15:11 -0500)
committerJoey Hess <joey@gnu.kitenet.net>
Fri, 27 Feb 2009 20:11:25 +0000 (15:11 -0500)
* dh: debian/rules override targets can change what is run
  for a specific debhelper command in a sequence.
* dh: Redid all the examples to use override targets, since these
  eliminate all annoying boilerplate and are much easier to understand
  than the old method.
* Remove rules.simple example, there's no need to use explcit targets
  with dh anymore.
(cherry picked from commit 0f3f59fe6058edfda4010dc88bd3b8aa3ae70a6d)

Conflicts:

Debian/Debhelper/Dh_Getopt.pm
Debian/Debhelper/Dh_Lib.pm
debian/changelog
dh

Debian/Debhelper/Dh_Getopt.pm
Debian/Debhelper/Dh_Lib.pm
debian/changelog
dh
examples/rules.simple [deleted file]

index f8e02889f9572c9cbcc4699a249ce73b435ef267..d8019337b4d2cbc13ef935ac837f91cd9979f53f 100644 (file)
@@ -191,6 +191,15 @@ sub parseopts {
                "<>" => \&NonOption,
        );
 
+       # DH_INTERNAL_OPTIONS is used to pass additional options from
+       # dh through an override target to a command.
+       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 $ret=getoptions(\@ARGV, $options);
        if (!$ret) {
                error("unknown option; aborting");
        }
index 6be25f9d8bb6f2deb4da5ee063fc9d0ba5f7e1de..871adf48dfac829810c655a09f393351894972ce 100644 (file)
@@ -31,15 +31,9 @@ sub init {
        # Check to see if an argument on the command line starts with a dash.
        # if so, we need to pass this off to the resource intensive 
        # Getopt::Long, which I'd prefer to avoid loading at all if possible.
-       my $parseopt=undef;
-       my $arg;
-       foreach $arg (@ARGV) {
-               if ($arg=~m/^-/) {
-                       $parseopt=1;
-                       last;
-               }       
-       }
-       if ($parseopt) {
+       if ((defined $ENV{DH_OPTIONS} && length $ENV{DH_OPTIONS}) ||
+           (defined $ENV{DH_INTERNAL_OPTIONS} && length $ENV{DH_INTERNAL_OPTIONS}) ||
+           grep /^-/, @ARGV) {
                eval "use Debian::Debhelper::Dh_Getopt";
                error($!) if $@;
                %dh=Debian::Debhelper::Dh_Getopt::parseopts();
@@ -114,14 +108,20 @@ sub init {
 my $write_log=1;
 sub END {
        if ($? == 0 && $write_log) {
-               my $cmd=basename($0);
-               foreach my $package (@{$dh{DOPACKAGES}}) {
-                       my $ext=pkgext($package);
-                       my $log="debian/${ext}debhelper.log";
-                       open(LOG, ">>", $log) || error("failed to write to ${log}: $!");
-                       print LOG $cmd."\n";
-                       close LOG;
-               }
+               write_log(basename($0), @{$dh{DOPACKAGES}});
+       }
+}      
+
+sub write_log {
+       my $cmd=shift;
+       my @packages=@_;
+
+       foreach my $package (@packages) {
+               my $ext=pkgext($package);
+               my $log="debian/${ext}debhelper.log";
+               open(LOG, ">>", $log) || error("failed to write to ${log}: $!");
+               print LOG $cmd."\n";
+               close LOG;
        }
 }
 
index 2f107939f7aaab00338a793e804baca7cce6f069..9950c219c7b4d0909ee9aff8d06b818948ae0b1f 100644 (file)
@@ -1,3 +1,15 @@
+debhelper (7.2.0) UNRELEASED; urgency=low
+
+  * dh: debian/rules override targets can change what is run
+    for a specific debhelper command in a sequence.
+  * dh: Redid all the examples to use override targets, since these
+    eliminate all annoying boilerplate and are much easier to understand
+    than the old method.
+  * Remove rules.simple example, there's no need to use explcit targets
+    with dh anymore.
+
+ -- Joey Hess <joeyh@debian.org>  Thu, 25 Dec 2008 16:26:36 -0500
+
 debhelper (7.0.17) unstable; urgency=low
 
   [ Per Olofsson ]
diff --git a/dh b/dh
index 98d9024135d52a7337b1fbd6f2b4c5f94f7a8203..d0165c9969394d4e2e65d9d9204eb1c00f009fd9 100755 (executable)
--- a/dh
+++ b/dh
@@ -11,7 +11,7 @@ use Debian::Debhelper::Dh_Lib;
 
 =head1 SYNOPSIS
 
-B<dh> sequence [B<--until> I<cmd>] [B<--before> I<cmd>] [B<--after> I<cmd>] [B<--remaining>] [B<--with> I<addon>] [S<I<debhelper options>>]
+B<dh> sequence [B<--with> I<addon>] [B<--until> I<cmd>] [B<--before> I<cmd>] [B<--after> I<cmd>] [B<--remaining>] [S<I<debhelper options>>]
 
 =head1 DESCRIPTION
 
@@ -34,10 +34,25 @@ that is in the specified sequence. It then continues with the next command
 in the sequence. The B<--until>, B<--before>, B<--after>, and B<--remaining>
 options can override this behavior.
 
+If debian/rules contains a target with a name like "override_I<dh_command>",
+then when it gets to that command in the sequence, dh will run that
+target from the rules file, rather than running the actual command. The
+override target can then run the command with additional options, or run
+entirely different commands instead. (Note that to use this feature,
+you should Build-Depend on debhelper 7.2 or above.)
+
 =head1 OPTIONS
 
 =over 4
 
+=item B<--with> I<addon>
+
+Add the debhelper commands specified by the given addon to appropriate places
+in the sequence of commands that is run. This option can be repeated more
+than once, and is used when there is a third-party package that provides
+debhelper commands. See "SEQUENCE ADDONS" below for documentation about what
+such packages should do to be supported by --with.
+
 =item B<--until> I<cmd>
 
 Run commands in the sequence until and including I<cmd>, then stop.
@@ -54,14 +69,6 @@ Run commands in the sequence that come after I<cmd>.
 
 Run all commands in the sequence that have yet to be run.
 
-=item B<--with> I<addon>
-
-Add the debhelper commands specified by the given addon to appropriate places
-in the sequence of commands that is run. This option can be repeated more
-than once, and is used when there is a third-party package that provides
-debhelper commands. See "SEQUENCE ADDONS" below for documentation about what
-such packages should do to be supported by --with.
-
 =back
 
 All other options passed to dh are passed on to each command it runs. This
@@ -137,83 +144,43 @@ commands work with no additional options.
        %:
                dh $@
 
-This is a simple rules file that is a good starting place for customisation.
-(It's also available in F</usr/share/doc/debhelper/examples/rules.simple>
-
+Often you'll want to pass an option to a specific debhelper command. The
+easy way to do with is by adding an override target for that command.
+       
        #!/usr/bin/make -f
+       %:
+               dh $@
 
-       build: build-stamp
-               dh build
-               touch build-stamp
-
-       clean:
-               dh clean
-
-       install: build install-stamp
-       install-stamp:
-               dh install
-               touch install-stamp
-
-       binary-arch: install
-               dh binary-arch
-
-       binary-indep: install
-               dh binary-indep
-
-       binary: binary-arch binary-indep
-
-Often you'll want to pass an option to ./configure. This uses dh to run all
-commands before L<dh_auto_configure(1)>, then runs that command by hand,
-and then finished up by running the rest of the sequence. You could also
-run ./configure by hand, instead of bothering with using dh_auto_configure.
-And if necessary, you can add commands to run automake, etc here too.
+       override_dh_strip:
+               dh_strip -Xfoo
+               
+       override_dh_installdocs:
+               dh_installdocs README TODO
 
-       build: build-stamp
-       build-stamp:
-               dh build --before configure
-               dh_auto_configure -- --kitchen-sink=yes
-               dh build --after configure
-               touch build-stamp
+Sometimes the automated dh_auto_configure and dh_auto_build can't guess
+what to do for a strange package. Here's how to avoid running either
+and instead run your own commands.
 
-Here's how to skip two automated steps in a row (configure and build), and
-instead run the commands by hand.
+       #!/usr/bin/make -f
+       %:
+               dh $@
 
-       build: build-stamp
-       build-stamp:
-               dh build --before configure
+       override_dh_auto_configure:
                ./mondoconfig
+
+       override_dh_auto_build:
                make universe-explode-in-delight
-               dh build --after build
-               touch build-stamp
 
-Another common case is wanting to run some code manually after a particular
-debhelper command is run.
+Another common case is wanting to do something manually before or
+after a particular debhelper command is run.
 
-       install: build install-stamp
-       install-stamp:
-               dh install --until dh_fixperms
-               # dh_fixperms has run, now override it for one program
-               chmod 4755 debian/foo/usr/bin/foo
-               # and continue
-               dh install --after dh_fixperms
-               touch install-stamp
-
-It's also fine to run debhelper commands early. Just make sure that at
-least dh_prep is run from the sequence first, and be sure to use the
-B<--remaining> option to ensure that commands that normally come before
-those in the sequence are still run.
-
-       install: build install-stamp
-       install-stamp:
-               dh install --until dh_prep
-               dh_installdocs README TODO
-               dh_installchangelogs Changes
-               dh install --remaining
-               touch install-stamp
+       #!/usr/bin/make -f
+       %:
+               dh $@
 
-        binary-arch: install
-                dh_strip -X foo
-                dh binary-arch --remaining
+       override_dh_fixperms:
+               dh_fixperms
+               chmod 4755 debian/foo/usr/bin/foo
 
 =cut
 
@@ -443,21 +410,33 @@ foreach my $i (0..$stoppoint) {
                # Command already done for all packages.
                next;
        }
-       elsif (! @exclude) {
-               # Run command for all packages.
-               run($sequence[$i], @options);
-       }
-       else {
-               # Run command for only a subset of packages.
-               run($sequence[$i], @options,
-                       map { "-N$_" } @exclude);
-       }
+
+       run($sequence[$i], \@packages, \@exclude, @options);
 }
 
 sub run {
        my $command=shift;
+       my @packages=@{shift()};
+       my @exclude=@{shift()};
        my @options=@_;
        
+       # Check for override targets in debian/rules and
+       # run them instead of running the command directly.
+       my $override_command;
+       if (rules_explicit_target("override_".$command)) {
+               $override_command=$command;
+               # This passes the options through to commands called
+               # inside the target.
+               $ENV{DH_INTERNAL_OPTIONS}=join(" ", @options);
+               $command="debian/rules";
+               @options="override_".$override_command;
+       }
+       else {
+               # If some packages are excluded, add flags
+               # to prevent them from being acted on.
+               push @options, map { "-N$_" } @exclude;
+       }
+
        # 3 space indent lines the command being run up under the 
        # sequence name after "dh ".
        print "   ".escape_shell($command, @options)."\n";
@@ -470,6 +449,16 @@ sub run {
                elsif ($ret) {
                        exit 1;
                }
+
+               if (defined $override_command) {
+                       delete $ENV{DH_INTERNAL_OPTIONS};
+                       # Need to handle logging for overriden commands here,
+                       # because the actual debhelper command may not have
+                       # been run by the rules file target.
+                       my %packages=map { $_ => 1 } @packages;
+                       map { delete $packages{$_} } @exclude;
+                       Debian::Debhelper::Dh_Lib::write_log($override_command, keys %packages);
+               }
        }
 }
 
@@ -498,6 +487,31 @@ sub writelog {
        close LOG;
 }
 
+{
+my %targets;
+my $rules_parsed;
+
+sub rules_explicit_target {
+       # Checks if a specified target exists as an explicit target
+       # in debian/rules. 
+       # Currently this is accomplished via a stupid makefile parser.
+       my $target=shift;
+       
+       if (! $rules_parsed) {  
+               open(IN, "<debian/rules") || warning("dh cannot read debian/rules: $!");
+               while (<IN>) {
+                       if (/^([a-zA-Z_]+):/) {
+                               $targets{$1}=1;
+                       }
+               }
+               close IN;
+       }
+
+       return exists $targets{$target};
+}
+
+}
+
 =head1 SEE ALSO
 
 L<debhelper(7)>
diff --git a/examples/rules.simple b/examples/rules.simple
deleted file mode 100755 (executable)
index ab49db9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/make -f
-
-build: build-stamp
-build-stamp:
-       dh build
-       touch build-stamp
-
-clean:
-       dh clean
-
-install: build install-stamp
-install-stamp:
-       dh install
-       touch install-stamp
-
-binary-arch: install
-       dh binary-arch
-
-binary-indep: install
-       dh binary-indep
-
-binary: binary-arch binary-indep