]> git.donarmstrong.com Git - debhelper.git/blobdiff - dh
Fix typo in French translation, about debian/package.README.Debian files.
[debhelper.git] / dh
diff --git a/dh b/dh
index 215833f85b05da992eb332818b32f7e5df1f778a..289e7fc253fc9b3e3f37a484c4127f18c53f97b1 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> [S<I<debhelper options>>]
+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>>]
 
 =head1 DESCRIPTION
 
@@ -24,12 +24,8 @@ they only work on binary independent packages, and commands in the
 binary-arch sequences are passed the "-a" option to ensure they only work
 on architecture dependent packages.
 
-Options passed to dh are passed on to each command it runs. This can be
-used to set an option like "-v" or "-X" or "-N", as well as for more
-specialised options.
-
 Each debhelper command will record when it's successfully run in
-debian/package.log.debhelper. (Which dh_clean deletes.) So dh can tell
+debian/package.debhelper.log. (Which dh_clean deletes.) So dh can tell
 which commands have already been run, for which packages, and skip running
 those commands again.
 
@@ -58,6 +54,20 @@ 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
+can be used to set an option like "-v" or "-X" or "-N", as well as for more
+specialised options.
+
 =head1 COMMAND SPECIFICATION
 
 I<cmd> can be a full name of a debhelper command, or a substring. It'll first
@@ -65,6 +75,28 @@ search for a command in the sequence exactly matching the name, to avoid any
 ambiguity. If there are multiple substring matches, the last one in the
 sequence will be used.
 
