Announcing Vellum, the Python based make for books (or anything really). I used Scons in
the past but I really didn’t like how huge and complex it was. For something like building
a book in LaTeX using Idiopidae I needed just a very simple build thing, so I hacked one
up in about four hours (first version took 40 minutes). For 142 lines of
fairly simple Python it’s already damn functional.
Right now it’s a single source file and a sample YAML file named build.yml.
Here’s the sample build.yml I’m using for my resume:
options:
default: build
file: res3
targets:
pdf: |
dvipdf %(file)s.dvi
dvi: |
--> echo {"file": "something else"}
latex %(file)s.tex
--> echo {}
echo: |
<<< Building %(file)s
>>> print "opts: %s" % file
depends:
build: [pdf]
pdf: [dvi]
What you see here is more of a sample then something realistic for
building a single LaTeX document. It shows that options, targets, and
dependencies are in separate sections. It shows that each target is just
a set of string lines with different startings (more on that later).
You’ll see the syntax “dvi: |” which is just how you tell YAML that what
follows is a verbatim section. You can also see that each line is handed
the options (plus command line settings) as a dict format so you can use
it to change the commands dynamically. Notice also how ‘—>’ lines (which
run sub-targets) can take an optional dict that is merged into the main
options, letting you basically pass parameters. Finally, notice that
you don’t have to put a target in the “targets:” section if it’s in
the “depends:” so you can have fake targets that just run others.
If you want to run this, just install
PyYAML first
and then make a build.yml file. Run your build with vellum or use
vellum -h to see the available options.
It looks for a build.yml in the current directory or one you tell it,
builds the dependency graph, and then runs each target specified line by
line. Pretty simple, but there’s a few interesting things about Vellum:
- The targets, options, and dependencies are specified in separate sections, keeping
things flat the way Python people like it. This also makes it easy to parse and process.
- It uses YAML so it looks kind of like Makefile syntax. Some Pythonistas say they hate YAML
but the result of a YAML parse is just a dict, so I’ll include the option to just eval a .py
file that has the same data in it.
- It has very good error messages that tell you what line of what target caused a problem and
what the full problem was so you can fix it.
- It will print out all the targets and their dependencies so you can debug the graph if you need.
- It already has options for dry-run (-d), keep-going (-k), quiet (-q), and listing targets (-T).
- The part I think is the coolest feature is how it uses simple line prefixes to figure out what
to run. ‘>>>’ means exec that line as Python. ‘<<<’ means output that line as a message. ‘—>’ means jump to that target and run it (so you can do out of order calls with alternative options hashes too).
- It will stop when there’s an error unless you say -k (keep-going).
- Dry run tries to do as much non-destructive processing as possible so you can debug the vellum script. Combined with -q you can get a quick check of the script since it won’t print anything, but it will sys.exit(1) on error.
- You can list all the targets you want on the command line and it will run them in order with their dependencies.
The main thing that’s missing is:
- A mechanism to indicate a test that has to be true in order for processing in that target to continue. I may change ‘<<<’ from being “output” to being “exit on false”. It would take a python expression that has to be true for processing to continue. That would let you do the usual “only build .c if .o is older” and other tests.
- A simple recipe or extension system, and hopefully one that could snarf existing recipes from other build systems. It’d be great if Vellum could be used as a meta-build system for people. The goal on this is you’d be able to—> to targets that other people would write, passing in options which would make it run things for you.
I think with those two it’d be fairly complete, and even right now it works great for me.
I’ll be putting up a bzr repository sometime this weekend so if you’re interested in helping out or
just have ideas let me know.