David Eyk
David Eyk

Reputation: 12531

Performing string transformations on buildbot build properties?

Is there a good way to perform string transformations on a property or source stamp attribute before using it in an Interpolate? We use slashes in our branch names, and I need to transform the slashes into dashes so I can use them in filenames.

That is, say I have the branch "feature/fix-all-the-things", accessible as Interpolate("%(prop:branch)s") or Interpolate("%(src::branch)s"). I would like to be able to transform it to "feature-fix-all-the-things" for some interpolations. Obviously, it needs to remain in its original form for selecting the appropriate branch from source control.

Upvotes: 5

Views: 1380

Answers (2)

Ryan Nowakowski
Ryan Nowakowski

Reputation: 830

It looks like there's a newer, easier way to do this since buildbot v0.9.0 with Transform:

filename = util.Transform(
    lambda p: p.replace('/', '-'),
    util.Property('branch')
)

Upvotes: 2

David Eyk
David Eyk

Reputation: 12531

It turned out, I just needed to subclass Interpolate:

import re
from buildbot.process.properties import Interpolate


class InterpolateReplace(Interpolate):
    """Interpolate with regex replacements.

    This takes an additional argument, `patterns`, which is a list of
    dictionaries containing the keys "search" and "replace", corresponding to
    `pattern` and `repl` arguments to `re.sub()`.
    """
    def __init__(self, fmtstring, patterns, *args, **kwargs):
        Interpolate.__init__(self, fmtstring, *args, **kwargs)
        self._patterns = patterns

    def _sub(self, s):
        for pattern in self._patterns:
            search = pattern['search']
            replace = pattern['replace']
            s = re.sub(search, replace, s)
        return s

    def getRenderingFor(self, props):
        props = props.getProperties()
        if self.args:
            d = props.render(self.args)
            d.addCallback(lambda args:
                          self._sub(self.fmtstring % tuple(args)))
            return d
        else:
            d = props.render(self.interpolations)
            d.addCallback(lambda res:
                          self._sub(self.fmtstring % res))
            return d

Upvotes: 3

Related Questions