You can use build properties in ShellCommands by using the
WithProperties
wrapper when setting the arguments of
the ShellCommand. This interpolates the named build properties
into the generated shell command. Most step parameters accept
WithProperties
. Please file bugs for any parameters which
do not.
from buildbot.steps.shell import ShellCommand from buildbot.process.properties import WithProperties f.addStep(ShellCommand( command=["tar", "czf", WithProperties("build-%s.tar.gz", "revision"), "source"]))
If this BuildStep were used in a tree obtained from Subversion, it would create a tarball with a name like build-1234.tar.gz.
The WithProperties
function does printf
-style string
interpolation, using strings obtained by calling
build.getProperty(propname)
. Note that for every %s
(or
%d
, etc), you must have exactly one additional argument to
indicate which build property you want to insert.
You can also use python dictionary-style string interpolation by using
the %(propname)s
syntax. In this form, the property name goes
in the parentheses, and WithProperties takes no additional
arguments:
f.addStep(ShellCommand( command=["tar", "czf", WithProperties("build-%(revision)s.tar.gz"), "source"]))
Don't forget the extra “s” after the closing parenthesis! This is the cause of many confusing errors.
The dictionary-style interpolation supports a number of more advanced syntaxes, too.
propname:-replacement
propname
exists, substitute its value; otherwise,
substitute replacement
. replacement
may be empty
(%(propname:-)s
)
propname:~replacement
propname:-replacement
, but only substitutes the value
of property propname
if it is something Python regards as "true".
Python considers None
, 0, empty lists, and the empty string to be
false, so such values will be replaced by replacement
.
propname:+replacement
propname
exists, substitute replacement
; otherwise,
substitute an empty string.
Although these are similar to shell substitutions, no other
substitutions are currently supported, and replacement
in the
above cannot contain more substitutions.
If you need to do more complex substitution, you can pass keyword
arguments to WithProperties
. The value of each keyword argument
should be a function that takes one argument (the existing properties)
and returns a string value that will be used to replace that key:
WithProperties('%(now)s', now=lambda _: time.clock())
def determine_foo(props): if props.has_key('bar'): return props['bar'] elif props.has_key('baz'): return props['baz'] return 'qux' WithProperties('%(foo)s', foo=determine_foo)
Note: like python, you can either do positional-argument interpolation
or keyword-argument interpolation, not both. Thus you cannot use
a string like WithProperties("foo-%(revision)s-%s", "branch")
.