<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Properties — Buildbot 0.8.8 documentation</title> <link rel="stylesheet" href="../_static/agogo.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '0.8.8', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="shortcut icon" href="../_static/buildbot.ico"/> <link rel="top" title="Buildbot 0.8.8 documentation" href="../index.html" /> <link rel="up" title="Configuration" href="configuration.html" /> <link rel="next" title="Build Steps" href="cfg-buildsteps.html" /> <link rel="prev" title="Build Factories" href="cfg-buildfactories.html" /> </head> <body> <div class="header-wrapper"> <div class="header"> <p class="logo"><a href="../index.html"> <img class="logo" src="../_static/header-text-transparent.png" alt="Logo"/> </a></p> <div class="headertitle"><a href="../index.html">Buildbot 0.8.8 documentation</a></div> <div class="rel"> <a href="cfg-buildfactories.html" title="Build Factories" accesskey="P">previous</a> | <a href="cfg-buildsteps.html" title="Build Steps" accesskey="N">next</a> | <a href="../py-modindex.html" title="Python Module Index" >modules</a> | <a href="../genindex.html" title="General Index" accesskey="I">index</a> </div> </div> </div> <div class="content-wrapper"> <div class="content"> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="properties"> <span id="index-0"></span><span id="id1"></span><h1>Properties<a class="headerlink" href="#properties" title="Permalink to this headline">¶</a></h1> <p>Build properties are a generalized way to provide configuration information to build steps; see <a class="reference internal" href="concepts.html#build-properties"><em>Build Properties</em></a> for the conceptual overview of properties.</p> <p>Some build properties come from external sources and are set before the build begins; others are set during the build, and available for later steps. The sources for properties are:</p> <ul class="simple"> <li><a class="reference internal" href="cfg-global.html#cfg-properties" title="properties"><tt class="xref bb bb-cfg docutils literal"><span class="pre">global</span> <span class="pre">configuration</span></tt></a> -- These properties apply to all builds.</li> <li><a class="reference internal" href="cfg-schedulers.html#configuring-schedulers"><em>schedulers</em></a> -- A scheduler can specify properties that become available to all builds it starts.</li> <li><a class="reference internal" href="cfg-changesources.html#change-sources"><em>changes</em></a> -- A change can have properties attached to it, supplying extra information gathered by the change source. This is most commonly used with the <a class="reference internal" href="cmdline.html#cmdline-sendchange" title="sendchange"><tt class="xref bb bb-cmdline docutils literal"><span class="pre">sendchange</span></tt></a> command.</li> <li><a class="reference internal" href="cfg-statustargets.html#status-WebStatus" title="WebStatus"><tt class="xref bb bb-status docutils literal"><span class="pre">forced</span> <span class="pre">builds</span></tt></a> -- The "Force Build" form allows users to specify properties</li> <li><a class="reference internal" href="cfg-buildslaves.html#cfg-slaves" title="slaves"><tt class="xref bb bb-cfg docutils literal"><span class="pre">buildslaves</span></tt></a> -- A buildslave can pass properties on to the builds it performs.</li> <li><a class="reference internal" href="#common-build-properties"><em>builds</em></a> -- A build automatically sets a number of properties on itself.</li> <li><a class="reference internal" href="cfg-builders.html#cfg-builders" title="builders"><tt class="xref bb bb-cfg docutils literal"><span class="pre">builders</span></tt></a> -- A builder can set properties on all the builds it runs.</li> <li><a class="reference internal" href="cfg-buildsteps.html#build-steps"><em>steps</em></a> -- The steps of a build can set properties that are available to subsequent steps. In particular, source steps set the <cite>got_revision</cite> property.</li> </ul> <p>If the same property is supplied in multiple places, the final appearance takes precedence. For example, a property set in a builder configuration will override one supplied by a scheduler.</p> <p>Properties are stored internally in JSON format, so they are limited to basic types of data: numbers, strings, lists, and dictionaries.</p> <div class="section" id="common-build-properties"> <span id="index-1"></span><span id="id2"></span><h2>Common Build Properties<a class="headerlink" href="#common-build-properties" title="Permalink to this headline">¶</a></h2> <p>The following build properties are set when the build is started, and are available to all steps.</p> <dl class="docutils" id="index-2"> <dt><tt class="docutils literal"><span class="pre">got_revision</span></tt></dt> <dd><p class="first">This property is set when a <tt class="xref py py-class docutils literal"><span class="pre">Source</span></tt> step checks out the source tree, and provides the revision that was actually obtained from the VC system. In general this should be the same as <tt class="docutils literal"><span class="pre">revision</span></tt>, except for non-absolute sourcestamps, where <tt class="docutils literal"><span class="pre">got_revision</span></tt> indicates what revision was current when the checkout was performed. This can be used to rebuild the same source code later.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">For some VC systems (Darcs in particular), the revision is a large string containing newlines, and is not suitable for interpolation into a filename.</p> </div> <p class="last">For multi-codebase builds (where codebase is not the default <cite>''</cite>), this property is a dictionary, keyed by codebase.</p> </dd> </dl> <dl class="docutils" id="index-3"> <dt><tt class="docutils literal"><span class="pre">buildername</span></tt></dt> <dd>This is a string that indicates which <tt class="xref py py-class docutils literal"><span class="pre">Builder</span></tt> the build was a part of. The combination of buildername and buildnumber uniquely identify a build.</dd> </dl> <dl class="docutils" id="index-4"> <dt><tt class="docutils literal"><span class="pre">buildnumber</span></tt></dt> <dd>Each build gets a number, scoped to the <tt class="xref py py-class docutils literal"><span class="pre">Builder</span></tt> (so the first build performed on any given <tt class="xref py py-class docutils literal"><span class="pre">Builder</span></tt> will have a build number of 0). This integer property contains the build's number.</dd> </dl> <dl class="docutils" id="index-5"> <dt><tt class="docutils literal"><span class="pre">slavename</span></tt></dt> <dd>This is a string which identifies which buildslave the build is running on.</dd> </dl> <dl class="docutils" id="index-6"> <dt><tt class="docutils literal"><span class="pre">scheduler</span></tt></dt> <dd>If the build was started from a scheduler, then this property will contain the name of that scheduler.</dd> <dt><tt class="docutils literal"><span class="pre">workdir</span></tt></dt> <dd>The absolute path of the base working directory on the slave, of the current builder.</dd> </dl> <p id="index-7">For single codebase builds, where the codebase is <cite>''</cite>, the following <a class="reference internal" href="#source-stamp-attributes"><em>Source Stamp Attributes</em></a> are also available as properties: <tt class="docutils literal"><span class="pre">branch</span></tt>, <tt class="docutils literal"><span class="pre">revision</span></tt>, <tt class="docutils literal"><span class="pre">repository</span></tt>, and <tt class="docutils literal"><span class="pre">project</span></tt> .</p> </div> <div class="section" id="source-stamp-attributes"> <span id="id3"></span><h2>Source Stamp Attributes<a class="headerlink" href="#source-stamp-attributes" title="Permalink to this headline">¶</a></h2> <p id="index-8"><tt class="docutils literal"><span class="pre">branch</span></tt> <tt class="docutils literal"><span class="pre">revision</span></tt> <tt class="docutils literal"><span class="pre">repository</span></tt> <tt class="docutils literal"><span class="pre">project</span></tt> <tt class="docutils literal"><span class="pre">codebase</span></tt></p> <blockquote> <div>For details of these attributes see <a class="reference internal" href="concepts.html"><em>Concepts</em></a>.</div></blockquote> <p><tt class="docutils literal"><span class="pre">changes</span></tt></p> <blockquote> <div>This attribute is a list of dictionaries reperesnting the changes that make up this sourcestamp.</div></blockquote> <p><tt class="docutils literal"><span class="pre">has_patch</span></tt> <tt class="docutils literal"><span class="pre">patch_level</span></tt> <tt class="docutils literal"><span class="pre">patch_body</span></tt> <tt class="docutils literal"><span class="pre">patch_subdir</span></tt> <tt class="docutils literal"><span class="pre">patch_author</span></tt> <tt class="docutils literal"><span class="pre">patch_comment</span></tt></p> <blockquote> <div>These attributes are set if the source stamp was created by a <a class="reference internal" href="cfg-schedulers.html#try-schedulers"><em>try scheduler</em></a>.</div></blockquote> </div> <div class="section" id="using-properties-in-steps"> <h2>Using Properties in Steps<a class="headerlink" href="#using-properties-in-steps" title="Permalink to this headline">¶</a></h2> <p>For the most part, properties are used to alter the behavior of build steps during a build. This is done by annotating the step definition in <tt class="docutils literal"><span class="pre">master.cfg</span></tt> with placeholders. When the step is executed, these placeholders will be replaced using the current values of the build properties.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p>Properties are defined while a build is in progress; their values are not available when the configuration file is parsed. This can sometimes confuse newcomers to Buildbot! In particular, the following is a common error:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">Property</span><span class="p">(</span><span class="s">'release_train'</span><span class="p">)</span> <span class="o">==</span> <span class="s">'alpha'</span><span class="p">:</span> <span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> </pre></div> </div> <p class="last">This does not work because the value of the property is not available when the <tt class="docutils literal"><span class="pre">if</span></tt> statement is executed. However, Python will not detect this as an error - you will just never see the step added to the factory.</p> </div> <p>You can use build properties in most step parameters. Please file bugs for any parameters which do not accept properties.</p> <div class="section" id="property"> <span id="index-9"></span><span id="id4"></span><h3>Property<a class="headerlink" href="#property" title="Permalink to this headline">¶</a></h3> <p>The simplest form of annotation is to wrap the property name with <tt class="xref py py-class docutils literal"><span class="pre">Property</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">buildbot.steps.shell</span> <span class="kn">import</span> <span class="n">ShellCommand</span> <span class="kn">from</span> <span class="nn">buildbot.process.properties</span> <span class="kn">import</span> <span class="n">Property</span> <span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="n">ShellCommand</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="p">[</span> <span class="s">'echo'</span><span class="p">,</span> <span class="s">'buildername:'</span><span class="p">,</span> <span class="n">Property</span><span class="p">(</span><span class="s">'buildername'</span><span class="p">)</span> <span class="p">]))</span> </pre></div> </div> <p>You can specify a default value by passing a <tt class="docutils literal"><span class="pre">default</span></tt> keyword argument:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="n">ShellCommand</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="p">[</span> <span class="s">'echo'</span><span class="p">,</span> <span class="s">'warnings:'</span><span class="p">,</span> <span class="n">Property</span><span class="p">(</span><span class="s">'warnings'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'none'</span><span class="p">)</span> <span class="p">]))</span> </pre></div> </div> <p>The default value is used when the property doesn't exist, or when the value is something Python regards as <tt class="docutils literal"><span class="pre">False</span></tt>. The <tt class="docutils literal"><span class="pre">defaultWhenFalse</span></tt> argument can be set to <tt class="docutils literal"><span class="pre">False</span></tt> to force buildbot to use the default argument only if the parameter is not set:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="n">ShellCommand</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="p">[</span> <span class="s">'echo'</span><span class="p">,</span> <span class="s">'warnings:'</span><span class="p">,</span> <span class="n">Property</span><span class="p">(</span><span class="s">'warnings'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'none'</span><span class="p">,</span> <span class="n">defaultWhenFalse</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="p">]))</span> </pre></div> </div> <p>The default value can reference other properties, e.g.,</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">command</span><span class="o">=</span><span class="n">Property</span><span class="p">(</span><span class="s">'command'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">Property</span><span class="p">(</span><span class="s">'default-command'</span><span class="p">))</span> </pre></div> </div> </div> <div class="section" id="interpolate"> <span id="index-10"></span><span id="id5"></span><h3>Interpolate<a class="headerlink" href="#interpolate" title="Permalink to this headline">¶</a></h3> <p><tt class="xref py py-class docutils literal"><span class="pre">Property</span></tt> can only be used to replace an entire argument: in the example above, it replaces an argument to <tt class="docutils literal"><span class="pre">echo</span></tt>. Often, properties need to be interpolated into strings, instead. The tool for that job is <a class="reference internal" href="#interpolate"><em>Interpolate</em></a>.</p> <p>The more common pattern is to use Python dictionary-style string interpolation by using the <tt class="docutils literal"><span class="pre">%(prop:<propname>)s</span></tt> syntax. In this form, the property name goes in the parentheses, as above. A common mistake is to omit the trailing "s", leading to a rather obscure error from Python ("ValueError: unsupported format character").</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">buildbot.steps.shell</span> <span class="kn">import</span> <span class="n">ShellCommand</span> <span class="kn">from</span> <span class="nn">buildbot.process.properties</span> <span class="kn">import</span> <span class="n">Interpolate</span> <span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="n">ShellCommand</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="p">[</span> <span class="s">'make'</span><span class="p">,</span> <span class="n">Interpolate</span><span class="p">(</span><span class="s">'REVISION=%(prop:got_revision)s'</span><span class="p">),</span> <span class="s">'dist'</span> <span class="p">]))</span> </pre></div> </div> <p>This example will result in a <tt class="docutils literal"><span class="pre">make</span></tt> command with an argument like <tt class="docutils literal"><span class="pre">REVISION=12098</span></tt>.</p> <p id="interpolate-dictstyle">The syntax of dictionary-style interpolation is a selector, followed by a colon, followed by a selector specific key, optionally followed by a colon and a string indicating how to interpret the value produced by the key.</p> <p>The following selectors are supported.</p> <dl class="docutils"> <dt><tt class="docutils literal"><span class="pre">prop</span></tt></dt> <dd>The key is the name of a property.</dd> <dt><tt class="docutils literal"><span class="pre">src</span></tt></dt> <dd>The key is a codebase and source stamp attribute, separated by a colon.</dd> <dt><tt class="docutils literal"><span class="pre">kw</span></tt></dt> <dd>The key refers to a keyword argument passed to <tt class="docutils literal"><span class="pre">Interpolate</span></tt>.</dd> </dl> <p>The following ways of interpreting the value are available.</p> <dl class="docutils"> <dt><tt class="docutils literal"><span class="pre">-replacement</span></tt></dt> <dd>If the key exists, substitute its value; otherwise, substitute <tt class="docutils literal"><span class="pre">replacement</span></tt>. <tt class="docutils literal"><span class="pre">replacement</span></tt> may be empty (<tt class="docutils literal"><span class="pre">%(prop:propname:-)s</span></tt>). This is the default.</dd> <dt><tt class="docutils literal"><span class="pre">~replacement</span></tt></dt> <dd>Like <tt class="docutils literal"><span class="pre">-replacement</span></tt>, but only substitutes the value of the key if it is something Python regards as <tt class="docutils literal"><span class="pre">True</span></tt>. Python considers <tt class="docutils literal"><span class="pre">None</span></tt>, 0, empty lists, and the empty string to be false, so such values will be replaced by <tt class="docutils literal"><span class="pre">replacement</span></tt>.</dd> <dt><tt class="docutils literal"><span class="pre">+replacement</span></tt></dt> <dd>If the key exists, substitute <tt class="docutils literal"><span class="pre">replacement</span></tt>; otherwise, substitute an empty string.</dd> </dl> <p><tt class="docutils literal"><span class="pre">?|sub_if_exists|sub_if_missing</span></tt></p> <dl class="docutils"> <dt><tt class="docutils literal"><span class="pre">#?|sub_if_true|sub_if_false</span></tt></dt> <dd>Ternary substitution, depending on either the key being present (with <tt class="docutils literal"><span class="pre">?</span></tt>, similar to <tt class="docutils literal"><span class="pre">+</span></tt>) or being <tt class="docutils literal"><span class="pre">True</span></tt> (with <tt class="docutils literal"><span class="pre">#?</span></tt>, like <tt class="docutils literal"><span class="pre">~</span></tt>). Notice that there is a pipe immediately following the question mark <em>and</em> between the two substitution alternatives. The character that follows the question mark is used as the delimiter between the two alternatives. In the above examples, it is a pipe, but any character other than <tt class="docutils literal"><span class="pre">(</span></tt> can be used.</dd> </dl> <p>Although these are similar to shell substitutions, no other substitutions are currently supported.</p> <p>Example</p> <div class="highlight-python"><pre>from buildbot.steps.shell import ShellCommand from buildbot.process.properties import Interpolate f.addStep(ShellCommand(command=[ 'make', Interpolate('REVISION=%(prop:got_revision:-%(src::revision:-unknown)s)s') 'dist' ]))</pre> </div> <p>In addition, <tt class="docutils literal"><span class="pre">Interpolate</span></tt> supports using positional string interpolation. Here, <tt class="docutils literal"><span class="pre">%s</span></tt> is used as a placeholder, and the substitutions (which may themselves be placeholders), are given as subsequent arguments:</p> <div class="highlight-python"><pre>.. note:</pre> </div> <blockquote> <div>Like Python, you can use either positional interpolation <em>or</em> dictionary-style interpolation, not both. Thus you cannot use a string like <tt class="docutils literal"><span class="pre">Interpolate("foo-%(src::revision)s-%s",</span> <span class="pre">"branch")</span></tt>.</div></blockquote> </div> <div class="section" id="renderer"> <span id="index-11"></span><span id="id6"></span><h3>Renderer<a class="headerlink" href="#renderer" title="Permalink to this headline">¶</a></h3> <p>While Interpolate can handle many simple cases, and even some common conditionals, more complex cases are best handled with Python code. The <tt class="docutils literal"><span class="pre">renderer</span></tt> decorator creates a renderable object that will be replaced with the result of the function, called when the step it's passed to begins. The function receives an <tt class="xref py py-class docutils literal"><span class="pre">IProperties</span></tt> object, which it can use to examine the values of any and all properties. For example:</p> <div class="highlight-python"><pre> @properties.renderer def makeCommand(props): command = [ 'make' ] cpus = props.getProperty('CPUs') if cpus: command += [ '-j', str(cpus+1) ] else: command += [ '-j', '2' ] command += [ 'all' ] return command f.addStep(ShellCommand(command=makeCommand))</pre> </div> <p>You can think of <tt class="docutils literal"><span class="pre">renderer</span></tt> as saying "call this function when the step starts".</p> </div> <div class="section" id="withproperties"> <span id="index-12"></span><span id="id7"></span><h3>WithProperties<a class="headerlink" href="#withproperties" title="Permalink to this headline">¶</a></h3> <div class="admonition warning"> <p class="first admonition-title">Warning</p> <p class="last">This placeholder is deprecated. It is an older version of <a class="reference internal" href="#interpolate"><em>Interpolate</em></a>. It exists for compatibility with older configs.</p> </div> <p>The simplest use of this class is with positional string interpolation. Here, <tt class="docutils literal"><span class="pre">%s</span></tt> is used as a placeholder, and property names are given as subsequent arguments:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">buildbot.steps.shell</span> <span class="kn">import</span> <span class="n">ShellCommand</span> <span class="kn">from</span> <span class="nn">buildbot.process.properties</span> <span class="kn">import</span> <span class="n">WithProperties</span> <span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="n">ShellCommand</span><span class="p">(</span> <span class="n">command</span><span class="o">=</span><span class="p">[</span><span class="s">"tar"</span><span class="p">,</span> <span class="s">"czf"</span><span class="p">,</span> <span class="n">WithProperties</span><span class="p">(</span><span class="s">"build-</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">.tar.gz"</span><span class="p">,</span> <span class="s">"branch"</span><span class="p">,</span> <span class="s">"revision"</span><span class="p">),</span> <span class="s">"source"</span><span class="p">]))</span> </pre></div> </div> <p>If this <tt class="xref py py-class docutils literal"><span class="pre">BuildStep</span></tt> were used in a tree obtained from Git, it would create a tarball with a name like <tt class="file docutils literal"><span class="pre">build-master-a7d3a333db708e786edb34b6af646edd8d4d3ad9.tar.gz</span></tt>.</p> <p id="index-13">The more common pattern is to use Python dictionary-style string interpolation by using the <tt class="docutils literal"><span class="pre">%(propname)s</span></tt> syntax. In this form, the property name goes in the parentheses, as above. A common mistake is to omit the trailing "s", leading to a rather obscure error from Python ("ValueError: unsupported format character").</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">buildbot.steps.shell</span> <span class="kn">import</span> <span class="n">ShellCommand</span> <span class="kn">from</span> <span class="nn">buildbot.process.properties</span> <span class="kn">import</span> <span class="n">WithProperties</span> <span class="n">f</span><span class="o">.</span><span class="n">addStep</span><span class="p">(</span><span class="n">ShellCommand</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="p">[</span> <span class="s">'make'</span><span class="p">,</span> <span class="n">WithProperties</span><span class="p">(</span><span class="s">'REVISION=</span><span class="si">%(got_revision)s</span><span class="s">'</span><span class="p">),</span> <span class="s">'dist'</span> <span class="p">]))</span> </pre></div> </div> <p>This example will result in a <tt class="docutils literal"><span class="pre">make</span></tt> command with an argument like <tt class="docutils literal"><span class="pre">REVISION=12098</span></tt>.</p> <p id="withproperties-dictstyle">The dictionary-style interpolation supports a number of more advanced syntaxes in the parentheses.</p> <dl class="docutils"> <dt><tt class="docutils literal"><span class="pre">propname:-replacement</span></tt></dt> <dd>If <tt class="docutils literal"><span class="pre">propname</span></tt> exists, substitute its value; otherwise, substitute <tt class="docutils literal"><span class="pre">replacement</span></tt>. <tt class="docutils literal"><span class="pre">replacement</span></tt> may be empty (<tt class="docutils literal"><span class="pre">%(propname:-)s</span></tt>)</dd> <dt><tt class="docutils literal"><span class="pre">propname:~replacement</span></tt></dt> <dd>Like <tt class="docutils literal"><span class="pre">propname:-replacement</span></tt>, but only substitutes the value of property <tt class="docutils literal"><span class="pre">propname</span></tt> if it is something Python regards as <tt class="docutils literal"><span class="pre">True</span></tt>. Python considers <tt class="docutils literal"><span class="pre">None</span></tt>, 0, empty lists, and the empty string to be false, so such values will be replaced by <tt class="docutils literal"><span class="pre">replacement</span></tt>.</dd> <dt><tt class="docutils literal"><span class="pre">propname:+replacement</span></tt></dt> <dd>If <tt class="docutils literal"><span class="pre">propname</span></tt> exists, substitute <tt class="docutils literal"><span class="pre">replacement</span></tt>; otherwise, substitute an empty string.</dd> </dl> <p>Although these are similar to shell substitutions, no other substitutions are currently supported, and <tt class="docutils literal"><span class="pre">replacement</span></tt> in the above cannot contain more substitutions.</p> <p>Note: like Python, you can use either positional interpolation <em>or</em> dictionary-style interpolation, not both. Thus you cannot use a string like <tt class="docutils literal"><span class="pre">WithProperties("foo-%(revision)s-%s",</span> <span class="pre">"branch")</span></tt>.</p> </div> <div class="section" id="custom-renderables"> <h3>Custom Renderables<a class="headerlink" href="#custom-renderables" title="Permalink to this headline">¶</a></h3> <p>If the options described above are not sufficient, more complex substitutions can be achieved by writing custom renderables.</p> <p>Renderables are objects providing the <tt class="xref py py-class docutils literal"><span class="pre">IRenderable</span></tt> interface. That interface is simple - objects must provide a <cite>getRenderingFor</cite> method. The method should take one argument - an <tt class="xref py py-class docutils literal"><span class="pre">IProperties</span></tt> provider - and should return a string or a deferred firing with a string. Pass instances of the class anywhere other renderables are accepted. For example:</p> <div class="highlight-python"><pre>class DetermineFoo(object): implements(IRenderable) def getRenderingFor(self, props) if props.hasProperty('bar'): return props['bar'] elif props.hasProperty('baz'): return props['baz'] return 'qux' ShellCommand(command=['echo', DetermineFoo()])</pre> </div> <p>or, more practically,</p> <div class="highlight-python"><pre>class Now(object): implements(IRenderable) def getRenderingFor(self, props) return time.clock() ShellCommand(command=['make', Interpolate('TIME=%(kw:now)', now=Now())])</pre> </div> <p>This is equivalent to:</p> <div class="highlight-python"><div class="highlight"><pre><span class="nd">@renderer</span> <span class="k">def</span> <span class="nf">now</span><span class="p">(</span><span class="n">props</span><span class="p">):</span> <span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">clock</span><span class="p">()</span> <span class="n">ShellCommand</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="p">[</span><span class="s">'make'</span><span class="p">,</span> <span class="n">Interpolate</span><span class="p">(</span><span class="s">'TIME=%(kw:now)'</span><span class="p">,</span> <span class="n">now</span><span class="o">=</span><span class="n">now</span><span class="p">)])</span> </pre></div> </div> <p>Note that a custom renderable must be instantiated (and its constructor can take whatever arguments you'd like), whereas a function decorated with <tt class="xref py py-func docutils literal"><span class="pre">renderer</span></tt> can be used directly.</p> </div> </div> </div> </div> </div> </div> </div> <div class="sidebar"> <h3>Table Of Contents</h3> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Buildbot Tutorial</a></li> <li class="toctree-l1 current"><a class="reference internal" href="index.html">Buildbot Manual</a><ul class="current"> <li class="toctree-l2"><a class="reference internal" href="introduction.html">Introduction</a></li> <li class="toctree-l2"><a class="reference internal" href="installation.html">Installation</a></li> <li class="toctree-l2"><a class="reference internal" href="concepts.html">Concepts</a></li> <li class="toctree-l2 current"><a class="reference internal" href="configuration.html">Configuration</a><ul class="current"> <li class="toctree-l3"><a class="reference internal" href="cfg-intro.html">Configuring Buildbot</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-global.html">Global Configuration</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-changesources.html">Change Sources</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-schedulers.html">Schedulers</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-buildslaves.html">Buildslaves</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-builders.html">Builder Configuration</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-buildfactories.html">Build Factories</a></li> <li class="toctree-l3 current"><a class="current reference internal" href="">Properties</a><ul class="simple"> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="cfg-buildsteps.html">Build Steps</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-interlocks.html">Interlocks</a></li> <li class="toctree-l3"><a class="reference internal" href="cfg-statustargets.html">Status Targets</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="customization.html">Customization</a></li> <li class="toctree-l2"><a class="reference internal" href="cmdline.html">Command-line Tool</a></li> <li class="toctree-l2"><a class="reference internal" href="resources.html">Resources</a></li> <li class="toctree-l2"><a class="reference internal" href="optimization.html">Optimization</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="../developer/index.html">Buildbot Development</a></li> <li class="toctree-l1"><a class="reference internal" href="../relnotes/index.html">Release Notes for Buildbot v0.8.8</a></li> </ul> <h3 style="margin-top: 1.5em;">Search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <div class="clearer"></div> </div> </div> <div class="footer-wrapper"> <div class="footer"> <div class="left"> <a href="cfg-buildfactories.html" title="Build Factories" >previous</a> | <a href="cfg-buildsteps.html" title="Build Steps" >next</a> | <a href="../py-modindex.html" title="Python Module Index" >modules</a> | <a href="../genindex.html" title="General Index" >index</a> <br/> <a href="../_sources/manual/cfg-properties.txt" rel="nofollow">Show Source</a> </div> <div class="right"> <div class="footer"> © Copyright Buildbot Team Members. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. </div> </div> <div class="clearer"></div> </div> </div> </body> </html>