[Buildbot-commits] buildbot/buildbot/process properties.py, NONE, 1.1 base.py, 1.80, 1.81 buildstep.py, 1.11, 1.12

Brian Warner warner at users.sourceforge.net
Thu May 22 22:12:59 UTC 2008


Update of /cvsroot/buildbot/buildbot/buildbot/process
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv17197/buildbot/process

Modified Files:
	base.py buildstep.py 
Added Files:
	properties.py 
Log Message:
[project @ #124:properties-class.patch]
Add and use a Properties class, refactor the way properties are rendered,
and update unit tests accordingly.

Original author: dustin at v.igoro.us
Date: 2008-04-12 20:58:59+00:00

Index: base.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/process/base.py,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -d -r1.80 -r1.81
--- base.py	22 May 2008 22:12:34 -0000	1.80
+++ base.py	22 May 2008 22:12:57 -0000	1.81
@@ -207,15 +207,18 @@
     def getSourceStamp(self):
         return self.source
 
-    def setProperty(self, propname, value):
+    def setProperty(self, propname, value, source):
         """Set a property on this build. This may only be called after the
         build has started, so that it has a BuildStatus object where the
         properties can live."""
-        self.build_status.setProperty(propname, value)
+        self.build_status.setProperty(propname, value, source)
 
     def getCustomProperties(self):
         return self.custom_properties
 
+    def getProperties(self):
+        return self.build_status.getProperties()
+
     def getProperty(self, propname):
         return self.build_status.properties[propname]
 
@@ -277,22 +280,22 @@
 
     def setupStatus(self, build_status):
         self.build_status = build_status
-        self.setProperty("buildername", self.builder.name)
-        self.setProperty("buildnumber", self.build_status.number)
-        self.setProperty("branch", self.source.branch)
-        self.setProperty("revision", self.source.revision)
+        self.setProperty("buildername", self.builder.name, "build")
+        self.setProperty("buildnumber", self.build_status.number, "build")
+        self.setProperty("branch", self.source.branch, "build")
+        self.setProperty("revision", self.source.revision, "build")
         if self.scheduler is None:
-            self.setProperty("scheduler", "none")
+            self.setProperty("scheduler", "none", "build")
         else:
-            self.setProperty("scheduler", self.scheduler.name)
+            self.setProperty("scheduler", self.scheduler.name, "build")
         for key, userProp in self.custom_properties.items():
-            self.setProperty(key, userProp)
+            self.setProperty(key, userProp, "custom_props")
 
     def setupSlaveBuilder(self, slavebuilder):
         self.slavebuilder = slavebuilder
         self.slavename = slavebuilder.slave.slavename
         self.build_status.setSlavename(self.slavename)
-        self.setProperty("slavename", self.slavename)
+        self.setProperty("slavename", self.slavename, "build")
 
     def startBuild(self, build_status, expectations, slavebuilder):
         """This method sets up the build, then starts it by invoking the

Index: buildstep.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/process/buildstep.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- buildstep.py	23 Mar 2008 00:36:56 -0000	1.11
+++ buildstep.py	22 May 2008 22:12:57 -0000	1.12
@@ -632,8 +632,8 @@
     def getProperty(self, propname):
         return self.build.getProperty(propname)
 
-    def setProperty(self, propname, value):
-        self.build.setProperty(propname, value)
+    def setProperty(self, propname, value, source):
+        self.build.setProperty(propname, value, source)
 
     def startStep(self, remote):
         """Begin the step. This returns a Deferred that will fire when the
@@ -1092,46 +1092,5 @@
         self.step_status.setText(self.getText(cmd, results))
         self.step_status.setText2(self.maybeGetText2(cmd, results))
 
-class _BuildPropertyMapping:
-    def __init__(self, build):
-        self.build = build
-    def __getitem__(self, name):
-        p = self.build.getProperty(name)
-        if p is None:
-            p = ""
-        return p
-
-class WithProperties(util.ComparableMixin):
-    """This is a marker class, used in ShellCommand's command= argument to
-    indicate that we want to interpolate a build property.
-    """
-
-    compare_attrs = ('fmtstring', 'args')
-
-    def __init__(self, fmtstring, *args):
-        self.fmtstring = fmtstring
-        self.args = args
-
-    def render(self, build):
-        pmap = _BuildPropertyMapping(build)
-        if self.args:
-            strings = []
-            for name in self.args:
-                strings.append(pmap[name])
-            s = self.fmtstring % tuple(strings)
-        else:
-            s = self.fmtstring % pmap
-        return s
-
-def render_properties(s, build):
-    """Return a string based on s and build that is suitable for use
-    in a running BuildStep.  If s is a string, return s.  If s is a
-    WithProperties object, return the result of s.render(build).
-    Otherwise, return str(s).
-    """
-    if isinstance(s, (str, unicode)):
-        return s
-    elif isinstance(s, WithProperties):
-        return s.render(build)
-    else:
-        return str(s)
+# (WithProeprties used to be available in this module)
+from buildbot.process.properties import WithProperties

--- NEW FILE: properties.py ---
from zope.interface import implements
from buildbot import util
from twisted.python import log
from twisted.python.failure import Failure

class Properties:
    """
    I represent a set of properties that can be interpolated into various
    strings in buildsteps.

    @ivar properties: dictionary mapping property values to tuples 
        (value, source), where source is a string identifing the source
        of the property.

    Objects of this class can be read like a dictionary -- in this case,
    only the property value is returned.

    As a special case, a property value of None is returned as an empty 
    string when used as a mapping.
    """
    def __init__(self):
        self.properties = {}

    def __getitem__(self, name):
        """Just get the value for this property, special-casing None -> ''"""
        rv = self.properties[name][0]
        if rv is None: rv = ''
        return rv

    def has_key(self, name):
        return self.properties.has_key(name)

    def getProperty(self, name, default=(None,None)):
        """Get the (value, source) tuple for the given property"""
        return self.properties.get(name, default)

    def setProperty(self, name, value, source):
        self.properties[name] = (value, source)

    def update(self, dict, source):
        """Update this object from a dictionary, with an explicit source specified."""
        for k, v in dict.items():
            self.properties[k] = (v, source)

    def updateFromProperties(self, other):
        """Update this object based on another object; the other object's """
        self.properties.update(other.properties)

    def render(self, value):
        """
        Return a variant of value that has any WithProperties objects
        substituted.  This recurses into Python's compound data types.
        """
        if isinstance(value, (str, unicode)):
            return value
        elif isinstance(value, WithProperties):
            return value.render(self)
        elif isinstance(value, list):
            return [ self.render(e) for e in value ]
        elif isinstance(value, tuple):
            return tuple([ self.render(e) for e in value ])
        elif isinstance(value, dict):
            return dict([ (self.render(k), self.render(v)) for k,v in value.iteritems() ])
        else:
            return value

class WithProperties(util.ComparableMixin):
    """This is a marker class, used in ShellCommand's command= argument to
    indicate that we want to interpolate a build property.
    """

    compare_attrs = ('fmtstring', 'args')

    def __init__(self, fmtstring, *args):
        self.fmtstring = fmtstring
        self.args = args

    def render(self, properties):
        if self.args:
            strings = []
            for name in self.args:
                strings.append(properties[name])
            s = self.fmtstring % tuple(strings)
        else:
            s = self.fmtstring % properties
        return s





More information about the Commits mailing list