Author: David Schneider <david.schnei...@picle.org> Branch: Changeset: r859:3eaa460b6947 Date: 2013-09-08 15:53 +0200 http://bitbucket.org/pypy/buildbot/changeset/3eaa460b6947/
Log: add a buildstep to extract and update the changeset-id from the revision property of a SourceStamp diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -1,10 +1,12 @@ from buildbot.steps.source.mercurial import Mercurial +from buildbot.process.buildstep import BuildStep from buildbot.process import factory from buildbot.steps import shell, transfer from buildbot.steps.trigger import Trigger from buildbot.process.properties import WithProperties from buildbot import locks from pypybuildbot.util import symlink_force +from buildbot.status.results import SKIPPED, SUCCESS import os # buildbot supports SlaveLocks, which can be used to limit the amout of builds @@ -168,6 +170,21 @@ builder.saveYourself() # _______________________________________________________________ +# XXX Currently the build properties got_revision and final_file_name contain +# the revision number and the changeset-id, CheckGotRevision takes care to set +# the corresponding build properties +# rev:changeset for got_revision +# rev-changeset for final_file_name +# +# The rev part of got_revision and filename is used everywhere to sort the +# builds, i.e. on the summary and download pages. +# +# The rev part is strictly local and needs to be removed from the SourceStamp, +# at least for decoupled builds, which is what ParseRevision does. +# +# XXX in general it would be nice to drop the revision-number using only the +# changeset-id for got_revision and final_file_name and sorting the builds +# chronologically class CheckGotRevision(ShellCmd): description = 'got_revision' command = ['hg', 'parents', '--template', 'got_revision:{rev}:{node}'] @@ -189,6 +206,34 @@ self.build.setProperty('final_file_name', final_file_name, 'got_revision') +class ParseRevision(BuildStep): + """Parse the revision property of the source stamp and extract the global + part of the revision + 123:3a34 -> 3a34""" + name = "parse_revision" + + def __init__(self, *args, **kwargs): + BuildStep.__init__(self, *args, **kwargs) + + @staticmethod + def hideStepIf(results, step): + return results==SKIPPED + + @staticmethod + def doStepIf(step): + revision = step.build.getSourceStamp().revision + return isinstance(revision, (unicode, str)) and ':' in revision + + def start(self): + stamp = self.build.getSourceStamp() + revision = stamp.revision + if isinstance(revision, (unicode, str)) and ':' in revision: + parts = revision.split(':') + self.build.setProperty('revision', parts[1], 'parse_revision') + stamp.revision = parts[1] + self.finished(SUCCESS) + + def update_hg(platform, factory, repourl, workdir, use_branch, force_branch=None): factory.addStep( @@ -212,6 +257,9 @@ # for debugging repourl = '/home/antocuni/pypy/default' # + factory.addStep(ParseRevision(hideStepIf=ParseRevision.hideStepIf, + doStepIf=ParseRevision.doStepIf)) + # update_hg(platform, factory, repourl, workdir, use_branch=True, force_branch=force_branch) # @@ -476,7 +524,7 @@ basename=name + extension, workdir='.', blocksize=100 * 1024)) - if trigger: # if provided trigger schedulers that are depend on this one + if trigger: # if provided trigger schedulers that depend on this one self.addStep(Trigger(schedulerNames=[trigger])) diff --git a/bot2/pypybuildbot/test/test_builds.py b/bot2/pypybuildbot/test/test_builds.py --- a/bot2/pypybuildbot/test/test_builds.py +++ b/bot2/pypybuildbot/test/test_builds.py @@ -4,37 +4,67 @@ class FakeProperties(object): - def __init__(self): - pass - + sources = {} + + def __init__(self, properties=None): + if properties is None: + self.properties = {'branch':None, 'got_revision': 123, + 'final_file_name': '123-ea5ca8'} + else: + self.properties = properties + def __getitem__(self, item): - if item == 'branch': - return None - if item == 'got_revision': - return 123 - if item == 'final_file_name': - return '123-ea5ca8' - + return self.properties.get(item) + + def __setitem__(self, name, value): + self.properties[name] = value + def render(self, x): return x +class FakeSourceStamp(object): + def __init__(self, properties=None): + self.properties = properties if properties is not None else {} + + def __getattr__(self, name): + return self.properties.get(name) + + def __setattribute__(self, name, value): + self.properties[name] = value + class FakeBuild(object): slaveEnvironment = None - def __init__(self): - self.properties = FakeProperties() - + def __init__(self, properties=None): + self.properties = FakeProperties(properties) + self.source_stamp = FakeSourceStamp(properties) + def getProperties(self): return self.properties + def setProperty(self, name, value, source): + self.properties[name] = value + self.properties.sources[name] = source + def getSlaveCommandVersion(self, *args): return 3 + def getSourceStamp(self, *args): + return self.source_stamp + class FakeStepStatus(object): def setText(self, *args): pass + def stepFinished(self, results): + self.results = results + + def setHidden(self, *args): + pass + class FakeDeferred(object): + def callback(*args): + pass def addCallback(self, *args): return FakeDeferred() def addErrback(self, *args): @@ -146,3 +176,34 @@ step.commandComplete(cmd) summary = builder.summary_by_branch_and_revision[('trunk', '123')] assert summary.to_tuple() == (2, 2, 4, 0) + + +class TestParseRevision(object): + + def setup_method(self, mth): + inst = builds.ParseRevision() + factory = inst._getStepFactory().factory + kw = inst._getStepFactory().kwargs + self.rebuilt = factory(**kw) + self.rebuilt.step_status = FakeStepStatus() + self.rebuilt.deferred = FakeDeferred() + + def test_has_revision(self): + self.rebuilt.build = FakeBuild({'revision':u'123:ea5ca8'}) + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] == 'ea5ca8' + + def test_no_revision(self): + self.rebuilt.build = FakeBuild() + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] is None + + def test_revision_no_local_part(self): + self.rebuilt.build = FakeBuild({'revision':u'ea5ca8'}) + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] == 'ea5ca8' + + def test_empty_revision(self): + self.rebuilt.build = FakeBuild({'revision':u''}) + self.rebuilt.start() + assert self.rebuilt.build.getProperties()['revision'] == '' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit