Right now, there's no way to do this. Someone asked me about this the
other day, and I didn't quite grasp the use case... your description
here makes sense to me.
I think such a thing is possible. There's a little bit of trickery
involved and some thought needs to be put in as far as what, exactly,
propagates to the sub-pavements.
There are some module globals that need to be considered. Primarily:
1. options
2. tasks
I'm guessing that we'd want these to propagate down to the sub-
pavement, but be overridden by any values that are in those sub-
pavements. (People with more experience with Make or Rake here can
chime in... I'm sure this stuff has been thought about) After the sub-
pavement has been run, the values should be reset.
That means making a deep copy of options, and a shallow copy of tasks,
temporarily moving aside the paver.defaults (which is where the
pavement runs), reinitializing paver.defaults, running the sub-
pavement, and then restoring everything. It is likely possible to
eliminate paver.defaults and just exec into a dictionary that we keep
around.
It's not hard, but the devil's in the details.
Kevin
--
Kevin Dangoor
Product Manager
SitePen, Inc.
Web development experts:
development, support, training
> - find "pavement.py" files in subdirectories
> - invoke a sub-paver with the same Python interpreter and sys.path,
> adjusting for relative paths (if present)... critical for loading
> "common task" code
> - call the same task in child as in parent
> - pass build/install paths to the sub-paver, adjusting for relative
> paths
Hmm, I wonder if it's a hard requirement that the sub-paver has the
same Python interpreter. Things become a lot less complicated if
that's not the case, because of how imports work in Python and things
like that. Paver could grow a command line option that says "read in
an options pickle on stdin" to pass state from the parent paver to the
child paver.
Is a goal here that the sub-pavements are runnable on their own? Make
(or bmake) has something like this:
FOO?=bar
which only sets FOO if it's not already set.
If the intention is that the sub-pavements can be run standalone but
can also be invoked as part of a larger build, then you'd want the
inherited settings to actually take precedence over the local settings
in some cases, right?
By the way, it'll be good to nail down exactly what we want here, but
I have too many things on my plate to personally work on this right
now. I can certainly provide guidance to someone who does want to work
on it.
I am hoping to do a new release sometime soon with some deployment
goodies.
Kevin
>
> I've taken a stab at implementing a subtask runner in a non-recursive
> manner. Since my current projects are all "setup.py" based, I simply
> scan for all such files, then iterate over those projects, calling
> "python setup.py <task>" in each.
Obviously, we'd want to scan for both pavement.py and setup.py :)
> Some bits of horribleness in my current code:
> - I'm using sh("find") to search for the sub-setup.py files, so I can
> use the "-maxdepth" argument. Obviously, not portable!
you want to use the goodies in the path module. They're not hard, they
are portable and it doesn't need to fire up a shell... you just get
the results directly in path objects.
> - I'm using sh("cd <subdir>; python setup.py <target>") to run the
> subtask. This will use whatever "python" is on the PATH, not
> necessarily the one I started with.
sys.executable is what you want. It will tell you which Python is in
use.
> - My "dependency_rank()" function is a fairly crazy way to sort the
> list of subprojects in dependency order. It works and is fast, but I
> doubt anyone could maintain it.
I'm pretty sure there's gotta be another way to do this :)
We likely want to end up with a function that can be called that will
track down sub-pavements and setups, run them with some standard set
of parameters (and pass in options automatically) and have some
customizable ordering.
Once we have a function that does that, we might be able to figure out
some nice, declarative options that can be used to create a task for it.
Kevin
>
> Quick question: do the goodies in the path module allow provide any
> control for the depth of traversal?
If it doesn't, there's no reason we can't add it. Our path.py is
already a fork from the original as it is (adding dry-run support), so
there's no reason why it can't just do everything we want.
Kevin