[Buildbot-commits] buildbot/buildbot/slave commands.py,1.44,1.45
Brian Warner
warner at users.sourceforge.net
Mon Apr 24 06:45:39 UTC 2006
Update of /cvsroot/buildbot/buildbot/buildbot/slave
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/buildbot/slave
Modified Files:
commands.py
Log Message:
Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506
Creator: Brian Warner <warner at lothar.com>
add 'build properties', update test_vc
2006-04-23 Brian Warner <warner at lothar.com>
* buildbot/test/test_vc.py (VCBase.checkGotRevision): test
'got_revision' build property for all VC systems that implement
accurate ones: SVN, Darcs, Arch, Bazaar, Mercurial.
* buildbot/slave/commands.py (SourceBase._handleGotRevision): try
to determine which revision we actually obtained
(CVS.parseGotRevision): implement this for CVS, which just means
to grab a timestamp. Not ideal, and it depends upon the buildslave
having a clock that is reasonably well syncronized with the server,
but it's better than nothing.
(SVN.parseGotRevision): implement it for SVN, which is accurate
(Darcs.parseGotRevision): same
(Arch.parseGotRevision): same
(Bazaar.parseGotRevision): same
(Mercurial.parseGotRevision): same
* buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate):
keep a record of all non-stdout/stderr/header/rc status updates,
for the benefit of RemoteCommands that send other useful things,
like got_revision
(Source.commandComplete): put any 'got_revision' status values
into a build property of the same name
* buildbot/process/step_twisted.py (Trial): update to deal with
new ShellCommand refactoring
* docs/buildbot.texinfo (Build Properties): document new feature
that allows BuildSteps to get/set Build-wide properties like which
revision was requested and/or checked out.
* buildbot/interfaces.py (IBuildStatus.getProperty): new method
* buildbot/status/builder.py (BuildStatus.getProperty): implement
it. Note that this bumps the persistenceVersion of the saved Build
object, so add the necessary upgrade-old-version logic to include
an empty properties dict.
* buildbot/process/base.py (Build.setProperty): implement it
(Build.getProperty): same
(Build.startBuild): change build startup to set 'branch',
'revision', and 'slavename' properties at the right time
* buildbot/process/step.py (BuildStep.__init__): change setup to
require 'build' argument in a better way
(LoggingBuildStep): split ShellCommand into two pieces, for better
subclassing elsewhere. LoggingBuildStep is a BuildStep which runs
a single RemoteCommand that sends stdout/stderr status text. It
also provides the usual commandComplete / createSummary /
evaluateCommand / getText methods to be overridden...
(ShellCommand): .. whereas ShellCommand is specifically for
running RemoteShellCommands. Other shell-like BuildSteps (like
Source) can inherit from LoggingBuildStep instead of ShellCommand
(WithProperties): marker class to do build-property interpolation
(Source): inherit from LoggingBuildStep instead of ShellCommand
(RemoteDummy): same
* buildbot/test/test_properties.py: test new functionality
2006-04-21 Brian Warner <warner at lothar.com>
* buildbot/test/test_vc.py: rename testBranch to
testCheckoutBranch to keep the tests in about the right
alphabetical order
Index: commands.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/slave/commands.py,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- commands.py 17 Apr 2006 19:22:34 -0000 1.44
+++ commands.py 24 Apr 2006 06:45:37 -0000 1.45
@@ -1,6 +1,6 @@
# -*- test-case-name: buildbot.test.test_slavecommand -*-
-import os, os.path, re, signal, shutil, types
+import os, os.path, re, signal, shutil, types, time
from twisted.internet.protocol import ProcessProtocol
from twisted.internet import reactor, defer
@@ -123,6 +123,14 @@
workdir, environ=None,
sendStdout=True, sendStderr=True, sendRC=True,
timeout=None, stdin=None, keepStdout=False):
+ """
+
+ @param keepStdout: if True, we keep a copy of all the stdout text
+ that we've seen. This copy is available in
+ self.stdout, which can be read after the command
+ has finished.
+ """
+
self.builder = builder
self.command = command
self.sendStdout = sendStdout
@@ -680,6 +688,7 @@
d = self.doVCFull()
d.addBoth(self.maybeDoVCRetry)
d.addCallback(self._abandonOnFailure)
+ d.addCallback(self._handleGotRevision)
d.addCallback(self.writeSourcedata)
return d
@@ -692,6 +701,28 @@
return False
return True
+ def _handleGotRevision(self, res):
+ d = defer.maybeDeferred(self.parseGotRevision)
+ d.addCallback(lambda got_revision:
+ self.sendStatus({'got_revision': got_revision}))
+ return d
+
+ def parseGotRevision(self):
+ """Override this in a subclass. It should return a string that
+ represents which revision was actually checked out, or a Deferred
+ that will fire with such a string. If, in a future build, you were to
+ pass this 'got_revision' string in as the 'revision' component of a
+ SourceStamp, you should wind up with the same source code as this
+ checkout just obtained.
+
+ It is probably most useful to scan self.command.stdout for a string
+ of some sort. Be sure to set keepStdout=True on the VC command that
+ you run, so that you'll have something available to look at.
+
+ If this information is unavailable, just return None."""
+
+ return None
+
def writeSourcedata(self, res):
open(self.sourcedatafile, "w").write(self.sourcedata)
return res
@@ -910,6 +941,13 @@
self.command = c
return c.start()
+ def parseGotRevision(self):
+ # CVS does not have any kind of revision stamp to speak of. We return
+ # the current timestamp as a best-effort guess, but this depends upon
+ # the local system having a clock that is
+ # reasonably-well-synchronized with the repository.
+ return time.strftime("%Y-%m-%d %H:%M:%S %z", time.gmtime())
+
registerSlaveCommand("cvs", CVS, cvs_ver)
class SVN(SourceBase):
@@ -939,7 +977,8 @@
d = os.path.join(self.builder.basedir, self.srcdir)
command = ['svn', 'update', '--revision', str(revision)]
c = ShellCommand(self.builder, command, d,
- sendRC=False, timeout=self.timeout)
+ sendRC=False, timeout=self.timeout,
+ keepStdout=True)
self.command = c
return c.start()
@@ -954,10 +993,22 @@
command = ['svn', 'checkout', '--revision', str(revision),
self.svnurl, self.srcdir]
c = ShellCommand(self.builder, command, d,
- sendRC=False, timeout=self.timeout)
+ sendRC=False, timeout=self.timeout,
+ keepStdout=True)
self.command = c
return c.start()
+ def parseGotRevision(self):
+ # svn checkout operations finish with 'Checked out revision 16657.'
+ # svn update operations finish the line 'At revision 16654.'
+ lines = self.command.stdout.rstrip().split("\n")
+ lastline = lines[-1]
+ r = re.search(r'revision (\d+)\.', lastline)
+ if r:
+ return int(r.group(1))
+ return None
+
+
registerSlaveCommand("svn", SVN, cvs_ver)
class Darcs(SourceBase):
@@ -1023,6 +1074,18 @@
os.unlink(n)
return res
+ def parseGotRevision(self):
+ # we use 'darcs context' to find out what we wound up with
+ command = ["darcs", "changes", "--context"]
+ c = ShellCommand(self.builder, command,
+ os.path.join(self.builder.basedir, self.srcdir),
+ sendStdout=False, sendStderr=False, sendRC=False,
+ keepStdout=True)
+ c.usePTY = False
+ d = c.start()
+ d.addCallback(lambda res: c.stdout)
+ return d
+
registerSlaveCommand("darcs", Darcs, cvs_ver)
class Git(SourceBase):
@@ -1175,6 +1238,27 @@
d.addCallback(self._abandonOnFailure)
return d
+ def parseGotRevision(self):
+ # using code from tryclient.TlaExtractor
+ # 'tla logs --full' gives us ARCHIVE/BRANCH--REVISION
+ # 'tla logs' gives us REVISION
+ command = ["tla", "logs", "--full", "--reverse"]
+ c = ShellCommand(self.builder, command,
+ os.path.join(self.builder.basedir, self.srcdir),
+ sendStdout=False, sendStderr=False, sendRC=False,
+ keepStdout=True)
+ c.usePTY = False
+ d = c.start()
+ def _parse(res):
+ tid = c.stdout.split("\n")[0].strip()
+ slash = tid.index("/")
+ dd = tid.rindex("--")
+ #branch = tid[slash+1:dd]
+ baserev = tid[dd+2:]
+ return baserev
+ d.addCallback(_parse)
+ return d
+
registerSlaveCommand("arch", Arch, cvs_ver)
class Bazaar(Arch):
@@ -1217,6 +1301,25 @@
d.addCallback(self._didGet)
return d
+ def parseGotRevision(self):
+ # using code from tryclient.BazExtractor
+ command = ["baz", "tree-id"]
+ c = ShellCommand(self.builder, command,
+ os.path.join(self.builder.basedir, self.srcdir),
+ sendStdout=False, sendStderr=False, sendRC=False,
+ keepStdout=True)
+ c.usePTY = False
+ d = c.start()
+ def _parse(res):
+ tid = c.stdout.strip()
+ slash = tid.index("/")
+ dd = tid.rindex("--")
+ #branch = tid[slash+1:dd]
+ baserev = tid[dd+2:]
+ return baserev
+ d.addCallback(_parse)
+ return d
+
registerSlaveCommand("bazaar", Bazaar, cvs_ver)
@@ -1281,6 +1384,20 @@
self.command = c
return c.start()
+ def parseGotRevision(self):
+ # we use 'hg identify' to find out what we wound up with
+ command = ["hg", "identify"]
+ c = ShellCommand(self.builder, command,
+ os.path.join(self.builder.basedir, self.srcdir),
+ sendStdout=False, sendStderr=False, sendRC=False,
+ keepStdout=True)
+ d = c.start()
+ def _parse(res):
+ m = re.search(r'^(\w+)', c.stdout)
+ return m.group(1)
+ d.addCallback(_parse)
+ return d
+
registerSlaveCommand("hg", Mercurial, cvs_ver)
More information about the Commits
mailing list