faster dh
With wheezy released, the floodgates are opened on a lot of debhelper
changes that have been piling up. Most of these should be pretty minor, but
I released one yesterday that will affect all users of dh
. Hopefully in a
good way.
I made dh
smarter about selecting which debhelper commands it runs.
It can tell when a package does not use the stuff done by a particular
command, and skips running the command entirely.
So the debian/rules binary
of a package using dh
will now often look like this:
dh binary
dh_testroot
dh_prep
dh_auto_install
dh_installdocs
dh_installchangelogs
dh_perl
dh_link
dh_compress
dh_fixperms
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
Which is pretty close to the optimal hand-crafted debian/rules
file (and just
about as fast, too). But with the benefit that if you later add, say, cron job
files, dh_installcron
will automatically start being run too.
Hopefully this will not result in any behavior changes, other than packages
building faster and with less noise. If there is a bug it'll probably
be something missing in the specification of when a command needs to be run.
Beyond speed, I hope that this will help to lower the bar to adding new
commands to debhelper, and to the default dh sequences. Before, every such
new command slowed things down and was annoying. Now more special-purpose
commands won't get in the way of packages that don't need them.
The way this works is that debhelper commands can include a "PROMISE"
directive. An example from dh_installexamples
# PROMISE: DH NOOP WITHOUT examples
Mostly this specifies the files in debian/
that are used by the command, and
whose presence triggers the command to run. There is also a syntax to specify
items that can be present in the package build directory to trigger the command
to run.
(Unfortunatly, dh_perl
can't use this. There's no good way to specify
when dh_perl
needs to run, short of doing nearly as much work as dh_perl
would do when run. Oh well.)
Note that third-party dh_
commands can include these directives too, if that
makes sense.
I'm happy how this turned out, but I could be happier about the implementation.
The PROMISE directives need to be maintained along with the code of the
command. If another config file is added, they obviously must be updated.
Other changes to a command can invalidate the PROMISE directive, and cause
unexpected bugs.
What would be ideal is to not repeat the inputs of the command in these
directives, but instead write the command such that its inputs can be
automatically extracted. I played around with some code like this:
$behavior = main_behavior("docs tmp(usr/share/doc/)", sub {
my $package=shift;
my $docs=shift;
my $docdir=shift;
install($docs, $docdir);
});
$behavior->($package);
But refactoring all debhelper commands to be written in this style
would be a big job. And I was not happy enough with the flexability
and expressiveness of this to continue with it.
I can however, dream about what this would look like if debhelper were written
in Haskell. Then I would have a Debhelper a
monad, within which each command
executes.
main = runDebhelperIO installDocs
installDocs :: Monad a => Debhelper a
installDocs = do
docs <- configFile "docs"
docdir <- tmpDir "usr/share/doc"
lift $ install docs docdir
To run the command, runDebhelperIO
would loop over all the packages
and run the action, in the Debhelper IO
monad.
But, this also allows making an examineDebhelper
that takes an action
like installDocs
, and runs it in a Debhelper Writer
monad. That would
accumulate a list of all the inputs used by the action, and return it,
without performing any side effecting IO actions.
It's been 15 years since I last changed the language debhelper was written
in. I did that for less gains than this, really. (The issue back then was
that shell getopt
sucked.) IIRC it was not very hard, and only took a few
days. Still, I don't really anticipate reimplementing debhelper in Haskell
any time soon.
For one thing, individual Haskell binaries are quite large, statically
linking all Haskell libraries they use, and so the installed size of
debhelper would go up quite a bit. I hope that forthcoming changes will
move things toward dynamically linked haskell libraries, and make it more
appealing for projects that involve a lot of small commands.
So, just a thought experiment for now..
Syndicated 2013-05-08 19:18:06 from see shy jo