Thursday, 14 October 2010

Muddle FAQ: Efficient minimal rebuilds

"I've made a change deep within some package. How do I perform an efficient minimal rebuild?"

Coming to muddle from a mostly make-driven world, I really wanted to be able to stand at the top of a tree, type make and have it rebuild only what has changed. Unfortunately, life isn't as simple as that: it only works properly if package dependencies are correctly defined. This sometimes seems to be beyond individual package developers with their own software, let alone complicated inter-package dependencies, so clearly we need a different plan.

The missing link is provided by muddle labels. These are a bit like the build-stamps I'm familiar with from working with make: if a label is asserted, a certain task been completed for a particular component of your tree. For example, a checkout may be checked_out and a package may be configured, built and installed, and as you might imagine these terms imply a natural dependency ordering. Whenever you invoke muddle at the top level it figures out what needs to be done based on the state of those labels.

However, labels are not wired into the build system of any checkout: in other words, you don't get those make-like semantics. This would be difficult to implement in the general case; muddle would have to get down and extremely dirty with the build system of every checkout - and don't forget that they might be built with make, ant, jam or some build system you've never heard of.

Now, labels may be manually retracted and asserted if necessary. Therefore, one might at first think that it would be reasonable to simply retract the built label for the package in question. However, that is not a safe course of action: in the general case a single checkout might be built into multiple packages, so your change might have multiple effects without you realising it. The better plan is to retract the checked_out tag for the checkout you have changed, and then immediately reassert it. Retracting a label has the obvious semantics on labels depending on it, so this would cause all packages depending on that checkout to be rebuilt - what you actually wanted!

Figuring out the label

So, how do you determine the label to retract and reassert? You might have read the documentation and know that it looks like checkout:YOUR-CHECKOUT/checked_out - but what is the checkout actually called?

At the moment you have to invoke muddle query checkout_dirs and look down the list of directories for one which matches your working directory. (Side note: There is no requirement that a checkout label bears any resemblance to the directory path, though by convention they usually do; I imagine that somebody who named their checkout "vaeGhoo3ohRoh3Qu" would find likely themselves on the receiving end of violence - or, at least, extreme sarcasm - from their colleagues.)

So, in this case, having found out that you were working in the frobozz checkout, you would then run:

muddle retract checkout:frobozz/checked_out
muddle assert checkout:frobozz/checked_out

You can then rebuild and redeploy in the usual way.

More generally, if you want to examine the complete list of dependency labels, start with muddle depend user-short.

No comments:

Post a Comment