+=head1 SEQUENCE ADDONS
+
+When B<--with> I<addon> is used, dh loads the perl module
+Debian::Debhelper::Sequence::I<addon>. Two functions are provided to let
+the module add its commands to sequences:
+
+=over 4
+
+=item Debian::Debhelper::Dh_Lib::insert_before(existing_command, new_command)
+
+Insert I<new_command> in sequences before I<existing_command>.
+
+=item Debian::Debhelper::Dh_Lib::insert_after(existing_command, new_command)
+
+Insert I<new_command> in sequences after I<existing_command>.
+
+=item Debian::Debhelper::Dh_Lib::remove_command(existing_command)
+
+Remove I<existing_command> from the list of commands to run.
+
+=back
+
 =cut
 
 sub command_pos {
@@ -98,26 +130,29 @@ anything:
 
        dh binary-arch --no-act
 
-This is a very simple rules file, for packages where the default seqences of
+This is a very simple rules file, for packages where the default sequences of
 commands work with no additional options.
 
        #!/usr/bin/make -f
        %:
-               dh %@
+               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>
 
        #!/usr/bin/make -f
 
-       build:
+       build: build-stamp
                dh build
+               touch build-stamp
 
        clean:
                dh clean
 
-       install: build
+       install: build install-stamp
+       install-stamp:
                dh install
+               touch install-stamp
 
        binary-arch: install
                dh binary-arch
@@ -133,37 +168,51 @@ 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.
 
-       build:
+       build: build-stamp
+       build-stamp:
                dh build --before configure
-               dh_auto_configure --kitchen-sink=yes
+               dh_auto_configure -- --kitchen-sink=yes
                dh build --after configure
+               touch build-stamp
 
 Here's how to skip two automated in a row (configure and build), and
 instead run the commands by hand.
 
-       build:
+       build: build-stamp
+       build-stamp:
                dh build --before configure
                ./mondoconfig
                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.
 
-       binary-arch: install
-               dh binary-arch --until dh_fixperms
+       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 binary-arch --after dh_fixperms
-
-It's also fine to run debhelper commands before starting the dh sequence.
-Just be sure to use the B<--remaining> option to ensure that commands
-that normally come before those in the sequence are still run.
+               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
 
         binary-arch: install
                 dh_strip -X foo
-                dh_fixperms -X bar
                 dh binary-arch --remaining
 
 =cut
@@ -172,6 +221,7 @@ that normally come before those in the sequence are still run.
 my @ARGV_orig=@ARGV;
 
 init();
+inhibit_log();
 
 # Definitions of sequences.
 my %sequences;
@@ -188,7 +238,7 @@ $sequences{clean} = [qw{
 }];
 $sequences{install} = [@{$sequences{build}}, qw{
        dh_testroot
-       dh_clean
+       dh_prep
        dh_installdirs
        dh_auto_install
 
@@ -221,7 +271,6 @@ $sequences{install} = [@{$sequences{build}}, qw{
        dh_gconf
        dh_icons
        dh_perl
-       dh_pysupport
        dh_scrollkeeper
        dh_usrlocal
 
@@ -230,6 +279,7 @@ $sequences{install} = [@{$sequences{build}}, qw{
        dh_fixperms
 }];
 my @b=qw{
+       dh_installdeb
        dh_gencontrol
        dh_md5sums
        dh_builddeb
@@ -242,12 +292,52 @@ $sequences{binary} = [@{$sequences{install}}, qw{
 }, @b];
 $sequences{'binary-arch'} = [@{$sequences{binary}}];
 
-# Third-party commands can be listed in the sequences, but should be
-# listed here as well. They will not be run if not present.
-my %thirdparty=(
-       dh_pycompat => 1,
-       dh_pysupport => 1,
-);
+# --with python-support is enabled by default, at least for now
+unshift @{$dh{WITH}}, "python-support";
+
+# sequence addon interface
+sub _insert {
+       my $offset=shift;
+       my $existing=shift;
+       my $new=shift;
+       foreach my $sequence (keys %sequences) {
+               my @list=@{$sequences{$sequence}};
+               next unless grep $existing, @list;
+               my @new;
+               foreach my $command (@list) {
+                       if ($command eq $existing) {
+                               push @new, $new if $offset < 0;
+                               push @new, $command;
+                               push @new, $new if $offset > 0;
+                       }
+                       else {
+                               push @new, $command;
+                       }
+               }
+               $sequences{$sequence}=\@new;
+       }
+}
+sub insert_before {
+       _insert(-1, @_);
+}
+sub insert_after {
+       _insert(1, @_);
+}
+sub remove_command {
+       my $command=shift;
+       foreach my $sequence (keys %sequences) {
+               $sequences{$sequence}=[grep { $_ ne $command } @{$sequences{$sequence}}];
+       }
+       
+}
+foreach my $addon (@{$dh{WITH}}) {
+       my $mod="Debian::Debhelper::Sequence::$addon";
+       $mod=~s/-/_/g;
+       eval "use $mod";
+       if ($@) {
+               error("--with $addon not supported or failed to load module $mod");
+       }
+}
 
 # Get the sequence of commands to run.
 if (! @ARGV) {
@@ -260,23 +350,33 @@ if (! exists $sequences{$sequence}) {
 }
 my @sequence=@{$sequences{$sequence}};
 
+# The list of all packages that can be acted on.
+my @packages=@{$dh{DOPACKAGES}};
+
 # Get the options to pass to commands in the sequence.
 # Filter out options intended only for this program.
 my @options;
 if ($sequence eq 'binary-arch') {
        push @options, "-a";
+       # as an optimisation, remove from the list any packages
+       # that are not arch dependent
+       my %arch_packages = map { $_ => 1 } getpackages("arch");
+       @packages = grep { $arch_packages{$_} } @packages;
 }
 elsif ($sequence eq 'binary-indep') {
        push @options, "-i";
+       # ditto optimisation for arch indep
+       my %indep_packages = map { $_ => 1 } getpackages("indep");
+       @packages = grep { $indep_packages{$_} } @packages;
 }
 while (@ARGV_orig) {
        my $opt=shift @ARGV_orig;
        next if $opt eq $sequence;
-       if ($opt =~ /^--?(after|until|before)$/) {
+       if ($opt =~ /^--?(after|until|before|with)$/) {
                shift @ARGV_orig;
                next;
        }
-       elsif ($opt =~ /^--?(remaining|(after|until|before)=)/) {
+       elsif ($opt =~ /^--?(no-act|remaining|(after|until|before|with)=)/) {
                next;
        }
        push @options, $opt;
@@ -285,11 +385,18 @@ while (@ARGV_orig) {
 # Figure out at what point in the sequence to start for each package.
 my %logged;
 my %startpoint;
-foreach my $package (@{$dh{DOPACKAGES}}) {
+foreach my $package (@packages) {
+       my @log=loadlog($package);
        if ($dh{AFTER}) {
                # Run commands in the sequence that come after the
                # specified command.
                $startpoint{$package}=command_pos($dh{AFTER}, @sequence) + 1;
+               # Write a dummy log entry indicating that the specified
+               # command was, in fact, run. This handles the case where
+               # no commands remain to run after it, communicating to
+               # future dh instances that the specified command should not
+               # be run again.
+               writelog($package, $sequence[$startpoint{$package}-1]);
        }
        elsif ($dh{REMAINING}) {
                # Start at the beginning so all remaining commands will get
@@ -300,7 +407,6 @@ foreach my $package (@{$dh{DOPACKAGES}}) {
                # Find the last logged command that is in the sequence, and
                # continue with the next command after it. If no logged
                # command is in the sequence, we're starting at the beginning..                         
-               my @log=loadlog($package);
                $startpoint{$package}=0;
 COMMAND:       foreach my $command (reverse @log) {
                        foreach my $i (0..$#sequence) {
@@ -326,14 +432,14 @@ elsif ($dh{BEFORE}) {
 foreach my $i (0..$stoppoint) {
        # Figure out which packages need to run this command.
        my @exclude;
-       foreach my $package (@{$dh{DOPACKAGES}}) {
+       foreach my $package (@packages) {
                if ($startpoint{$package} > $i ||
                    $logged{$package}{$sequence[$i]}) {
                        push @exclude, $package;
                }
        }
        
-       if (@exclude eq @{$dh{DOPACKAGES}}) {
+       if (@exclude eq @packages) {
                # Command already done for all packages.
                next;
        }
@@ -352,22 +458,18 @@ sub run {
        my $command=shift;
        my @options=@_;
        
-       # dh_clean -k is a special case
-       if ($command eq 'dh_clean' && $sequence ne 'clean') {
-               unshift @options, "-k";
-       }
-
-       # If a third party command is not in /usr/bin, don't try to run it.
-       if ($thirdparty{$command} && ! -x "/usr/bin/$command") {
-               return;
-       }
-
-       # The 4 spaces is a kind of half indent.
-       print "    ".escape_shell($command, @options)."\n";
+       # 3 space indent lines the command being run up under the 
+       # sequence name after "dh ".
+       print "   ".escape_shell($command, @options)."\n";
 
        if (! $dh{NO_ACT}) {
                my $ret=system($command, @options);
-               exit($ret) if $ret != 0;
+               if ($ret >> 8 != 0) {
+                       exit $ret >> 8;
+               }
+               elsif ($ret) {
+                       exit 1;
+               }
        }
 }
 
@@ -376,7 +478,7 @@ sub loadlog {
        my $ext=pkgext($package);
        
        my @log;
-       open(LOG, "<", "debian/${ext}log.debhelper");
+       open(LOG, "<", "debian/${ext}debhelper.log") || return;
        while (<LOG>) {
                chomp;
                push @log, $_;
@@ -385,6 +487,16 @@ sub loadlog {
        close LOG;
        return @log;
 }
+               
+sub writelog {
+       my $package=shift;
+       my $cmd=shift;
+       my $ext=pkgext($package);
+       
+       open(LOG, ">>", "debian/${ext}debhelper.log") || error("failed to write to log");
+       print LOG $cmd."\n";
+       close LOG;
+}
 
 =head1 SEE ALSO