From warner at users.sourceforge.net Wed Apr 5 18:10:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:10:39 +0000 Subject: [Buildbot-commits] buildbot README,1.28,1.29 ChangeLog,1.582,1.583 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5420 Modified Files: README ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-477 Creator: Brian Warner add some windows fixes from Niklaus Giger * buildbot/test/__init__.py: set $LANG to 'C', to insure that spawned commands emit parseable results in english and not some other language. Patch from Niklaus Giger. * README (INSTALLATION): discourage users from running unit tests on a "network drive", patch from Niklaus Giger. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.582 retrieving revision 1.583 diff -u -d -r1.582 -r1.583 --- ChangeLog 22 Mar 2006 20:53:31 -0000 1.582 +++ ChangeLog 5 Apr 2006 18:10:34 -0000 1.583 @@ -1,3 +1,12 @@ +2006-04-03 Brian Warner + + * buildbot/test/__init__.py: set $LANG to 'C', to insure that + spawned commands emit parseable results in english and not some + other language. Patch from Niklaus Giger. + + * README (INSTALLATION): discourage users from running unit tests on + a "network drive", patch from Niklaus Giger. + 2006-03-22 Brian Warner * contrib/svn_buildbot.py: rearrange, add an easy-to-change Index: README =================================================================== RCS file: /cvsroot/buildbot/buildbot/README,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- README 25 Oct 2005 02:49:53 -0000 1.28 +++ README 5 Apr 2006 18:10:34 -0000 1.29 @@ -97,6 +97,9 @@ should stop and investigate the cause before continuing the installation process, as it will probably be easier to track down the bug early. +Neither CVS nor SVN support file based repositories on network filesystem +(or network drives in Windows parlance). Therefore it is recommended to run +all unit tests on local hard disks. INSTALLING THE LIBRARIES: From warner at users.sourceforge.net Wed Apr 5 18:10:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:10:39 +0000 Subject: [Buildbot-commits] buildbot/buildbot/test __init__.py,1.1,1.2 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5420/buildbot/test Modified Files: __init__.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-477 Creator: Brian Warner add some windows fixes from Niklaus Giger * buildbot/test/__init__.py: set $LANG to 'C', to insure that spawned commands emit parseable results in english and not some other language. Patch from Niklaus Giger. * README (INSTALLATION): discourage users from running unit tests on a "network drive", patch from Niklaus Giger. Index: __init__.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/test/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- __init__.py 8 Jan 2004 20:05:24 -0000 1.1 +++ __init__.py 5 Apr 2006 18:10:36 -0000 1.2 @@ -0,0 +1,4 @@ +import os + +# We do not want to be bother with output in exotic languages! +os.environ['LANG']='C' From warner at users.sourceforge.net Wed Apr 5 18:25:38 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:25:38 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.583,1.584 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16615 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-479 Creator: Brian Warner improve test_vc.py to work better with windows, from Niklaus Giger * buildbot/test/test_vc.py: modified find-the-VC-command logic to work under windows too. Adapted from a patch by Niklaus Giger. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.583 retrieving revision 1.584 diff -u -d -r1.583 -r1.584 --- ChangeLog 5 Apr 2006 18:10:34 -0000 1.583 +++ ChangeLog 5 Apr 2006 18:25:36 -0000 1.584 @@ -1,5 +1,8 @@ 2006-04-03 Brian Warner + * buildbot/test/test_vc.py: modified find-the-VC-command logic to + work under windows too. Adapted from a patch by Niklaus Giger. + * buildbot/test/__init__.py: set $LANG to 'C', to insure that spawned commands emit parseable results in english and not some other language. Patch from Niklaus Giger. From warner at users.sourceforge.net Wed Apr 5 18:25:38 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:25:38 +0000 Subject: [Buildbot-commits] buildbot/buildbot/test test_vc.py,1.44,1.45 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16615/buildbot/test Modified Files: test_vc.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-479 Creator: Brian Warner improve test_vc.py to work better with windows, from Niklaus Giger * buildbot/test/test_vc.py: modified find-the-VC-command logic to work under windows too. Adapted from a patch by Niklaus Giger. Index: test_vc.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_vc.py,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- test_vc.py 13 Mar 2006 05:50:24 -0000 1.44 +++ test_vc.py 5 Apr 2006 18:25:36 -0000 1.45 @@ -7,6 +7,7 @@ from twisted.trial import unittest from twisted.internet import defer, reactor, utils +from twisted.python.procutils import which #defer.Deferred.debug = True from twisted.python import log @@ -14,6 +15,7 @@ from buildbot import master, interfaces from buildbot.slave import bot +from buildbot.slave.commands import rmdirRecursive from buildbot.status.builder import SUCCESS, FAILURE from buildbot.process import step, base from buildbot.changes import changes @@ -239,12 +241,12 @@ def _setUp1(self, res): if os.path.exists("basedir"): - shutil.rmtree("basedir") + rmdirRecursive("basedir") os.mkdir("basedir") self.master = master.BuildMaster("basedir") self.slavebase = os.path.abspath("slavebase") if os.path.exists(self.slavebase): - shutil.rmtree(self.slavebase) + rmdirRecursive(self.slavebase) os.mkdir("slavebase") # NOTE: self.createdRepository survives from one test method to the # next, and we use this fact to avoid repeating the (expensive) @@ -336,6 +338,11 @@ d = self.runCommand(basedir, command, failureIsOk=failureIsOk) return waitForDeferred(d) + def dovc(self, basedir, command, failureIsOk=False): + """Like do(), but the VC binary will be prepended to COMMAND.""" + command = self.vcexe + " " + command + return self.do(basedir, command, failureIsOk) + def populate(self, basedir): os.makedirs(basedir) os.makedirs(os.path.join(basedir, "subdir")) @@ -387,7 +394,7 @@ c = open(os.path.join(d, f), "r").read() self.failUnlessIn(contents, c) - def do_vc(self, testRetry=True): + def do_vctest(self, testRetry=True): vctype = self.vctype args = self.vcargs m = self.master @@ -406,30 +413,30 @@ d = self.connectSlave() d.addCallback(lambda res: log.msg("testing clobber")) - d.addCallback(self._do_vc_clobber) + d.addCallback(self._do_vctest_clobber) d.addCallback(lambda res: log.msg("doing update")) d.addCallback(lambda res: self.loadConfig(config % 'update')) d.addCallback(lambda res: log.msg("testing update")) - d.addCallback(self._do_vc_update) + d.addCallback(self._do_vctest_update) if testRetry: d.addCallback(lambda res: log.msg("testing update retry")) - d.addCallback(self._do_vc_update_retry) + d.addCallback(self._do_vctest_update_retry) d.addCallback(lambda res: log.msg("doing copy")) d.addCallback(lambda res: self.loadConfig(config % 'copy')) d.addCallback(lambda res: log.msg("testing copy")) - d.addCallback(self._do_vc_copy) + d.addCallback(self._do_vctest_copy) if self.metadir: d.addCallback(lambda res: log.msg("doing export")) d.addCallback(lambda res: self.loadConfig(config % 'export')) d.addCallback(lambda res: log.msg("testing export")) - d.addCallback(self._do_vc_export) + d.addCallback(self._do_vctest_export) return d - def _do_vc_clobber(self, res): + def _do_vctest_clobber(self, res): d = self.doBuild() # initial checkout - d.addCallback(self._do_vc_clobber_1) + d.addCallback(self._do_vctest_clobber_1) return d - def _do_vc_clobber_1(self, res): + def _do_vctest_clobber_1(self, res): self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldExist(self.workdir, "subdir", "subdir.c") @@ -439,18 +446,18 @@ self.touch(self.workdir, "newfile") self.shouldExist(self.workdir, "newfile") d = self.doBuild() # rebuild clobbers workdir - d.addCallback(self._do_vc_clobber_2) + d.addCallback(self._do_vctest_clobber_2) return d - def _do_vc_clobber_2(self, res): + def _do_vctest_clobber_2(self, res): self.shouldNotExist(self.workdir, "newfile") - def _do_vc_update(self, res): - log.msg("_do_vc_update") + def _do_vctest_update(self, res): + log.msg("_do_vctest_update") d = self.doBuild() # rebuild with update - d.addCallback(self._do_vc_update_1) + d.addCallback(self._do_vctest_update_1) return d - def _do_vc_update_1(self, res): - log.msg("_do_vc_update_1") + def _do_vctest_update_1(self, res): + log.msg("_do_vctest_update_1") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", @@ -460,20 +467,20 @@ self.touch(self.workdir, "newfile") d = self.doBuild() # update rebuild leaves new files - d.addCallback(self._do_vc_update_2) + d.addCallback(self._do_vctest_update_2) return d - def _do_vc_update_2(self, res): - log.msg("_do_vc_update_2") + def _do_vctest_update_2(self, res): + log.msg("_do_vctest_update_2") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.touch(self.workdir, "newfile") # now make a change to the repository and make sure we pick it up d = self.vc_revise() d.addCallback(lambda res: self.doBuild()) - d.addCallback(self._do_vc_update_3) + d.addCallback(self._do_vctest_update_3) return d - def _do_vc_update_3(self, res): - log.msg("_do_vc_update_3") + def _do_vctest_update_3(self, res): + log.msg("_do_vctest_update_3") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", @@ -481,27 +488,27 @@ self.shouldExist(self.workdir, "newfile") # now "update" to an older revision d = self.doBuild(ss=SourceStamp(revision=self.trunk[-2])) - d.addCallback(self._do_vc_update_4) + d.addCallback(self._do_vctest_update_4) return d - def _do_vc_update_4(self, res): - log.msg("_do_vc_update_4") + def _do_vctest_update_4(self, res): + log.msg("_do_vctest_update_4") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", "version=%d" % (self.version-1)) # now update to the newer revision d = self.doBuild(ss=SourceStamp(revision=self.trunk[-1])) - d.addCallback(self._do_vc_update_5) + d.addCallback(self._do_vctest_update_5) return d - def _do_vc_update_5(self, res): - log.msg("_do_vc_update_5") + def _do_vctest_update_5(self, res): + log.msg("_do_vctest_update_5") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", "version=%d" % self.version) - def _do_vc_update_retry(self, res): + def _do_vctest_update_retry(self, res): # certain local changes will prevent an update from working. The # most common is to replace a file with a directory, or vice # versa. The slave code should spot the failure and do a @@ -512,16 +519,16 @@ self.touch(self.workdir, "newfile") d = self.doBuild() # update, but must clobber to handle the error - d.addCallback(self._do_vc_update_retry_1) + d.addCallback(self._do_vctest_update_retry_1) return d - def _do_vc_update_retry_1(self, res): + def _do_vctest_update_retry_1(self, res): self.shouldNotExist(self.workdir, "newfile") - def _do_vc_copy(self, res): + def _do_vctest_copy(self, res): d = self.doBuild() # copy rebuild clobbers new files - d.addCallback(self._do_vc_copy_1) + d.addCallback(self._do_vctest_copy_1) return d - def _do_vc_copy_1(self, res): + def _do_vctest_copy_1(self, res): if self.metadir: self.shouldExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") @@ -529,9 +536,9 @@ self.touch(self.vcdir, "newvcfile") d = self.doBuild() # copy rebuild clobbers new files - d.addCallback(self._do_vc_copy_2) + d.addCallback(self._do_vctest_copy_2) return d - def _do_vc_copy_2(self, res): + def _do_vctest_copy_2(self, res): if self.metadir: self.shouldExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") @@ -539,19 +546,19 @@ self.shouldExist(self.workdir, "newvcfile") self.touch(self.workdir, "newfile") - def _do_vc_export(self, res): + def _do_vctest_export(self, res): d = self.doBuild() # export rebuild clobbers new files - d.addCallback(self._do_vc_export_1) + d.addCallback(self._do_vctest_export_1) return d - def _do_vc_export_1(self, res): + def _do_vctest_export_1(self, res): self.shouldNotExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") self.touch(self.workdir, "newfile") d = self.doBuild() # export rebuild clobbers new files - d.addCallback(self._do_vc_export_2) + d.addCallback(self._do_vctest_export_2) return d - def _do_vc_export_2(self, res): + def _do_vctest_export_2(self, res): self.shouldNotExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") @@ -636,7 +643,7 @@ self.failUnlessIn("Hello patched subdir.\\n", data) - def do_vc_once(self, shouldSucceed): + def do_vctest_once(self, shouldSucceed): m = self.master vctype = self.vctype args = self.vcargs @@ -879,9 +886,10 @@ global VCS if not VCS.has_key("cvs"): VCS["cvs"] = False - for p in os.environ['PATH'].split(os.pathsep): - if os.path.exists(os.path.join(p, 'cvs')): - VCS["cvs"] = True + cvspaths = which('cvs') + if cvspaths: + VCS["cvs"] = True + self.vcexe = cvspaths[0] if not VCS["cvs"]: raise unittest.SkipTest("CVS is not installed") @@ -895,31 +903,31 @@ self.cvsrep = cvsrep = os.path.join(self.repbase, "CVS-Repository") tmp = os.path.join(self.repbase, "cvstmp") - w = self.do(self.repbase, "cvs -d %s init" % cvsrep) + w = self.dovc(self.repbase, "-d %s init" % cvsrep) yield w; w.getResult() # we must getResult() to raise any exceptions self.populate(tmp) - cmd = ("cvs -d %s import" % cvsrep + + cmd = ("-d %s import" % cvsrep + " -m sample_project_files sample vendortag start") - w = self.do(tmp, cmd) + w = self.dovc(tmp, cmd) yield w; w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) # take a timestamp as the first revision number time.sleep(2) self.addTrunkRev(self.getdate()) time.sleep(2) - w = self.do(self.repbase, - "cvs -d %s checkout -d cvstmp sample" % self.cvsrep) + w = self.dovc(self.repbase, + "-d %s checkout -d cvstmp sample" % self.cvsrep) yield w; w.getResult() - w = self.do(tmp, "cvs tag -b %s" % self.branchname) + w = self.dovc(tmp, "tag -b %s" % self.branchname) yield w; w.getResult() self.populate_branch(tmp) - w = self.do(tmp, - "cvs commit -m commit_on_branch -r %s" % self.branchname) + w = self.dovc(tmp, + "commit -m commit_on_branch -r %s" % self.branchname) yield w; w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) time.sleep(2) self.addBranchRev(self.getdate()) time.sleep(2) @@ -929,16 +937,16 @@ def vc_revise(self): tmp = os.path.join(self.repbase, "cvstmp") - w = self.do(self.repbase, - "cvs -d %s checkout -d cvstmp sample" % self.cvsrep) + w = self.dovc(self.repbase, + "-d %s checkout -d cvstmp sample" % self.cvsrep) yield w; w.getResult() self.version += 1 version_c = VERSION_C % self.version open(os.path.join(tmp, "version.c"), "w").write(version_c) - w = self.do(tmp, - "cvs commit -m revised_to_%d version.c" % self.version) + w = self.dovc(tmp, + "commit -m revised_to_%d version.c" % self.version) yield w; w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) time.sleep(2) self.addTrunkRev(self.getdate()) time.sleep(2) @@ -948,7 +956,11 @@ # 'workdir' is an absolute path assert os.path.abspath(workdir) == workdir - cmd = ["cvs", "-d", self.cvsrep, "checkout", + # get rid of timezone info, which might not be parsed # TODO + #rev = re.sub("[^0-9 :-]","",rev) + #rev = re.sub(" ","",rev) + #print "res is now <"+rev+">" + cmd = [self.vcexe, "-d", self.cvsrep, "checkout", "-d", workdir, "-D", rev] if branch is not None: @@ -961,12 +973,12 @@ vc_try_checkout = deferredGenerator(vc_try_checkout) def vc_try_finish(self, workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) class CVS(CVSSupport, unittest.TestCase): def testCheckout(self): - d = self.do_vc() + d = self.do_vctest() return maybeWait(d) def testPatch(self): @@ -993,23 +1005,24 @@ global VCS if not VCS.has_key("svn"): VCS["svn"] = False - for p in os.environ['PATH'].split(os.pathsep): - if os.path.exists(os.path.join(p, 'svn')): - # we need svn to be compiled with the ra_local access - # module - from twisted.internet import utils - log.msg("running svn --version..") - d = utils.getProcessOutput('svn', ["--version"], - env=os.environ) - d.addCallback(self._capable) - return d + svnpaths = which('svn') + svnadminpaths = which('svnadmin') + if svnpaths and svnadminpaths: + self.vcexe = svnpaths[0] + self.svnadmin = svnadminpaths[0] + # we need svn to be compiled with the ra_local access + # module + log.msg("running svn --version..") + d = utils.getProcessOutput(self.vcexe, ["--version"], + env=os.environ) + d.addCallback(self._capable) + return d if not VCS["svn"]: raise unittest.SkipTest("No usable Subversion was found") def _capable(self, v): if v.find("handles 'file' schem") != -1: - # older versions say 'schema'. 1.2.0 and beyond say - # 'scheme'. + # older versions say 'schema', 1.2.0 and beyond say 'scheme' VCS['svn'] = True else: log.msg(("%s found but it does not support 'file:' " + @@ -1019,74 +1032,81 @@ raise unittest.SkipTest("Found SVN, but it can't use file: schema") def vc_create(self): - self.svnrep = os.path.join(self.repbase, "SVN-Repository") + self.svnrep = os.path.join(self.repbase, + "SVN-Repository").replace('\\','/') tmp = os.path.join(self.repbase, "svntmp") - self.svnurl = "file://%s" % self.svnrep + if sys.platform == 'win32': + # On Windows Paths do not start with a / + self.svnurl = "file:///%s" % self.svnrep + else: + self.svnurl = "file://%s" % self.svnrep self.svnurl_trunk = self.svnurl + "/sample/trunk" self.svnurl_branch = self.svnurl + "/sample/branch" - w = self.do(self.repbase, "svnadmin create %s" % self.svnrep) + w = self.do(self.repbase, self.svnadmin+" create %s" % self.svnrep) yield w; w.getResult() self.populate(tmp) - w = self.do(tmp, - "svn import -m sample_project_files %s" % - self.svnurl_trunk) + w = self.dovc(tmp, + "import -m sample_project_files %s" % + self.svnurl_trunk) yield w; out = w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) m = re.search(r'Committed revision (\d+)\.', out) assert m.group(1) == "1" # first revision is always "1" self.addTrunkRev(int(m.group(1))) - w = self.do(self.repbase, - "svn checkout %s svntmp" % self.svnurl_trunk) + w = self.dovc(self.repbase, + "checkout %s svntmp" % self.svnurl_trunk) yield w; w.getResult() - w = self.do(tmp, "svn cp -m make_branch %s %s" % (self.svnurl_trunk, - self.svnurl_branch)) + w = self.dovc(tmp, "cp -m make_branch %s %s" % (self.svnurl_trunk, + self.svnurl_branch)) yield w; w.getResult() - w = self.do(tmp, "svn switch %s" % self.svnurl_branch) + w = self.dovc(tmp, "switch %s" % self.svnurl_branch) yield w; w.getResult() self.populate_branch(tmp) - w = self.do(tmp, "svn commit -m commit_on_branch") + w = self.dovc(tmp, "commit -m commit_on_branch") yield w; out = w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) m = re.search(r'Committed revision (\d+)\.', out) self.addBranchRev(int(m.group(1))) vc_create = deferredGenerator(vc_create) def vc_revise(self): tmp = os.path.join(self.repbase, "svntmp") - w = self.do(self.repbase, - "svn checkout %s svntmp" % self.svnurl_trunk) + rmdirRecursive(tmp) + log.msg("vc_revise" + self.svnurl_trunk) + w = self.dovc(self.repbase, + "checkout %s svntmp" % self.svnurl_trunk) yield w; w.getResult() self.version += 1 version_c = VERSION_C % self.version open(os.path.join(tmp, "version.c"), "w").write(version_c) - w = self.do(tmp, "svn commit -m revised_to_%d" % self.version) + w = self.dovc(tmp, "commit -m revised_to_%d" % self.version) yield w; out = w.getResult() m = re.search(r'Committed revision (\d+)\.', out) self.addTrunkRev(int(m.group(1))) - shutil.rmtree(tmp) + rmdirRecursive(tmp) vc_revise = deferredGenerator(vc_revise) def vc_try_checkout(self, workdir, rev, branch=None): assert os.path.abspath(workdir) == workdir if os.path.exists(workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) if not branch: svnurl = self.svnurl_trunk else: # N.B.: this is *not* os.path.join: SVN URLs use slashes # regardless of the host operating system's filepath separator svnurl = self.svnurl + "/" + branch - w = self.do(self.repbase, - "svn checkout %s %s" % (svnurl, workdir)) + w = self.dovc(self.repbase, + "checkout %s %s" % (svnurl, workdir)) yield w; w.getResult() open(os.path.join(workdir, "subdir", "subdir.c"), "w").write(TRY_C) vc_try_checkout = deferredGenerator(vc_try_checkout) def vc_try_finish(self, workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) class SVN(SVNSupport, unittest.TestCase): @@ -1095,7 +1115,7 @@ # we verify this one with the svnurl style of vcargs. We test the # baseURL/defaultBranch style in testPatch and testBranch. self.vcargs = { 'svnurl': self.svnurl_trunk } - d = self.do_vc() + d = self.do_vctest() return maybeWait(d) def testPatch(self): @@ -1120,7 +1140,7 @@ } d = self.do_getpatch() return maybeWait(d) - + class DarcsSupport(VCBase): # Darcs has a metadir="_darcs", but it does not have an 'export' @@ -1175,7 +1195,7 @@ w = self.do(tmp, "darcs changes --context") yield w; out = w.getResult() self.addBranchRev(out) - shutil.rmtree(tmp) + rmdirRecursive(tmp) vc_create = deferredGenerator(vc_create) def vc_revise(self): @@ -1196,13 +1216,13 @@ w = self.do(tmp, "darcs changes --context") yield w; out = w.getResult() self.addTrunkRev(out) - shutil.rmtree(tmp) + rmdirRecursive(tmp) vc_revise = deferredGenerator(vc_revise) def vc_try_checkout(self, workdir, rev, branch=None): assert os.path.abspath(workdir) == workdir if os.path.exists(workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) os.makedirs(workdir) w = self.do(workdir, "darcs initialize") yield w; w.getResult() @@ -1216,13 +1236,13 @@ vc_try_checkout = deferredGenerator(vc_try_checkout) def vc_try_finish(self, workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) class Darcs(DarcsSupport, unittest.TestCase): def testCheckout(self): self.vcargs = { 'repourl': self.rep_trunk } - d = self.do_vc(testRetry=False) + d = self.do_vctest(testRetry=False) # TODO: testRetry has the same problem with Darcs as it does for # Arch @@ -1244,7 +1264,7 @@ self.serveHTTP() repourl = "http://localhost:%d/Darcs-Repository/trunk" % self.httpPort self.vcargs = { 'repourl': repourl } - d = self.do_vc(testRetry=False) + d = self.do_vctest(testRetry=False) return maybeWait(d) def testTry(self): @@ -1294,17 +1314,17 @@ global VCS if not VCS.has_key("tla"): VCS["tla"] = False - for p in os.environ['PATH'].split(os.pathsep): - if os.path.exists(os.path.join(p, 'tla')): - VCS["tla"] = True + exe = which('tla') + if len(exe) > 0: + VCS["tla"] = True # we need to check for bazaar here too, since vc_create needs to know # about the presence of /usr/bin/baz even if we're running the tla # tests. if not VCS.has_key("baz"): VCS["baz"] = False - for p in os.environ['PATH'].split(os.pathsep): - if os.path.exists(os.path.join(p, 'baz')): - VCS["baz"] = True + exe = which('baz') + if len(exe) > 0: + VCS["baz"] = True if not VCS["tla"]: raise unittest.SkipTest("Arch (tla) is not installed") @@ -1401,7 +1421,7 @@ "tla tag -A %s %s %s" % (a, branchstart, branch)) yield w; w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) # check out the branch w = self.do(self.repbase, @@ -1421,7 +1441,7 @@ w = waitForDeferred(self.unregisterRepository()) yield w; w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) vc_create = deferredGenerator(vc_create) def vc_revise(self): @@ -1437,7 +1457,7 @@ # replay' in a tree with an archive that is no longer recognized, and # baz aborts with a botched invariant exception. This causes # mode=update to fall back to clobber+get, which flunks one of the - # tests (the 'newfile' check in _do_vc_update_3 fails) + # tests (the 'newfile' check in _do_vctest_update_3 fails) # to avoid this, we take heroic steps here to leave the archive # registration in the same state as we found it. @@ -1490,13 +1510,13 @@ # now re-register the original coordinates w = waitForDeferred(self.registerRepository(coordinates)) yield w; w.getResult() - shutil.rmtree(tmp) + rmdirRecursive(tmp) vc_revise = deferredGenerator(vc_revise) def vc_try_checkout(self, workdir, rev, branch=None): assert os.path.abspath(workdir) == workdir if os.path.exists(workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) a = self.archname @@ -1520,11 +1540,11 @@ vc_try_checkout = deferredGenerator(vc_try_checkout) def vc_try_finish(self, workdir): - shutil.rmtree(workdir) + rmdirRecursive(workdir) class Arch(TlaSupport, unittest.TestCase): def testCheckout(self): - d = self.do_vc(testRetry=False) + d = self.do_vctest(testRetry=False) # the current testRetry=True logic doesn't have the desired effect: # "update" is a no-op because arch knows that the repository hasn't # changed. Other VC systems will re-checkout missing files on @@ -1539,7 +1559,7 @@ url = "http://localhost:%d/Tla-Repository" % self.httpPort self.vcargs = { 'url': url, 'version': "testvc--mainline--1" } - d = self.do_vc(testRetry=False) + d = self.do_vctest(testRetry=False) return maybeWait(d) def testPatch(self): @@ -1585,7 +1605,7 @@ class Bazaar(BazaarSupport, unittest.TestCase): def testCheckout(self): - d = self.do_vc(testRetry=False) + d = self.do_vctest(testRetry=False) # the current testRetry=True logic doesn't have the desired effect: # "update" is a no-op because arch knows that the repository hasn't # changed. Other VC systems will re-checkout missing files on @@ -1602,7 +1622,7 @@ 'archive': self.archname, 'version': self.defaultbranch, } - d = self.do_vc(testRetry=False) + d = self.do_vctest(testRetry=False) return maybeWait(d) def testPatch(self): @@ -1647,7 +1667,7 @@ 'version': self.defaultbranch, 'retry': (5.0, 4), } - d = self.do_vc_once(True) + d = self.do_vctest_once(True) d.addCallback(self._testRetry_1) return maybeWait(d) def _testRetry_1(self, bs): @@ -1676,7 +1696,7 @@ 'version': self.defaultbranch, 'retry': (0.5, 3), } - d = self.do_vc_once(False) + d = self.do_vctest_once(False) d.addCallback(self._testRetryFails_1) return maybeWait(d) def _testRetryFails_1(self, bs): From warner at users.sourceforge.net Wed Apr 5 18:45:18 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:45:18 +0000 Subject: [Buildbot-commits] site index.html,1.59,1.60 Message-ID: Update of /cvsroot/buildbot/site In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30439 Modified Files: index.html Log Message: add Logicalware Index: index.html =================================================================== RCS file: /cvsroot/buildbot/site/index.html,v retrieving revision 1.59 retrieving revision 1.60 diff -u -d -r1.59 -r1.60 --- index.html 17 Mar 2006 01:26:41 -0000 1.59 +++ index.html 5 Apr 2006 18:45:15 -0000 1.60 @@ -418,6 +418,21 @@ + Logicalware + + Buildbot + + + home page + + + Kevin Campbell reports that his company is using a buildbot to help + them provide commercial support of a product over a large range of + architectures. + + + + @@ -469,5 +484,5 @@ href="http://creativecommons.org/licenses/by-sa/2.5/">Creative Commons Attribution Share-Alike license.

-Last modified: Thu Mar 16 17:25:22 PST 2006 +Last modified: Wed Apr 5 14:44:47 EDT 2006 From warner at users.sourceforge.net Wed Apr 5 18:45:57 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:45:57 +0000 Subject: [Buildbot-commits] site ChangeLog,1.30,1.31 Message-ID: Update of /cvsroot/buildbot/site In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30849 Modified Files: ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/site/ChangeLog,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- ChangeLog 17 Mar 2006 01:26:41 -0000 1.30 +++ ChangeLog 5 Apr 2006 18:45:54 -0000 1.31 @@ -1,3 +1,7 @@ +2006-04-05 Brian Warner + + * index.html (Success Stories): add Logicalware + 2006-03-16 Brian Warner * index.html (Sucess Stories): added the ASCEND buildbot From warner at users.sourceforge.net Wed Apr 5 18:55:45 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Wed, 05 Apr 2006 18:55:45 +0000 Subject: [Buildbot-commits] site ChangeLog,1.31,1.32 index.html,1.60,1.61 Message-ID: Update of /cvsroot/buildbot/site In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5587 Modified Files: ChangeLog index.html Log Message: add CodeSourcery link Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/site/ChangeLog,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- ChangeLog 5 Apr 2006 18:45:54 -0000 1.31 +++ ChangeLog 5 Apr 2006 18:55:42 -0000 1.32 @@ -1,6 +1,6 @@ 2006-04-05 Brian Warner - * index.html (Success Stories): add Logicalware + * index.html (Success Stories): add Logicalware, and CodeSourcery 2006-03-16 Brian Warner Index: index.html =================================================================== RCS file: /cvsroot/buildbot/site/index.html,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- index.html 5 Apr 2006 18:45:15 -0000 1.60 +++ index.html 5 Apr 2006 18:55:42 -0000 1.61 @@ -433,6 +433,19 @@ + CodeSourcery + + + + home page + + + Stefan Seefeld is using a buildbot for internal builds and tests at his + company. + + + + @@ -484,5 +497,5 @@ href="http://creativecommons.org/licenses/by-sa/2.5/">Creative Commons Attribution Share-Alike license.

-Last modified: Wed Apr 5 14:44:47 EDT 2006 +Last modified: Wed Apr 5 14:52:00 EDT 2006 From warner at users.sourceforge.net Fri Apr 7 04:11:00 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:11:00 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.584,1.585 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27895 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-481 Creator: Brian Warner SF#1412605 : add BuildFactory.addStep * buildbot/process/factory.py (BuildFactory.addStep): new method to add steps to a BuildFactory. Use it instead of f.steps.append, and you can probably avoid using the s() convenience function. Patch from Neal Norwitz, sf.net #1412605. (other): update all factories to use addStep * buildbot/process/process_twisted.py: update all factories to use addStep. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.584 retrieving revision 1.585 diff -u -d -r1.584 -r1.585 --- ChangeLog 5 Apr 2006 18:25:36 -0000 1.584 +++ ChangeLog 7 Apr 2006 04:10:57 -0000 1.585 @@ -1,11 +1,22 @@ +2006-04-05 Brian Warner + + * buildbot/process/factory.py (BuildFactory.addStep): new method + to add steps to a BuildFactory. Use it instead of f.steps.append, + and you can probably avoid using the s() convenience function. + Patch from Neal Norwitz, sf.net #1412605. + (other): update all factories to use addStep + * buildbot/process/process_twisted.py: update all factories to use + addStep. + 2006-04-03 Brian Warner * buildbot/test/test_vc.py: modified find-the-VC-command logic to - work under windows too. Adapted from a patch by Niklaus Giger. + work under windows too. Adapted from a patch by Niklaus Giger, + addresses SF#1463399. * buildbot/test/__init__.py: set $LANG to 'C', to insure that spawned commands emit parseable results in english and not some - other language. Patch from Niklaus Giger. + other language. Patch from Niklaus Giger, SF#1463394. * README (INSTALLATION): discourage users from running unit tests on a "network drive", patch from Niklaus Giger. From warner at users.sourceforge.net Fri Apr 7 04:11:00 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:11:00 +0000 Subject: [Buildbot-commits] buildbot/buildbot/process factory.py,1.11,1.12 process_twisted.py,1.41,1.42 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/process In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27895/buildbot/process Modified Files: factory.py process_twisted.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-481 Creator: Brian Warner SF#1412605 : add BuildFactory.addStep * buildbot/process/factory.py (BuildFactory.addStep): new method to add steps to a BuildFactory. Use it instead of f.steps.append, and you can probably avoid using the s() convenience function. Patch from Neal Norwitz, sf.net #1412605. (other): update all factories to use addStep * buildbot/process/process_twisted.py: update all factories to use addStep. Index: factory.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/factory.py,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- factory.py 5 Nov 2005 21:52:08 -0000 1.11 +++ factory.py 7 Apr 2006 04:10:56 -0000 1.12 @@ -4,6 +4,7 @@ from buildbot.process.base import Build from buildbot.process import step +# deprecated, use BuildFactory.addStep def s(steptype, **kwargs): # convenience function for master.cfg files, to create step # specification tuples @@ -15,12 +16,12 @@ @type buildClass: L{buildbot.process.base.Build} """ buildClass = Build - steps = [] useProgress = 1 compare_attrs = ['buildClass', 'steps', 'useProgress'] def __init__(self, steps=None): - if steps is None: steps = [] + if steps is None: + steps = [] self.steps = steps def newBuild(self, request): @@ -32,6 +33,9 @@ b.setSteps(self.steps) return b + def addStep(self, steptype, **kwargs): + self.steps.append((steptype, kwargs)) + # BuildFactory subclasses for common build tools @@ -43,8 +47,7 @@ test=["make", "check"]): assert type(source) is tuple assert issubclass(source[0], step.BuildStep) - self.steps = [] - self.steps.append(source) + BuildFactory.__init__(self, [source]) if configure is not None: # we either need to wind up with a string (which will be # space-split), or with a list of strings (which will not). The @@ -58,35 +61,29 @@ else: assert type(configure) in (list, tuple) command = configure + configureFlags - self.steps.append(s(step.Configure, - command=command, - env=configureEnv)) + self.addStep(step.Configure, command=command, env=configureEnv) if compile is not None: - self.steps.append(s(step.Compile, command=compile)) + self.addStep(step.Compile, command=compile) if test is not None: - self.steps.append(s(step.Test, command=test)) + self.addStep(step.Test, command=test) class CPAN(BuildFactory): def __init__(self, source, perl="perl"): assert type(source) is tuple assert issubclass(source[0], step.BuildStep) - self.steps = [] - self.steps.append(source) - self.steps.append(s(step.Configure, - command=[perl, "Makefile.PL"])) - self.steps.append(s(step.Compile, command=["make"])) - self.steps.append(s(step.Test, command=["make", "test"])) + BuildFactory.__init__(self, [source]) + self.addStep(step.Configure, command=[perl, "Makefile.PL"]) + self.addStep(step.Compile, command=["make"]) + self.addStep(step.Test, command=["make", "test"]) class Distutils(BuildFactory): def __init__(self, source, python="python", test=None): assert type(source) is tuple assert issubclass(source[0], step.BuildStep) - self.steps = [] - self.steps.append(source) - self.steps.append(s(step.Compile, - command=[python, "./setup.py", "build"])) + BuildFactory.__init__(self, [source]) + self.addStep(step.Compile, command=[python, "./setup.py", "build"]) if test is not None: - self.steps.append(s(step.Test, command=test)) + self.addStep(step.Test, command=test) class Trial(BuildFactory): """Build a python module that uses distutils and trial. Set 'tests' to @@ -107,6 +104,7 @@ buildpython=["python"], trialpython=[], trial=None, testpath=".", randomly=None, recurse=None, tests=None, useTestCaseNames=False, env=None): + BuildFactory.__init__(self, [source]) assert type(source) is tuple assert issubclass(source[0], step.BuildStep) assert tests or useTestCaseNames, "must use one or the other" @@ -118,18 +116,16 @@ self.recurse = recurse from buildbot.process import step_twisted - self.steps = [] - self.steps.append(source) buildcommand = buildpython + ["./setup.py", "build"] - self.steps.append(s(step.Compile, command=buildcommand, env=env)) - self.steps.append(s(step_twisted.Trial, - python=trialpython, trial=self.trial, - testpath=testpath, - tests=tests, testChanges=useTestCaseNames, - randomly=self.randomly, - recurse=self.recurse, - env=env, - )) + self.addStep(step.Compile, command=buildcommand, env=env) + self.addStep(step_twisted.Trial, + python=trialpython, trial=self.trial, + testpath=testpath, + tests=tests, testChanges=useTestCaseNames, + randomly=self.randomly, + recurse=self.recurse, + env=env, + ) # compatibility classes, will go away. Note that these only offer Index: process_twisted.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/process_twisted.py,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- process_twisted.py 26 Oct 2005 20:38:07 -0000 1.41 +++ process_twisted.py 7 Apr 2006 04:10:57 -0000 1.42 @@ -3,7 +3,7 @@ # Build classes specific to the Twisted codebase from buildbot.process.base import Build -from buildbot.process.factory import BuildFactory, s +from buildbot.process.factory import BuildFactory from buildbot.process import step from buildbot.process.step_twisted import HLint, ProcessDocs, BuildDebs, \ Trial, RemovePYCs @@ -32,29 +32,23 @@ # this to add the local tree to PYTHONPATH during tests workdir = "Twisted" - def __init__(self, svnurl, steps): - self.steps = [] - self.steps.append(s(step.SVN, svnurl=svnurl, mode=self.mode)) - self.steps.extend(steps) + def __init__(self, source): + BuildFactory.__init__(self, [source]) class QuickTwistedBuildFactory(TwistedBaseFactory): treeStableTimer = 30 useProgress = 0 def __init__(self, source, python="python"): + TwistedBuildFactory.__init__(self, source) if type(python) is str: python = [python] - self.steps = [] - self.steps.append(source) - self.steps.append(s(HLint, python=python[0])) - self.steps.append(s(RemovePYCs)) + self.addStep(HLint, python=python[0]) + self.addStep(RemovePYCs) for p in python: cmd = [p, "setup.py", "all", "build_ext", "-i"] - self.steps.append(s(step.Compile, command=cmd, - flunkOnFailure=True)) - self.steps.append(s(TwistedTrial, - python=p, # can be a list - testChanges=True)) + self.addStep(step.Compile, command=cmd, flunkOnFailure=True) + self.addStep(TwistedTrial, python=p, testChanges=True) class FullTwistedBuildFactory(TwistedBaseFactory): treeStableTimer = 5*60 @@ -62,10 +56,9 @@ def __init__(self, source, python="python", processDocs=False, runTestsRandomly=False, compileOpts=[], compileOpts2=[]): - self.steps = [] - self.steps.append(source) + TwistedBuildFactory.__init__(self, source) if processDocs: - self.steps.append(s(ProcessDocs)) + self.addStep(ProcessDocs) if type(python) == str: python = [python] @@ -74,19 +67,17 @@ cmd = (python + compileOpts + ["setup.py", "all", "build_ext"] + compileOpts2 + ["-i"]) - self.steps.append(s(step.Compile, command=cmd, flunkOnFailure=True)) - self.steps.append(s(RemovePYCs)) - self.steps.append(s(TwistedTrial, python=python, - randomly=runTestsRandomly)) + self.addStep(step.Compile, command=cmd, flunkOnFailure=True) + self.addStep(RemovePYCs) + self.addStep(TwistedTrial, python=python, randomly=runTestsRandomly) class TwistedDebsBuildFactory(TwistedBaseFactory): treeStableTimer = 10*60 def __init__(self, source, python="python"): - self.steps = [] - self.steps.append(source) - self.steps.append(s(ProcessDocs, haltOnFailure=True)) - self.steps.append(s(BuildDebs, warnOnWarnings=True)) + TwistedBuildFactory.__init__(self, source) + self.addStep(ProcessDocs, haltOnFailure=True) + self.addStep(BuildDebs, warnOnWarnings=True) class TwistedReactorsBuildFactory(TwistedBaseFactory): treeStableTimer = 5*60 @@ -94,8 +85,7 @@ def __init__(self, source, python="python", compileOpts=[], compileOpts2=[], reactors=None): - self.steps = [] - self.steps.append(source) + TwistedBuildFactory.__init__(self, source) if type(python) == str: python = [python] @@ -104,7 +94,7 @@ cmd = (python + compileOpts + ["setup.py", "all", "build_ext"] + compileOpts2 + ["-i"]) - self.steps.append(s(step.Compile, command=cmd, warnOnFailure=True)) + self.addStep(step.Compile, command=cmd, warnOnFailure=True) if reactors == None: reactors = [ @@ -123,8 +113,7 @@ # # these are buggy, so tolerate failures for now # flunkOnFailure = 0 # warnOnFailure = 1 - self.steps.append(s(RemovePYCs)) # TODO: why? - self.steps.append(s(TwistedTrial, name=reactor, - python=python, reactor=reactor, - flunkOnFailure=flunkOnFailure, - warnOnFailure=warnOnFailure)) + self.stepaddStep(RemovePYCs) # TODO: why? + self.addStep(TwistedTrial, name=reactor, python=python, + reactor=reactor, flunkOnFailure=flunkOnFailure, + warnOnFailure=warnOnFailure) From warner at users.sourceforge.net Fri Apr 7 04:14:59 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:14:59 +0000 Subject: [Buildbot-commits] buildbot/buildbot/process step.py,1.79,1.80 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/process In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30329/buildbot/process Modified Files: step.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-483 Creator: Brian Warner SF#1219384: add arguments to p4poller/P4Sync * buildbot/changes/p4poller.py (P4Source): add new arguments: password, p4 binary, pollinterval, maximum history to check. Patch from an anonymous sf.net contributor, SF#1219384. * buildbot/process/step.py (P4Sync.__init__): add username, password, and client arguments. * buildbot/slave/commands.py (P4Sync): same Index: step.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step.py,v retrieving revision 1.79 retrieving revision 1.80 diff -u -d -r1.79 -r1.80 --- step.py 26 Nov 2005 02:14:31 -0000 1.79 +++ step.py 7 Apr 2006 04:14:56 -0000 1.80 @@ -1676,11 +1676,14 @@ name = "p4sync" - def __init__(self, p4port, **kwargs): + def __init__(self, p4port, p4user, p4passwd, p4client, **kwargs): assert kwargs['mode'] == "copy", "P4Sync can only be used in mode=copy" self.branch = None Source.__init__(self, **kwargs) self.args['p4port'] = p4port + self.args['p4user'] = p4user + self.args['p4passwd'] = p4passwd + self.args['p4client'] = p4client def computeSourceRevision(self, changes): if not changes: From warner at users.sourceforge.net Fri Apr 7 04:14:59 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:14:59 +0000 Subject: [Buildbot-commits] buildbot/buildbot/changes p4poller.py,1.4,1.5 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/changes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30329/buildbot/changes Modified Files: p4poller.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-483 Creator: Brian Warner SF#1219384: add arguments to p4poller/P4Sync * buildbot/changes/p4poller.py (P4Source): add new arguments: password, p4 binary, pollinterval, maximum history to check. Patch from an anonymous sf.net contributor, SF#1219384. * buildbot/process/step.py (P4Sync.__init__): add username, password, and client arguments. * buildbot/slave/commands.py (P4Sync): same Index: p4poller.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/changes/p4poller.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- p4poller.py 17 May 2005 10:14:09 -0000 1.4 +++ p4poller.py 7 Apr 2006 04:14:57 -0000 1.5 @@ -13,7 +13,7 @@ """This source will poll a perforce repository for changes and submit them to the change master.""" - compare_attrs = ["p4port", "p4user", "p4client", "p4base", + compare_attrs = ["p4port", "p4user", "p4passwd", "p4client", "p4base", "p4bin", "pollinterval", "histmax"] parent = None # filled in when we're added @@ -21,13 +21,16 @@ loop = None volatile = ['loop'] - def __init__(self, p4port, p4user, p4client, p4base, - p4bin='p4', pollinterval=60 * 10, histmax=100): + def __init__(self, p4port, p4user, p4passwd=None, p4client=None, + p4base='//...', p4bin='p4', + pollinterval=60 * 10, histmax=100): """ @type p4port: string @param p4port: p4 port definition (host:portno) @type p4user: string @param p4user: p4 user + @type p4passwd: string + @param p4passwd: p4 passwd @type p4client: string @param p4client: name of p4 client to poll @type p4base: string @@ -43,6 +46,7 @@ self.p4port = p4port self.p4user = p4user + self.p4passwd = p4passwd self.p4client = p4client self.p4base = p4base self.p4bin = p4bin @@ -59,7 +63,7 @@ return base.ChangeSource.stopService(self) def describe(self): - return "p4source %s:%s %s" % (self.p4port, self.p4client, self.p4base) + return "p4source %s-%s %s" % (self.p4port, self.p4client, self.p4base) def checkp4(self): d = self._get_changes() @@ -67,10 +71,17 @@ d.addCallback(self._handle_changes) def _get_changes(self): - args = ['changes', '-m', str(self.histmax), self.p4base] - env = {'P4PORT' : self.p4port, - 'P4USER' : self.p4user, - 'P4CLIENT' : self.p4client} + args = [] + if self.p4port: + args.extend(['-p', self.p4port]) + if self.p4user: + args.extend(['-u', self.p4user]) + if self.p4passwd: + args.extend(['-P', self.p4passwd]) + if self.p4client: + args.extend(['-c', self.p4client]) + args.extend(['changes', '-m', str(self.histmax), self.p4base]) + env = {} return getProcessOutput(self.p4bin, args, env) def _process_changes(self, result): @@ -91,9 +102,17 @@ return defer.DeferredList(ds) def _get_change(self, change): - args = ['describe', '-s', change['num']] - env = {'P4PORT' : self.p4port, - 'P4CLIENT' : self.p4client} + args = [] + if self.p4port: + args.extend(['-p', self.p4port]) + if self.p4user: + args.extend(['-u', self.p4user]) + if self.p4passwd: + args.extend(['-P', self.p4passwd]) + if self.p4client: + args.extend(['-c', self.p4client]) + args.extend(['describe', '-s', change['num']]) + env = {} d = getProcessOutput(self.p4bin, args, env) d.addCallback(self._process_change, change) return d From warner at users.sourceforge.net Fri Apr 7 04:14:59 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:14:59 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.585,1.586 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30329 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-483 Creator: Brian Warner SF#1219384: add arguments to p4poller/P4Sync * buildbot/changes/p4poller.py (P4Source): add new arguments: password, p4 binary, pollinterval, maximum history to check. Patch from an anonymous sf.net contributor, SF#1219384. * buildbot/process/step.py (P4Sync.__init__): add username, password, and client arguments. * buildbot/slave/commands.py (P4Sync): same Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.585 retrieving revision 1.586 diff -u -d -r1.585 -r1.586 --- ChangeLog 7 Apr 2006 04:10:57 -0000 1.585 +++ ChangeLog 7 Apr 2006 04:14:57 -0000 1.586 @@ -1,3 +1,12 @@ +2006-04-07 Brian Warner + + * buildbot/changes/p4poller.py (P4Source): add new arguments: + password, p4 binary, pollinterval, maximum history to check. + Patch from an anonymous sf.net contributor, SF#1219384. + * buildbot/process/step.py (P4Sync.__init__): add username, + password, and client arguments. + * buildbot/slave/commands.py (P4Sync): same + 2006-04-05 Brian Warner * buildbot/process/factory.py (BuildFactory.addStep): new method From warner at users.sourceforge.net Fri Apr 7 04:14:59 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:14:59 +0000 Subject: [Buildbot-commits] buildbot/buildbot/slave commands.py,1.40,1.41 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/slave In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30329/buildbot/slave Modified Files: commands.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-483 Creator: Brian Warner SF#1219384: add arguments to p4poller/P4Sync * buildbot/changes/p4poller.py (P4Source): add new arguments: password, p4 binary, pollinterval, maximum history to check. Patch from an anonymous sf.net contributor, SF#1219384. * buildbot/process/step.py (P4Sync.__init__): add username, password, and client arguments. * buildbot/slave/commands.py (P4Sync): same Index: commands.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/slave/commands.py,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- commands.py 22 Oct 2005 22:41:59 -0000 1.40 +++ commands.py 7 Apr 2006 04:14:57 -0000 1.41 @@ -1226,7 +1226,10 @@ environment. The only thing which comes from the master is P4PORT. 'mode' is required to be 'copy'. - ['p4port'] (required): host:port to put in env['P4PORT'] + ['p4port'] (required): host:port for server to access + ['p4user'] (optional): user to use for access + ['p4passwd'] (optional): passwd to try for the user + ['p4client'] (optional): client spec to use """ header = "p4 sync" @@ -1234,15 +1237,28 @@ def setup(self, args): SourceBase.setup(self, args) self.p4port = args['p4port'] + self.p4user = args['p4user'] + self.p4passwd = args['p4passwd'] + self.p4client = args['p4client'] def sourcedirIsUpdateable(self): return True def doVCUpdate(self): - # TODO: revision d = os.path.join(self.builder.basedir, self.srcdir) - command = ['p4', 'sync'] - env = {'P4PORT': self.p4port} + command = ['p4'] + if self.p4port: + command.extend(['-p', self.p4port]) + if self.p4user: + command.extend(['-u', self.p4user]) + if self.p4passwd: + command.extend(['-P', self.p4passwd]) + if self.p4client: + command.extend(['-c', self.p4client]) + command.extend(['sync']) + if self.revision: + command.extend(['@' + self.revision]) + env = {} c = ShellCommand(self.builder, command, d, environ=env, sendRC=False, timeout=self.timeout) self.command = c From warner at users.sourceforge.net Fri Apr 7 04:24:26 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:24:26 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.586,1.587 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4634 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-485 Creator: Brian Warner ChangeLog: fix sf.net issue numbers Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.586 retrieving revision 1.587 diff -u -d -r1.586 -r1.587 --- ChangeLog 7 Apr 2006 04:14:57 -0000 1.586 +++ ChangeLog 7 Apr 2006 04:24:24 -0000 1.587 @@ -25,10 +25,10 @@ * buildbot/test/__init__.py: set $LANG to 'C', to insure that spawned commands emit parseable results in english and not some - other language. Patch from Niklaus Giger, SF#1463394. + other language. Patch from Niklaus Giger, SF#1463395. * README (INSTALLATION): discourage users from running unit tests on - a "network drive", patch from Niklaus Giger. + a "network drive", patch from Niklaus Giger, SF#1463394. 2006-03-22 Brian Warner From warner at users.sourceforge.net Fri Apr 7 04:31:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:31:39 +0000 Subject: [Buildbot-commits] buildbot/docs/examples twisted_master.cfg,1.40,1.41 Message-ID: Update of /cvsroot/buildbot/buildbot/docs/examples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9077/docs/examples Modified Files: twisted_master.cfg Log Message: * docs/buildbot.texinfo (Interlocks): fix some typos, mention use of SlaveLocks for performance tests * docs/examples/twisted_master.cfg: update to match current usage Index: twisted_master.cfg =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/examples/twisted_master.cfg,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- twisted_master.cfg 19 Jan 2006 01:32:58 -0000 1.40 +++ twisted_master.cfg 7 Apr 2006 04:31:37 -0000 1.41 @@ -135,10 +135,20 @@ } builders.append(b4) +# jml's machine is specifically for testing Qt +bqt = {'name': "Qt", + 'slavename': "bot-jml-qt", + 'builddir': "qt", + 'factory': TwistedReactorsBuildFactory(source_copy, + python="python2.4", + reactors=['qt']), + } +builders.append(bqt) + jf = TwistedReactorsBuildFactory(source_copy, python="python2.4", reactors=["default"]) jf.steps.insert(0, s(step.ShellCommand, workdir=".", - command=["ktrace", "rm", "-rf", "Twisted"])) + command=["ktrace", "rm", "-rf", "Twisted"])) b24osx = {'name': "OS-X", 'slavename': "bot-jerub", 'builddir': "OSX-full2.4", @@ -186,17 +196,17 @@ builders.append(b24w32_iocp) -b23freebsd = {'name': "freebsd", +b24freebsd = {'name': "freebsd", 'slavename': "bot-landonf", - 'builddir': "freebsd-full2.3", + 'builddir': "freebsd-full2.4", 'factory': TwistedReactorsBuildFactory(source_copy, - python="python2.3", + python="python2.4", reactors=["default", "kqueue", ]), } -builders.append(b23freebsd) +builders.append(b24freebsd) # b24threadless = {'name': 'threadless', # 'slavename': 'bot-threadless', From warner at users.sourceforge.net Fri Apr 7 04:31:40 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:31:40 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.587,1.588 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9077 Modified Files: ChangeLog Log Message: * docs/buildbot.texinfo (Interlocks): fix some typos, mention use of SlaveLocks for performance tests * docs/examples/twisted_master.cfg: update to match current usage Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.587 retrieving revision 1.588 diff -u -d -r1.587 -r1.588 --- ChangeLog 7 Apr 2006 04:24:24 -0000 1.587 +++ ChangeLog 7 Apr 2006 04:31:38 -0000 1.588 @@ -1,5 +1,10 @@ 2006-04-07 Brian Warner + * docs/buildbot.texinfo (Interlocks): fix some typos, mention use + of SlaveLocks for performance tests + + * docs/examples/twisted_master.cfg: update to match current usage + * buildbot/changes/p4poller.py (P4Source): add new arguments: password, p4 binary, pollinterval, maximum history to check. Patch from an anonymous sf.net contributor, SF#1219384. From warner at users.sourceforge.net Fri Apr 7 04:31:40 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Fri, 07 Apr 2006 04:31:40 +0000 Subject: [Buildbot-commits] buildbot/docs buildbot.texinfo,1.41,1.42 Message-ID: Update of /cvsroot/buildbot/buildbot/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9077/docs Modified Files: buildbot.texinfo Log Message: * docs/buildbot.texinfo (Interlocks): fix some typos, mention use of SlaveLocks for performance tests * docs/examples/twisted_master.cfg: update to match current usage Index: buildbot.texinfo =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- buildbot.texinfo 17 Mar 2006 01:07:08 -0000 1.41 +++ buildbot.texinfo 7 Apr 2006 04:31:37 -0000 1.42 @@ -3029,15 +3029,16 @@ Note that there are no partial-acquire or partial-release semantics: this prevents deadlocks caused by two Steps each waiting for a lock -held by the other. This also means that waiting to acquire a - at code{Lock} can take an arbitrarily long time: if the buildmaster is -very busy, a Step or Build which requires only one @code{Lock} may -starve another that is waiting for that @code{Lock} plus some others. - at footnote{Also note that a clever buildmaster admin could still create -the opportunity for deadlock: Build A obtains Lock 1, inside which -Step A.two tries to acquire Lock 2 at the Step level. Meanwhile Build -B obtains Lock 2, and has a Step B.two which wants to acquire Lock 1 -at the Step level. Don't Do That.} +held by the other at footnote{Also note that a clever buildmaster admin +could still create the opportunity for deadlock: Build A obtains Lock +1, inside which Step A.two tries to acquire Lock 2 at the Step level. +Meanwhile Build B obtains Lock 2, and has a Step B.two which wants to +acquire Lock 1 at the Step level. Don't Do That.}. This also means +that waiting to acquire a @code{Lock} can take an arbitrarily long +time: if the buildmaster is very busy, a Step or Build which requires +only one @code{Lock} may starve another that is waiting for that + at code{Lock} plus some others. + In the following example, we run the same build on three different platforms. The unit-test steps of these builds all use a common @@ -3055,9 +3056,9 @@ s(step.ShellCommand, command="make test", locks=[db_lock]), ] f = factory.BuildFactory(steps) -b1 = @{'name': 'full1', 'slavename': 'bot-1, builddir='f1', 'factory': f@} -b2 = @{'name': 'full2', 'slavename': 'bot-2, builddir='f2', 'factory': f@} -b3 = @{'name': 'full3', 'slavename': 'bot-3, builddir='f3', 'factory': f@} +b1 = @{'name': 'full1', 'slavename': 'bot-1', builddir='f1', 'factory': f@} +b2 = @{'name': 'full2', 'slavename': 'bot-2', builddir='f2', 'factory': f@} +b3 = @{'name': 'full3', 'slavename': 'bot-3', builddir='f3', 'factory': f@} c['builders'] = [b1, b2, b3] @end example @@ -3079,11 +3080,11 @@ f22 = factory.Trial(source, trialpython=["python2.2"]) f23 = factory.Trial(source, trialpython=["python2.3"]) f24 = factory.Trial(source, trialpython=["python2.4"]) -b1 = @{'name': 'p22', 'slavename': 'bot-1, builddir='p22', 'factory': f22, +b1 = @{'name': 'p22', 'slavename': 'bot-1', builddir='p22', 'factory': f22, 'locks': [slow_lock] @} -b2 = @{'name': 'p23', 'slavename': 'bot-1, builddir='p23', 'factory': f23, +b2 = @{'name': 'p23', 'slavename': 'bot-1', builddir='p23', 'factory': f23, 'locks': [slow_lock] @} -b3 = @{'name': 'p24', 'slavename': 'bot-1, builddir='p24', 'factory': f24, +b3 = @{'name': 'p24', 'slavename': 'bot-1', builddir='p24', 'factory': f24, 'locks': [slow_lock] @} c['builders'] = [b1, b2, b3] @end example @@ -3116,13 +3117,13 @@ locks=[db_lock]), ] fast_factory = factory.BuildFactory(fast_steps) -b1 = @{'name': 'full1', 'slavename': 'bot-slow, builddir='full1', +b1 = @{'name': 'full1', 'slavename': 'bot-slow', builddir='full1', 'factory': slow_factory@} -b2 = @{'name': 'full2', 'slavename': 'bot-slow, builddir='full2', +b2 = @{'name': 'full2', 'slavename': 'bot-slow', builddir='full2', 'factory': slow_factory@} -b3 = @{'name': 'full3', 'slavename': 'bot-fast, builddir='full3', +b3 = @{'name': 'full3', 'slavename': 'bot-fast', builddir='full3', 'factory': fast_factory@} -b4 = @{'name': 'full4', 'slavename': 'bot-fast, builddir='full4', +b4 = @{'name': 'full4', 'slavename': 'bot-fast', builddir='full4', 'factory': fast_factory@} c['builders'] = [b1, b2, b3, b4] @end example @@ -3142,6 +3143,10 @@ developers would not (or which might slow down or break in ways that require human attention to deal with). + at code{SlaveLocks}s can be used to keep automated performance tests +from interfering with each other, when there are multiple Builders all +using the same buildslave. But they can't prevent other users from +running CPU-intensive jobs on that host while the tests are running. @node Build Factories, , Interlocks, Build Process @section Build Factories From warner at users.sourceforge.net Tue Apr 11 06:09:04 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:09:04 +0000 Subject: [Buildbot-commits] buildbot/buildbot/test test_vc.py,1.45,1.46 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15752/buildbot/test Modified Files: test_vc.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-488 Creator: Brian Warner fix a twisted1.3 compatibility problem with t.p.procutils.which() * buildbot/test/test_vc.py (which): define our own which() in case we can't import twisted.python.procutils, because procutils doesn't exist in Twisted-1.3 Index: test_vc.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_vc.py,v retrieving revision 1.45 retrieving revision 1.46 diff -u -d -r1.45 -r1.46 --- test_vc.py 5 Apr 2006 18:25:36 -0000 1.45 +++ test_vc.py 11 Apr 2006 06:09:01 -0000 1.46 @@ -7,7 +7,35 @@ from twisted.trial import unittest from twisted.internet import defer, reactor, utils -from twisted.python.procutils import which +try: + from twisted.python.procutils import which +except ImportError: + # copied from Twisted circa 2.2.0 + def which(name, flags=os.X_OK): + """Search PATH for executable files with the given name. + + @type name: C{str} + @param name: The name for which to search. + + @type flags: C{int} + @param flags: Arguments to L{os.access}. + + @rtype: C{list} + @param: A list of the full paths to files found, in the + order in which they were found. + """ + result = [] + exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep)) + for p in os.environ['PATH'].split(os.pathsep): + p = os.path.join(p, name) + if os.access(p, flags): + result.append(p) + for e in exts: + pext = p + e + if os.access(pext, flags): + result.append(pext) + return result + #defer.Deferred.debug = True from twisted.python import log From warner at users.sourceforge.net Tue Apr 11 06:09:03 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:09:03 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.588,1.589 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15752 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-488 Creator: Brian Warner fix a twisted1.3 compatibility problem with t.p.procutils.which() * buildbot/test/test_vc.py (which): define our own which() in case we can't import twisted.python.procutils, because procutils doesn't exist in Twisted-1.3 Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.588 retrieving revision 1.589 diff -u -d -r1.588 -r1.589 --- ChangeLog 7 Apr 2006 04:31:38 -0000 1.588 +++ ChangeLog 11 Apr 2006 06:08:59 -0000 1.589 @@ -1,5 +1,9 @@ 2006-04-07 Brian Warner + * buildbot/test/test_vc.py (which): define our own which() in case + we can't import twisted.python.procutils, because procutils doesn't + exist in Twisted-1.3 + * docs/buildbot.texinfo (Interlocks): fix some typos, mention use of SlaveLocks for performance tests From warner at users.sourceforge.net Tue Apr 11 06:13:01 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:13:01 +0000 Subject: [Buildbot-commits] buildbot/buildbot/test test_vc.py,1.46,1.47 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18934/buildbot/test Modified Files: test_vc.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-490 Creator: Brian Warner add Mercurial support * buildbot/process/step.py (Mercurial): add Mercurial support * buildbot/slave/commands.py (Mercurial): same * buildbot/scripts/tryclient.py (MercurialExtractor): same * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is not yet tested, but 'try' support *is* covered * docs/buildbot.texinfo (Mercurial): document it * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add some debugging messages (turned off) * buildbot/test/test_vc.py: improve debug messages Index: test_vc.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_vc.py,v retrieving revision 1.46 retrieving revision 1.47 diff -u -d -r1.46 -r1.47 --- test_vc.py 11 Apr 2006 06:09:01 -0000 1.46 +++ test_vc.py 11 Apr 2006 06:12:59 -0000 1.47 @@ -51,6 +51,8 @@ from buildbot.twcompat import maybeWait from buildbot.scripts import tryclient +#step.LoggedRemoteCommand.debug = True + # buildbot.twcompat will patch these into t.i.defer if necessary from twisted.internet.defer import waitForDeferred, deferredGenerator @@ -349,7 +351,10 @@ d = utils.getProcessOutputAndValue(command[0], command[1:], env=os.environ, path=basedir) def check((out, err, code)): + #print + #print "command: %s" % command #print "out: %s" % out + #print "code: %s" % code if code != 0 and not failureIsOk: log.msg("command %s finished with exit code %d" % (command, code)) @@ -415,9 +420,13 @@ def touch(self, d, f): open(os.path.join(d,f),"w").close() def shouldExist(self, *args): - self.failUnless(os.path.exists(os.path.join(*args))) + target = os.path.join(*args) + self.failUnless(os.path.exists(target), + "expected to find %s but didn't" % target) def shouldNotExist(self, *args): - self.failIf(os.path.exists(os.path.join(*args))) + target = os.path.join(*args) + self.failIf(os.path.exists(target), + "expected to NOT find %s, but did" % target) def shouldContain(self, d, f, contents): c = open(os.path.join(d, f), "r").read() self.failUnlessIn(contents, c) @@ -693,6 +702,7 @@ return d def do_branch(self): + log.msg("do_branch") vctype = self.vctype args = self.vcargs m = self.master @@ -714,6 +724,7 @@ d.addCallback(self._doBranch_1) return d def _doBranch_1(self, res): + log.msg("_doBranch_1") # make sure the checkout was of the trunk main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") data = open(main_c, "r").read() @@ -726,6 +737,7 @@ d.addCallback(self._doBranch_2) return d def _doBranch_2(self, res): + log.msg("_doBranch_2") # make sure it was on the branch main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") data = open(main_c, "r").read() @@ -739,6 +751,7 @@ d.addCallback(self._doBranch_3) return d def _doBranch_3(self, res): + log.msg("_doBranch_3") # make sure it is still on the branch main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") data = open(main_c, "r").read() @@ -751,6 +764,7 @@ d.addCallback(self._doBranch_4) return d def _doBranch_4(self, res): + log.msg("_doBranch_4") # make sure it was on the trunk main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") data = open(main_c, "r").read() @@ -758,6 +772,7 @@ self.shouldNotExist(self.workdir, "newbranchfile") def do_getpatch(self, doBranch=True): + log.msg("do_getpatch") # prepare a buildslave to do checkouts vctype = self.vctype args = self.vcargs @@ -785,10 +800,11 @@ d.addCallback(self.do_getpatch_trunkold) if doBranch: d.addCallback(self.do_getpatch_branch) - d.addBoth(self.do_getpatch_finish) + d.addCallback(self.do_getpatch_finish) return d def do_getpatch_finish(self, res): + log.msg("do_getpatch_finish") self.vc_try_finish(self.trydir) return res @@ -805,24 +821,29 @@ devfilename, devfile)) def do_getpatch_trunkhead(self, res): + log.msg("do_getpatch_trunkhead") d = self.vc_try_checkout(self.trydir, self.trunk[-1]) d.addCallback(self._do_getpatch_trunkhead_1) return d def _do_getpatch_trunkhead_1(self, res): + log.msg("_do_getpatch_trunkhead_1") d = tryclient.getSourceStamp(self.vctype_try, self.trydir, None) d.addCallback(self._do_getpatch_trunkhead_2) return d def _do_getpatch_trunkhead_2(self, ss): + log.msg("_do_getpatch_trunkhead_2") d = self.doBuild(ss=ss) d.addCallback(self._do_getpatch_trunkhead_3) return d def _do_getpatch_trunkhead_3(self, res): + log.msg("_do_getpatch_trunkhead_3") # verify that the resulting buildslave tree matches the developer's self.try_shouldMatch("main.c") self.try_shouldMatch("version.c") self.try_shouldMatch(os.path.join("subdir", "subdir.c")) def do_getpatch_trunkold(self, res): + log.msg("do_getpatch_trunkold") # now try a tree from an older revision. We need at least two # revisions here, so we might have to create one first if len(self.trunk) < 2: @@ -831,38 +852,46 @@ return d return self._do_getpatch_trunkold_1() def _do_getpatch_trunkold_1(self, res=None): + log.msg("_do_getpatch_trunkold_1") d = self.vc_try_checkout(self.trydir, self.trunk[-2]) d.addCallback(self._do_getpatch_trunkold_2) return d def _do_getpatch_trunkold_2(self, res): + log.msg("_do_getpatch_trunkold_2") d = tryclient.getSourceStamp(self.vctype_try, self.trydir, None) d.addCallback(self._do_getpatch_trunkold_3) return d def _do_getpatch_trunkold_3(self, ss): + log.msg("_do_getpatch_trunkold_3") d = self.doBuild(ss=ss) d.addCallback(self._do_getpatch_trunkold_4) return d def _do_getpatch_trunkold_4(self, res): + log.msg("_do_getpatch_trunkold_4") # verify that the resulting buildslave tree matches the developer's self.try_shouldMatch("main.c") self.try_shouldMatch("version.c") self.try_shouldMatch(os.path.join("subdir", "subdir.c")) def do_getpatch_branch(self, res): + log.msg("do_getpatch_branch") # now try a tree from a branch d = self.vc_try_checkout(self.trydir, self.branch[-1], self.branchname) d.addCallback(self._do_getpatch_branch_1) return d def _do_getpatch_branch_1(self, res): + log.msg("_do_getpatch_branch_1") d = tryclient.getSourceStamp(self.vctype_try, self.trydir, self.try_branchname) d.addCallback(self._do_getpatch_branch_2) return d def _do_getpatch_branch_2(self, ss): + log.msg("_do_getpatch_branch_2") d = self.doBuild(ss=ss) d.addCallback(self._do_getpatch_branch_3) return d def _do_getpatch_branch_3(self, res): + log.msg("_do_getpatch_branch_3") # verify that the resulting buildslave tree matches the developer's self.try_shouldMatch("main.c") self.try_shouldMatch("version.c") @@ -1133,6 +1162,7 @@ yield w; w.getResult() open(os.path.join(workdir, "subdir", "subdir.c"), "w").write(TRY_C) vc_try_checkout = deferredGenerator(vc_try_checkout) + def vc_try_finish(self, workdir): rmdirRecursive(workdir) @@ -1730,6 +1760,148 @@ def _testRetryFails_1(self, bs): self.failUnlessEqual(bs.getResults(), FAILURE) +class MercurialSupport(VCBase): + # Mercurial has a metadir=".hg", but it does not have an 'export' mode. + metadir = None + branchname = "branch" + try_branchname = "branch" + vctype = "step.Mercurial" + vctype_try = "hg" + + def capable(self): + global VCS + if not VCS.has_key("hg"): + VCS["hg"] = False + hgpaths = which("hg") + if hgpaths: + VCS["hg"] = True + self.vcexe = hgpaths[0] + if not VCS["hg"]: + raise unittest.SkipTest("Mercurial is not installed") + + def extract_id(self, output): + m = re.search(r'^(\w+)', output) + return m.group(0) + + def vc_create(self): + self.hg_base = os.path.join(self.repbase, "Mercurial-Repository") + self.rep_trunk = os.path.join(self.hg_base, "trunk") + self.rep_branch = os.path.join(self.hg_base, "branch") + tmp = os.path.join(self.hg_base, "hgtmp") + + os.makedirs(self.rep_trunk) + w = self.dovc(self.rep_trunk, "init") + yield w; w.getResult() + os.makedirs(self.rep_branch) + w = self.dovc(self.rep_branch, "init") + yield w; w.getResult() + + self.populate(tmp) + w = self.dovc(tmp, "init") + yield w; w.getResult() + w = self.dovc(tmp, "addremove") + yield w; w.getResult() + w = self.dovc(tmp, "commit -m initial_import") + yield w; w.getResult() + w = self.dovc(tmp, "push %s" % self.rep_trunk) + # note that hg-push does not actually update the working directory + yield w; w.getResult() + w = self.dovc(tmp, "identify") + yield w; out = w.getResult() + self.addTrunkRev(self.extract_id(out)) + + self.populate_branch(tmp) + w = self.dovc(tmp, "commit -m commit_on_branch") + yield w; w.getResult() + w = self.dovc(tmp, "push %s" % self.rep_branch) + yield w; w.getResult() + w = self.dovc(tmp, "identify") + yield w; out = w.getResult() + self.addBranchRev(self.extract_id(out)) + rmdirRecursive(tmp) + vc_create = deferredGenerator(vc_create) + + def vc_revise(self): + tmp = os.path.join(self.hg_base, "hgtmp2") + w = self.dovc(self.hg_base, "clone %s %s" % (self.rep_trunk, tmp)) + yield w; w.getResult() + + self.version += 1 + version_c = VERSION_C % self.version + version_c_filename = os.path.join(tmp, "version.c") + open(version_c_filename, "w").write(version_c) + # hg uses timestamps to distinguish files which have changed, so we + # force the mtime forward a little bit + future = time.time() + 2*self.version + os.utime(version_c_filename, (future, future)) + w = self.dovc(tmp, "commit -m revised_to_%d" % self.version) + yield w; w.getResult() + w = self.dovc(tmp, "push %s" % self.rep_trunk) + yield w; w.getResult() + w = self.dovc(tmp, "identify") + yield w; out = w.getResult() + self.addTrunkRev(self.extract_id(out)) + rmdirRecursive(tmp) + vc_revise = deferredGenerator(vc_revise) + + def vc_try_checkout(self, workdir, rev, branch=None): + assert os.path.abspath(workdir) == workdir + if os.path.exists(workdir): + rmdirRecursive(workdir) + if branch: + src = self.rep_branch + else: + src = self.rep_trunk + w = self.dovc(self.hg_base, "clone %s %s" % (src, workdir)) + yield w; w.getResult() + try_c_filename = os.path.join(workdir, "subdir", "subdir.c") + open(try_c_filename, "w").write(TRY_C) + future = time.time() + 2*self.version + os.utime(try_c_filename, (future, future)) + vc_try_checkout = deferredGenerator(vc_try_checkout) + + def vc_try_finish(self, workdir): + rmdirRecursive(workdir) + + +class Mercurial(MercurialSupport, unittest.TestCase): + def testCheckout(self): + self.vcargs = { 'repourl': self.rep_trunk } + d = self.do_vctest(testRetry=False) + + # TODO: testRetry has the same problem with Mercurial as it does for + # Arch + return maybeWait(d) + + def testPatch(self): + self.vcargs = { 'baseURL': self.hg_base + "/", + 'defaultBranch': "trunk" } + d = self.do_patch() + return maybeWait(d) + + def testBranch(self): + self.vcargs = { 'baseURL': self.hg_base + "/", + 'defaultBranch': "trunk" } + d = self.do_branch() + return maybeWait(d) + + def testCheckoutHTTP(self): + self.serveHTTP() + repourl = "http://localhost:%d/Mercurial-Repository/trunk/.hg" % self.httpPort + self.vcargs = { 'repourl': repourl } + d = self.do_vctest(testRetry=False) + return maybeWait(d) + # TODO: The easiest way to publish hg over HTTP is by running 'hg serve' + # as a child process while the test is running. (you can also use a CGI + # script, which sounds difficult, or you can publish the files directly, + # which isn't well documented). + testCheckoutHTTP.skip = "not yet implemented, use 'hg serve'" + + def testTry(self): + self.vcargs = { 'baseURL': self.hg_base + "/", + 'defaultBranch': "trunk" } + d = self.do_getpatch() + return maybeWait(d) class Sources(unittest.TestCase): From warner at users.sourceforge.net Tue Apr 11 06:13:01 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:13:01 +0000 Subject: [Buildbot-commits] buildbot/buildbot/scripts tryclient.py,1.11,1.12 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18934/buildbot/scripts Modified Files: tryclient.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-490 Creator: Brian Warner add Mercurial support * buildbot/process/step.py (Mercurial): add Mercurial support * buildbot/slave/commands.py (Mercurial): same * buildbot/scripts/tryclient.py (MercurialExtractor): same * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is not yet tested, but 'try' support *is* covered * docs/buildbot.texinfo (Mercurial): document it * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add some debugging messages (turned off) * buildbot/test/test_vc.py: improve debug messages Index: tryclient.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/scripts/tryclient.py,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- tryclient.py 5 Nov 2005 22:58:09 -0000 1.11 +++ tryclient.py 11 Apr 2006 06:12:59 -0000 1.12 @@ -129,6 +129,20 @@ d.addCallback(self.readPatch, 1) return d +class MercurialExtractor(SourceStampExtractor): + patchlevel = 1 + def getBaseRevision(self): + d = self.do(["hg", "identify"]) + d.addCallback(self.parseStatus) + return d + def parseStatus(self, output): + m = re.search(r'^(\w+)', output) + self.baserev = m.group(0) + def getPatch(self, res): + d = self.do(["hg", "diff"]) + d.addCallback(self.readPatch, self.patchlevel) + return d + class DarcsExtractor(SourceStampExtractor): patchlevel = 1 def getBaseRevision(self): @@ -151,6 +165,8 @@ e = BazExtractor(treetop, branch) elif vctype == "tla": e = TlaExtractor(treetop, branch) + elif vctype == "hg": + e = MercurialExtractor(treetop, branch) elif vctype == "darcs": e = DarcsExtractor(treetop, branch) else: From warner at users.sourceforge.net Tue Apr 11 06:13:01 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:13:01 +0000 Subject: [Buildbot-commits] buildbot/docs buildbot.texinfo,1.42,1.43 Message-ID: Update of /cvsroot/buildbot/buildbot/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18934/docs Modified Files: buildbot.texinfo Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-490 Creator: Brian Warner add Mercurial support * buildbot/process/step.py (Mercurial): add Mercurial support * buildbot/slave/commands.py (Mercurial): same * buildbot/scripts/tryclient.py (MercurialExtractor): same * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is not yet tested, but 'try' support *is* covered * docs/buildbot.texinfo (Mercurial): document it * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add some debugging messages (turned off) * buildbot/test/test_vc.py: improve debug messages Index: buildbot.texinfo =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- buildbot.texinfo 7 Apr 2006 04:31:37 -0000 1.42 +++ buildbot.texinfo 11 Apr 2006 06:12:59 -0000 1.43 @@ -147,6 +147,7 @@ * CVS:: * SVN:: * Darcs:: +* Mercurial:: * Arch:: * Bazaar:: * P4Sync:: @@ -1043,9 +1044,9 @@ tag used in CVS)@footnote{many VC systems provide more complexity than this: in particular the local views that P4 and ClearCase can assemble out of various source directories are more complex than we're prepared -to take advantage of here}. The SHA1 revision ID used by Monotone is -also a kind of revision stamp, in that it specifies a unique copy of -the source tree, as does a Darcs ``context'' file. +to take advantage of here}. The SHA1 revision ID used by Monotone and +Mercurial is also a kind of revision stamp, in that it specifies a +unique copy of the source tree, as does a Darcs ``context'' file. When we aren't intending to make any changes to the sources we check out (at least not any that need to be committed back upstream), there are two @@ -1206,6 +1207,13 @@ revision number, but the patch-reordering flexibility of Darcs makes it impossible to provide a shorter useful specification). + at uref{http://selenic.com/mercurial, Mercurial} is like Darcs, in that +each branch is stored in a separate repository. The @code{repourl}, + at code{baseURL}, and @code{defaultBranch} arguments are all handled the +same way as with Darcs. The ``revision'', however, is the hash +identifier returned by @command{hg identify}. + + @node Attributes of Changes, , How Different VC Systems Specify Sources, Version Control Systems @subsection Attributes of Changes @@ -1257,6 +1265,8 @@ @code{revision} is an int, a transation number (r%d) @item Darcs @code{revision} is a large string, the output of @code{darcs changes --context} + at item Mercurial + at code{revision} is a short string (a hash ID), the output of @code{hg identify} @item Arch/Bazaar @code{revision} is the full revision ID (ending in --patch-%d) @item P4 @@ -1276,7 +1286,7 @@ combination of some base URL, the branch name, and the filename within the branch. (In a sense, the branch name and the filename inhabit the same namespace). Darcs branches are subdirectories of a base URL just -like SVN. +like SVN. Mercurial branches are the same as Darcs. @table @samp @item CVS @@ -1285,6 +1295,8 @@ branch='branches/trunk', files=['src/foo.c'] @item Darcs branch='branches/trunk', files=['src/foo.c'] + at item Mercurial +branch='branches/trunk', files=['src/foo.c'] @item Arch/Bazaar branch='buildbot--usebranches--0', files=['buildbot/master.py'] @end table @@ -2631,6 +2643,7 @@ * CVS:: * SVN:: * Darcs:: +* Mercurial:: * Arch:: * Bazaar:: * P4Sync:: @@ -2805,7 +2818,7 @@ will concatenate ``svn://svn.example.org/MyProject/'' with ``features/newthing'' to get the svnurl for checkout. - at node Darcs, Arch, SVN, Source Checkout + at node Darcs, Mercurial, SVN, Source Checkout @subsubsection Darcs @cindex Darcs Checkout @@ -2847,8 +2860,38 @@ will be passed to the @code{darcs get} command. @end table + at node Mercurial, Arch, Darcs, Source Checkout + at subsubsection Mercurial - at node Arch, Bazaar, Darcs, Source Checkout + at cindex Mercurial Checkout + +The @code{Mercurial} build step performs a + at uref{http://selenic.com/mercurial, Mercurial} (aka ``hg'') checkout +or update. + +Branches are handled just like @xref{Darcs}. + +The Mercurial step takes the following arguments: + + at table @code + at item repourl +(required unless @code{baseURL} is provided): the URL at which the +Mercurial source repository is available. + + at item baseURL +(required unless @code{repourl} is provided): the base repository URL, +to which a branch name will be appended. It should probably end in a +slash. + + at item defaultBranch +(allowed if and only if @code{baseURL} is provided): this specifies +the name of the branch to use when a Build does not provide one of its +own. This will be appended to @code{baseURL} to create the string that +will be passed to the @code{hg clone} command. + at end table + + + at node Arch, Bazaar, Mercurial, Source Checkout @subsubsection Arch @cindex Arch Checkout @@ -4128,6 +4171,10 @@ This can also be provided as @code{try_vc} in @file{.buildbot/options}. +The following names are recognized: @code{cvs} @code{svn} @code{baz} + at code{tla} @code{hg} @code{darcs} + + @heading finding the top of the tree Some VC systems (notably CVS and SVN) track each directory @@ -4151,12 +4198,14 @@ for each tree you use, so it may be more convenient to use the @code{try_topfile} approach instead. +Other VC systems which work on full projects instead of individual +directories (tla, baz, darcs, monotone, mercurial) do not require + at command{try} to know the top directory, so the @option{--try-topfile} +and @option{--try-topdir} arguments will be ignored. + at c is this true? I think I currently require topdirs all the time. + If the @command{try} command cannot find the top directory, it will -abort with an error message. Other VC systems which work on full -projects instead of individual directories (tla, baz, darcs, monotone) -do not require @command{try} to know the top directory, so the - at option{--try-topfile} and @option{--try-topdir} arguments will be -ignored. +abort with an error message. @heading determining the branch name @@ -4176,8 +4225,13 @@ @table @code @item CVS -Wow, good question. We have to assume that you've done an @code{cvs -update} on the whole tree... [TODO] + + at command{try} pretends that the tree is up to date. It converts the +current time into a @code{-D} time specification, uses it as the base +revision, and computes the diff between the upstream tree as of that +point in time versus the current contents. This works, more or less, +but requires that the local clock be in reasonably good sync with the +repository. @item SVN @command{try} does a @code{svn status -u} to find the latest @@ -4204,7 +4258,7 @@ first line of @code{tla logs --reverse} to figure out the base revision. Then it does @code{tla changes --diffs} to obtain the patch. - at item darcs + at item Darcs @code{darcs changes --context} emits a text file that contains a list of all patches back to and including the last tag was made. This text file (plus the location of a repository that contains all these @@ -4216,8 +4270,15 @@ what your tree's base revision is, and then does a @code{darcs diff -u} to compute the patch relative to that revision. + at item Mercurial + at code{hg identify} emits a short revision ID (basically a truncated +SHA1 hash of the current revision's contents), which is used as the +base revision. @code{hg diff} then provides the patch relative to that +revision. For @command{try} to work, your working directory must only +have patches that are available from the same remotely-available +repository that the build process' @code{step.Mercurial} will use. + @c TODO: monotone, git - at c TODO: new VC systems: mercurial (hg) @end table @heading waiting for results From warner at users.sourceforge.net Tue Apr 11 06:13:01 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:13:01 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.589,1.590 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18934 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-490 Creator: Brian Warner add Mercurial support * buildbot/process/step.py (Mercurial): add Mercurial support * buildbot/slave/commands.py (Mercurial): same * buildbot/scripts/tryclient.py (MercurialExtractor): same * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is not yet tested, but 'try' support *is* covered * docs/buildbot.texinfo (Mercurial): document it * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add some debugging messages (turned off) * buildbot/test/test_vc.py: improve debug messages Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.589 retrieving revision 1.590 diff -u -d -r1.589 -r1.590 --- ChangeLog 11 Apr 2006 06:08:59 -0000 1.589 +++ ChangeLog 11 Apr 2006 06:12:59 -0000 1.590 @@ -1,3 +1,16 @@ +2006-04-10 Brian Warner + + * buildbot/process/step.py (Mercurial): add Mercurial support + * buildbot/slave/commands.py (Mercurial): same + * buildbot/scripts/tryclient.py (MercurialExtractor): same + * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is + not yet tested, but 'try' support *is* covered + * docs/buildbot.texinfo (Mercurial): document it + + * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add + some debugging messages (turned off) + * buildbot/test/test_vc.py: improve debug messages + 2006-04-07 Brian Warner * buildbot/test/test_vc.py (which): define our own which() in case From warner at users.sourceforge.net Tue Apr 11 06:13:01 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:13:01 +0000 Subject: [Buildbot-commits] buildbot/buildbot/process step.py,1.80,1.81 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/process In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18934/buildbot/process Modified Files: step.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-490 Creator: Brian Warner add Mercurial support * buildbot/process/step.py (Mercurial): add Mercurial support * buildbot/slave/commands.py (Mercurial): same * buildbot/scripts/tryclient.py (MercurialExtractor): same * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is not yet tested, but 'try' support *is* covered * docs/buildbot.texinfo (Mercurial): document it * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add some debugging messages (turned off) * buildbot/test/test_vc.py: improve debug messages Index: step.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step.py,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -r1.80 -r1.81 --- step.py 7 Apr 2006 04:14:56 -0000 1.80 +++ step.py 11 Apr 2006 06:12:59 -0000 1.81 @@ -239,6 +239,7 @@ log = None closeWhenFinished = False rc = None + debug = False def __repr__(self): return "" % (self.remote_command, id(self)) @@ -262,6 +263,9 @@ def addHeader(self, data): self.log.addHeader(data) def remoteUpdate(self, update): + if self.debug: + for k,v in update.items(): + log.msg("Update[%s]: %s" % (k,v)) if update.has_key('stdout'): self.addStdout(update['stdout']) if update.has_key('stderr'): @@ -1635,6 +1639,63 @@ self.cmd = LoggedRemoteCommand("bazaar", self.args) ShellCommand.start(self, warnings) +class Mercurial(Source): + """Check out a source tree from a mercurial repository 'repourl'.""" + + name = "hg" + + def __init__(self, repourl=None, baseURL=None, defaultBranch=None, + **kwargs): + """ + @type repourl: string + @param repourl: the URL which points at the Mercurial repository. + This is used as the default branch. Using C{repourl} + does not enable builds of alternate branches: use + C{baseURL} to enable this. Use either C{repourl} or + C{baseURL}, not both. + + @param baseURL: if branches are enabled, this is the base URL to + which a branch name will be appended. It should + probably end in a slash. Use exactly one of + C{repourl} and C{baseURL}. + + @param defaultBranch: if branches are enabled, this is the branch + to use if the Build does not specify one + explicitly. It will simply be appended to + C{baseURL} and the result handed to the + 'hg clone' command. + """ + self.repourl = repourl + self.baseURL = baseURL + self.branch = defaultBranch + Source.__init__(self, **kwargs) + if (not repourl and not baseURL) or (repourl and baseURL): + raise ValueError("you must provide exactly one of repourl and" + " baseURL") + + def startVC(self, branch, revision, patch): + slavever = self.slaveVersion("hg") + if not slavever: + raise BuildSlaveTooOldError("slave is too old, does not know " + "about hg") + + if self.repourl: + assert not branch # we need baseURL= to use branches + self.args['repourl'] = self.repourl + else: + self.args['repourl'] = self.baseURL + branch + self.args['revision'] = revision + self.args['patch'] = patch + + revstuff = [] + if branch is not None and branch != self.branch: + revstuff.append("[branch]") + self.description.extend(revstuff) + self.descriptionDone.extend(revstuff) + + self.cmd = LoggedRemoteCommand("hg", self.args) + ShellCommand.start(self) + class todo_P4(Source): name = "p4" From warner at users.sourceforge.net Tue Apr 11 06:13:01 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:13:01 +0000 Subject: [Buildbot-commits] buildbot/buildbot/slave commands.py,1.41,1.42 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/slave In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18934/buildbot/slave Modified Files: commands.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-490 Creator: Brian Warner add Mercurial support * buildbot/process/step.py (Mercurial): add Mercurial support * buildbot/slave/commands.py (Mercurial): same * buildbot/scripts/tryclient.py (MercurialExtractor): same * buildbot/test/test_vc.py (Mercurial): same, checkout over HTTP is not yet tested, but 'try' support *is* covered * docs/buildbot.texinfo (Mercurial): document it * buildbot/process/step.py (LoggedRemoteCommand.remoteUpdate): add some debugging messages (turned off) * buildbot/test/test_vc.py: improve debug messages Index: commands.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/slave/commands.py,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- commands.py 7 Apr 2006 04:14:57 -0000 1.41 +++ commands.py 11 Apr 2006 06:12:59 -0000 1.42 @@ -1217,9 +1217,72 @@ d.addCallback(self._didGet) return d +registerSlaveCommand("bazaar", Bazaar, cvs_ver) -registerSlaveCommand("bazaar", Bazaar, cvs_ver) +class Mercurial(SourceBase): + """Mercurial specific VC operation. In addition to the arguments + handled by SourceBase, this command reads the following keys: + + ['repourl'] (required): the Cogito repository string + """ + + header = "mercurial operation" + + def setup(self, args): + SourceBase.setup(self, args) + self.repourl = args['repourl'] + self.sourcedata = "%s\n" % self.repourl + self.stdout = "" + self.stderr = "" + + def sourcedirIsUpdateable(self): + if os.path.exists(os.path.join(self.builder.basedir, + self.srcdir, ".buildbot-patched")): + return False + # like Darcs, to check out a specific (old) revision, we have to do a + # full checkout. TODO: I think 'hg pull' plus 'hg update' might work + if self.revision: + return False + return os.path.isdir(os.path.join(self.builder.basedir, + self.srcdir, ".hg")) + + def doVCUpdate(self): + d = os.path.join(self.builder.basedir, self.srcdir) + command = ['hg', 'pull', '--update', '--verbose'] + if self.args['revision']: + command.extend(['--rev', self.args['revision']]) + c = ShellCommand(self.builder, command, d, + sendRC=False, timeout=self.timeout, + keepStdout=True) + self.command = c + d = c.start() + d.addCallback(self._handleEmptyUpdate) + return d + + def _handleEmptyUpdate(self, res): + if type(res) is int and res == 1: + if "no changes found" in self.command.stdout: + # 'hg pull', when it doesn't have anything to do, exits with + # rc=1, and there appears to be no way to shut this off. It + # emits a distinctive message to stdout, though. So catch + # this and pretend that it completed successfully. + return 0 + return res + + def doVCFull(self): + d = os.path.join(self.builder.basedir, self.srcdir) + command = ['hg', 'clone'] + if self.args['revision']: + command.extend(['--rev', self.args['revision']]) + command.extend([self.repourl, d]) + c = ShellCommand(self.builder, command, self.builder.basedir, + sendRC=False, timeout=self.timeout) + self.command = c + return c.start() + +registerSlaveCommand("hg", Mercurial, cvs_ver) + class P4Sync(SourceBase): """A partial P4 source-updater. Requires manual setup of a per-slave P4 From warner at users.sourceforge.net Tue Apr 11 06:48:29 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 11 Apr 2006 06:48:29 +0000 Subject: [Buildbot-commits] buildbot/buildbot/slave commands.py,1.42,1.43 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/slave In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13648/buildbot/slave Modified Files: commands.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-492 Creator: Brian Warner fix a python2.2-compatibility problem in Mercurial support Index: commands.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/slave/commands.py,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- commands.py 11 Apr 2006 06:12:59 -0000 1.42 +++ commands.py 11 Apr 2006 06:48:26 -0000 1.43 @@ -1262,7 +1262,7 @@ def _handleEmptyUpdate(self, res): if type(res) is int and res == 1: - if "no changes found" in self.command.stdout: + if self.command.stdout.find("no changes found") != -1: # 'hg pull', when it doesn't have anything to do, exits with # rc=1, and there appears to be no way to shut this off. It # emits a distinctive message to stdout, though. So catch From warner at users.sourceforge.net Sun Apr 16 23:05:43 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Sun, 16 Apr 2006 23:05:43 +0000 Subject: [Buildbot-commits] buildbot/buildbot/status html.py,1.81,1.82 builder.py,1.76,1.77 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/status In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29450/buildbot/status Modified Files: html.py builder.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-494 Creator: Brian Warner fix a number of incorrect names and missing imports [Anthony Baxter] * all: fix a number of incorrect names and missing imports, thanks to Anthony Baxter for the patch. * buildbot/status/html.py (WaterfallStatusResource.statusToHTML): remove unused buggy method. * buildbot/status/builder.py (BuildStatus.saveYourself): rmtree comes from shutil, not "shutils" * buildbot/process/step.py (TreeSize.evaluateCommand): fix bad name (Arch.checkSlaveVersion): same * buildbot/process/step_twisted.py (Trial.commandComplete): same, in some disabled code * buildbot/process/step_twisted2.py: add some missing imports * buildbot/twcompat.py (_deferGenerator): fix cut-and-paste error, this code used to live in twisted.internet.defer Index: builder.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/status/builder.py,v retrieving revision 1.76 retrieving revision 1.77 diff -u -d -r1.76 -r1.77 --- builder.py 13 Mar 2006 08:21:43 -0000 1.76 +++ builder.py 16 Apr 2006 23:05:41 -0000 1.77 @@ -1256,7 +1256,7 @@ filename = os.path.join(self.builder.basedir, "%d" % self.number) if os.path.isdir(filename): # leftover from 0.5.0, which stored builds in directories - shutils.rmtree(filename, ignore_errors=True) + shutil.rmtree(filename, ignore_errors=True) tmpfilename = filename + ".tmp" try: pickle.dump(self, open(tmpfilename, "wb"), -1) Index: html.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/status/html.py,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- html.py 12 Mar 2006 11:28:02 -0000 1.81 +++ html.py 16 Apr 2006 23:05:41 -0000 1.82 @@ -1530,18 +1530,7 @@ # Nones are left empty, rowspan should make it all fit data += " \n" return data - - def statusToHTML(self, color, text, files): - # UNUSED - """Create a element from the status box.""" - t = "Dummy\n" - # for files, need to create a Resource around the file and putChild - # it to the waterfall display. - # name the child: - name = "%s/%d/%s" % (builder.name, builder.buildNumber, step.number) - - return t class StatusResource(Resource): status = None From warner at users.sourceforge.net Sun Apr 16 23:05:43 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Sun, 16 Apr 2006 23:05:43 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.590,1.591 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29450 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-494 Creator: Brian Warner fix a number of incorrect names and missing imports [Anthony Baxter] * all: fix a number of incorrect names and missing imports, thanks to Anthony Baxter for the patch. * buildbot/status/html.py (WaterfallStatusResource.statusToHTML): remove unused buggy method. * buildbot/status/builder.py (BuildStatus.saveYourself): rmtree comes from shutil, not "shutils" * buildbot/process/step.py (TreeSize.evaluateCommand): fix bad name (Arch.checkSlaveVersion): same * buildbot/process/step_twisted.py (Trial.commandComplete): same, in some disabled code * buildbot/process/step_twisted2.py: add some missing imports * buildbot/twcompat.py (_deferGenerator): fix cut-and-paste error, this code used to live in twisted.internet.defer Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.590 retrieving revision 1.591 diff -u -d -r1.590 -r1.591 --- ChangeLog 11 Apr 2006 06:12:59 -0000 1.590 +++ ChangeLog 16 Apr 2006 23:05:41 -0000 1.591 @@ -1,3 +1,19 @@ +2006-04-11 Brian Warner + + * all: fix a number of incorrect names and missing imports, thanks + to Anthony Baxter for the patch. + * buildbot/status/html.py (WaterfallStatusResource.statusToHTML): + remove unused buggy method. + * buildbot/status/builder.py (BuildStatus.saveYourself): rmtree + comes from shutil, not "shutils" + * buildbot/process/step.py (TreeSize.evaluateCommand): fix bad name + (Arch.checkSlaveVersion): same + * buildbot/process/step_twisted.py (Trial.commandComplete): same, in + some disabled code + * buildbot/process/step_twisted2.py: add some missing imports + * buildbot/twcompat.py (_deferGenerator): fix cut-and-paste error, + this code used to live in twisted.internet.defer + 2006-04-10 Brian Warner * buildbot/process/step.py (Mercurial): add Mercurial support From warner at users.sourceforge.net Sun Apr 16 23:05:43 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Sun, 16 Apr 2006 23:05:43 +0000 Subject: [Buildbot-commits] buildbot/buildbot twcompat.py,1.2,1.3 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29450/buildbot Modified Files: twcompat.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-494 Creator: Brian Warner fix a number of incorrect names and missing imports [Anthony Baxter] * all: fix a number of incorrect names and missing imports, thanks to Anthony Baxter for the patch. * buildbot/status/html.py (WaterfallStatusResource.statusToHTML): remove unused buggy method. * buildbot/status/builder.py (BuildStatus.saveYourself): rmtree comes from shutil, not "shutils" * buildbot/process/step.py (TreeSize.evaluateCommand): fix bad name (Arch.checkSlaveVersion): same * buildbot/process/step_twisted.py (Trial.commandComplete): same, in some disabled code * buildbot/process/step_twisted2.py: add some missing imports * buildbot/twcompat.py (_deferGenerator): fix cut-and-paste error, this code used to live in twisted.internet.defer Index: twcompat.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/twcompat.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- twcompat.py 19 Jul 2005 01:55:21 -0000 1.2 +++ twcompat.py 16 Apr 2006 23:05:41 -0000 1.3 @@ -152,7 +152,7 @@ # they yield a Deferred. Perhaps eventually these semantics may # change. if isinstance(result, defer.Deferred): - return fail(TypeError("Yield waitForDeferred(d), not d!")) + return defer.fail(TypeError("Yield waitForDeferred(d), not d!")) if isinstance(result, waitForDeferred): waiting=[True, None] From warner at users.sourceforge.net Sun Apr 16 23:05:43 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Sun, 16 Apr 2006 23:05:43 +0000 Subject: [Buildbot-commits] buildbot/buildbot/process step_twisted2.py,1.2,1.3 step.py,1.81,1.82 step_twisted.py,1.72,1.73 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/process In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29450/buildbot/process Modified Files: step_twisted2.py step.py step_twisted.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-494 Creator: Brian Warner fix a number of incorrect names and missing imports [Anthony Baxter] * all: fix a number of incorrect names and missing imports, thanks to Anthony Baxter for the patch. * buildbot/status/html.py (WaterfallStatusResource.statusToHTML): remove unused buggy method. * buildbot/status/builder.py (BuildStatus.saveYourself): rmtree comes from shutil, not "shutils" * buildbot/process/step.py (TreeSize.evaluateCommand): fix bad name (Arch.checkSlaveVersion): same * buildbot/process/step_twisted.py (Trial.commandComplete): same, in some disabled code * buildbot/process/step_twisted2.py: add some missing imports * buildbot/twcompat.py (_deferGenerator): fix cut-and-paste error, this code used to live in twisted.internet.defer Index: step.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step.py,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- step.py 11 Apr 2006 06:12:59 -0000 1.81 +++ step.py 16 Apr 2006 23:05:40 -0000 1.82 @@ -917,7 +917,7 @@ return SUCCESS def getText(self, cmd, results): - if kb is not None: + if self.kb is not None: return ["treesize", "%d kb" % self.kb] return ["treesize", "unknown"] @@ -1572,7 +1572,7 @@ "buildbot-0.7.0 or newer." % (self.build.slavename, self.args['mode'])) log.msg(m) - raise BuildslaveError(m) + raise BuildSlaveTooOldError(m) return warnings Index: step_twisted.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step_twisted.py,v retrieving revision 1.72 retrieving revision 1.73 diff -u -d -r1.72 -r1.73 --- step_twisted.py 26 Oct 2005 20:38:07 -0000 1.72 +++ step_twisted.py 16 Apr 2006 23:05:40 -0000 1.73 @@ -483,7 +483,7 @@ counts['expectedFailures'] == 1 and "todo" or "todos")) if 0: # TODO - results = WARNING + results = WARNINGS if not text2: text2 = "todo" @@ -492,7 +492,7 @@ # the build WARNING if counts['unexpectedSuccesses']: text.append("%d surprises" % counts['unexpectedSuccesses']) - results = WARNING + results = WARNINGS if not text2: text2 = "tests" Index: step_twisted2.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step_twisted2.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- step_twisted2.py 17 May 2005 10:14:10 -0000 1.2 +++ step_twisted2.py 16 Apr 2006 23:05:40 -0000 1.3 @@ -8,8 +8,10 @@ from zope.interface import implements from twisted.python import log, failure from twisted.spread import jelly +from twisted.pb.tokens import BananaError from twisted.web.util import formatFailure from twisted.web.html import PRE +from twisted.web.error import NoResource class Null: pass ResultTypes = Null() From warner at users.sourceforge.net Mon Apr 17 18:11:45 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 18:11:45 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.591,1.592 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv688 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-496 Creator: Brian Warner add contrib/svnpoller.py and contrib/svn_watcher.py * contrib/svnpoller.py: added script by John Pye to poll a remote SVN repository (by running 'svn log') from a cronjob, and run 'buildbot sendchange' to deliver the changes to a remote buildmaster. * contrib/svn_watcher.py: added script by Niklaus Giger (a modification of svnpoller.py), same purpose, but this one loops internally (rather than expecting to run from a cronjob) and works under windows. * contrib/README.txt: same Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.591 retrieving revision 1.592 diff -u -d -r1.591 -r1.592 --- ChangeLog 16 Apr 2006 23:05:41 -0000 1.591 +++ ChangeLog 17 Apr 2006 18:11:43 -0000 1.592 @@ -1,3 +1,15 @@ +2006-04-17 Brian Warner + + * contrib/svnpoller.py: added script by John Pye to poll a remote + SVN repository (by running 'svn log') from a cronjob, and run + 'buildbot sendchange' to deliver the changes to a remote + buildmaster. + * contrib/svn_watcher.py: added script by Niklaus Giger (a + modification of svnpoller.py), same purpose, but this one loops + internally (rather than expecting to run from a cronjob) and works + under windows. + * contrib/README.txt: same + 2006-04-11 Brian Warner * all: fix a number of incorrect names and missing imports, thanks From warner at users.sourceforge.net Mon Apr 17 18:11:45 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 18:11:45 +0000 Subject: [Buildbot-commits] buildbot/contrib svnpoller.py,NONE,1.1 svn_watcher.py,NONE,1.1 README.txt,1.1,1.2 Message-ID: Update of /cvsroot/buildbot/buildbot/contrib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv688/contrib Modified Files: README.txt Added Files: svnpoller.py svn_watcher.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-496 Creator: Brian Warner add contrib/svnpoller.py and contrib/svn_watcher.py * contrib/svnpoller.py: added script by John Pye to poll a remote SVN repository (by running 'svn log') from a cronjob, and run 'buildbot sendchange' to deliver the changes to a remote buildmaster. * contrib/svn_watcher.py: added script by Niklaus Giger (a modification of svnpoller.py), same purpose, but this one loops internally (rather than expecting to run from a cronjob) and works under windows. * contrib/README.txt: same Index: README.txt =================================================================== RCS file: /cvsroot/buildbot/buildbot/contrib/README.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- README.txt 19 Jul 2004 18:37:59 -0000 1.1 +++ README.txt 17 Apr 2006 18:11:42 -0000 1.2 @@ -1,4 +1,5 @@ -Utility scripts: +Utility scripts, things contributed by users but not strictly a part of +buildbot: debugclient.py (and debug.*): debugging gui for buildbot @@ -9,3 +10,22 @@ svn_buildbot.py: a script intended to be run from a subversion hook-script which submits changes to svn (requires python 2.3) + +svnpoller.py: this script is intended to be run from a cronjob, and uses 'svn + log' to poll a (possibly remote) SVN repository for changes. + For each change it finds, it runs 'buildbot sendchange' to + deliver them to a waiting PBChangeSource on a (possibly remote) + buildmaster. Modify the svnurl to point at your own SVN + repository, and of course the user running the script must have + read permissions to that repository. It keeps track of the last + revision in a file, change 'fname' to set the location of this + state file. Modify the --master argument to the 'buildbot + sendchange' command to point at your buildmaster. Contributed + by John Pye. Note that if there are multiple changes within a + single polling interval, this will miss all but the last one. + +svn_watcher.py: adapted from svnpoller.py by Niklaus Giger to add options and + run under windows. Runs as a standalone script (it loops + internally rather than expecting to run from a cronjob), + polls an SVN repository every 10 minutes. It expects the + svnurl and buildmaster location as command-line arguments. --- NEW FILE: svn_watcher.py --- #!/usr/bin/python # This is a program which will poll a (remote) SVN repository, looking for # new revisions. It then uses the 'buildbot sendchange' command to deliver # information about the Change to a (remote) buildmaster. It can be run from # a cron job on a periodic basis, or can be told (with the 'watch' option) to # automatically repeat its check every 10 minutes. # This script does not store any state information, so to avoid spurious # changes you must use the 'watch' option and let it run forever. # You will need to provide it with the location of the buildmaster's # PBChangeSource port (in the form hostname:portnum), and the svnurl of the # repository to watch. # 15.03.06 by John Pye # 29.03.06 by Niklaus Giger, added support to run under windows, added invocation option import commands import xml.dom.minidom import sys import time import os if sys.platform == 'win32': import win32pipe def checkChanges(repo, master, verbose=False, oldRevision=-1): cmd ="svn log --non-interactive --xml --verbose --limit=1 "+repo if verbose == True: print "Getting last revision of repository: " + repo if sys.platform == 'win32': f = win32pipe.popen(cmd) xml1 = ''.join(f.readlines()) f.close() else: xml1 = commands.getoutput(cmd) if verbose == True: print "XML\n-----------\n"+xml1+"\n\n" doc = xml.dom.minidom.parseString(xml1) el = doc.getElementsByTagName("logentry")[0] revision = el.getAttribute("revision") author = "".join([t.data for t in el.getElementsByTagName("author")[0].childNodes]) comments = "".join([t.data for t in el.getElementsByTagName("msg")[0].childNodes]) pathlist = el.getElementsByTagName("paths")[0] paths = [] for p in pathlist.getElementsByTagName("path"): paths.append("".join([t.data for t in p.childNodes])) if verbose == True: print "PATHS" print paths if revision != oldRevision: cmd = "buildbot sendchange --master="+master+" --revision=\""+revision+"\" --username=\""+author+"\"--comments=\""+comments+"\" "+" ".join(paths) if verbose == True: print cmd if sys.platform == 'win32': f = win32pipe.popen(cmd) print time.strftime("%H.%M.%S ") + "Revision "+revision+ ": "+ ''.join(f.readlines()) f.close() else: xml1 = commands.getoutput(cmd) else: print time.strftime("%H.%M.%S ") + "nothing has changed since revision "+revision return revision if __name__ == '__main__': if len(sys.argv) == 4 and sys.argv[3] == 'watch': oldRevision = -1 print "Watching for changes in repo "+ sys.argv[1] + " master " + sys.argv[2] while 1: oldRevision = checkChanges(sys.argv[1], sys.argv[2], False, oldRevision) time.sleep(10*60) # Check the repository every 10 minutes elif len(sys.argv) == 3: checkChanges(sys.argv[1], sys.argv[2], True ) else: print os.path.basename(sys.argv[0]) + ": http://host/path/to/repo master:port [watch]" --- NEW FILE: svnpoller.py --- #!/usr/bin/python """ svn.py Script for BuildBot to monitor a remote Subversion repository. Copyright (C) 2006 John Pye """ # This script is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA import commands import xml.dom.minidom import ConfigParser import os.path import codecs # change these settings to match your project svnurl = "https://pse.cheme.cmu.edu/svn/ascend/code/trunk" statefilename = "~/changemonitor/config.ini" buildmaster = "buildbot.example.org:9989" # connects to a PBChangeSource xml1 = commands.getoutput("svn log --non-interactive --verbose --xml --limit=1 " + svnurl) #print "XML\n-----------\n"+xml1+"\n\n" try: doc = xml.dom.minidom.parseString(xml1) el = doc.getElementsByTagName("logentry")[0] revision = el.getAttribute("revision") author = "".join([t.data for t in el.getElementsByTagName("author")[0].childNodes]) comments = "".join([t.data for t in el.getElementsByTagName("msg")[0].childNodes]) pathlist = el.getElementsByTagName("paths")[0] paths = [] for p in pathlist.getElementsByTagName("path"): paths.append("".join([t.data for t in p.childNodes])) #print "PATHS" #print paths except xml.parsers.expat.ExpatError, e: print "FAILED TO PARSE 'svn log' XML:" print str(e) print "----" print "RECEIVED TEXT:" print xml1 import sys sys.exit(1) fname = statefilename fname = os.path.expanduser(fname) ini = ConfigParser.SafeConfigParser() try: ini.read(fname) except: print "Creating changemonitor config.ini:",fname ini.add_section("CurrentRevision") ini.set("CurrentRevision",-1) try: lastrevision = ini.get("CurrentRevision","changeset") except ConfigParser.NoOptionError: print "NO OPTION FOUND" lastrevision = -1 except ConfigParser.NoSectionError: print "NO SECTION FOUND" lastrevision = -1 if lastrevision != revision: #comments = codecs.encodings.unicode_escape.encode(comments) cmd = "buildbot sendchange --master="+buildmaster+" --branch=trunk --revision=\""+revision+"\" --username=\""+author+"\" --comments=\""+comments+"\" "+" ".join(paths) #print cmd res = commands.getoutput(cmd) print "SUBMITTING NEW REVISION",revision if not ini.has_section("CurrentRevision"): ini.add_section("CurrentRevision") try: ini.set("CurrentRevision","changeset",revision) f = open(fname,"w") ini.write(f) #print "WROTE CHANGES TO",fname except: print "FAILED TO RECORD INI FILE" From warner at users.sourceforge.net Mon Apr 17 18:31:43 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 18:31:43 +0000 Subject: [Buildbot-commits] buildbot/contrib viewcvspoll.py,NONE,1.1 README.txt,1.2,1.3 Message-ID: Update of /cvsroot/buildbot/buildbot/contrib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16215/contrib Modified Files: README.txt Added Files: viewcvspoll.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-498 Creator: Brian Warner added contrib/viewcvspoll.py * contrib/viewcvspoll.py: script to poll a viewcvs database for changes, then deliver them over PB to a remote buildmaster. Index: README.txt =================================================================== RCS file: /cvsroot/buildbot/buildbot/contrib/README.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- README.txt 17 Apr 2006 18:11:42 -0000 1.2 +++ README.txt 17 Apr 2006 18:31:41 -0000 1.3 @@ -29,3 +29,9 @@ internally rather than expecting to run from a cronjob), polls an SVN repository every 10 minutes. It expects the svnurl and buildmaster location as command-line arguments. + +viewcvspoll.py: a standalone script which loops every 60 seconds and polls a + (local?) MySQL database (presumably maintained by ViewCVS?) + for information about new CVS changes, then delivers them + over PB to a remote buildmaster's PBChangeSource. Contributed + by Stephen Kennedy. --- NEW FILE: viewcvspoll.py --- #! /usr/bin/python """Based on the fakechanges.py contrib script""" import sys from twisted.spread import pb from twisted.cred import credentials from twisted.internet import reactor, task from twisted.python import log import commands, random, os.path, time, MySQLdb class ViewCvsPoller: def __init__(self): def _load_rc(): import user ret = {} for line in open(os.path.join(user.home,".cvsblamerc")).readlines(): if line.find("=") != -1: key, val = line.split("=") ret[key.strip()] = val.strip() return ret # maybe add your own keys here db=xxx, user=xxx, passwd=xxx self.cvsdb = MySQLdb.connect("cvs", **_load_rc()) #self.last_checkin = "2005-05-11" # for testing self.last_checkin = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) def get_changes(self): changes = [] def empty_change(): return {'who': None, 'files': [], 'comments': None } change = empty_change() cursor = self.cvsdb.cursor() cursor.execute("""SELECT whoid, descid, fileid, dirid, branchid, ci_when FROM checkins WHERE ci_when>='%s'""" % self.last_checkin) last_checkin = None for whoid, descid, fileid, dirid, branchid, ci_when in cursor.fetchall(): if branchid != 1: # only head continue cursor.execute("""SELECT who from people where id=%s""" % whoid) who = cursor.fetchone()[0] cursor.execute("""SELECT description from descs where id=%s""" % descid) desc = cursor.fetchone()[0] cursor.execute("""SELECT file from files where id=%s""" % fileid) filename = cursor.fetchone()[0] cursor.execute("""SELECT dir from dirs where id=%s""" % dirid) dirname = cursor.fetchone()[0] if who == change["who"] and desc == change["comments"]: change["files"].append( "%s/%s" % (dirname, filename) ) elif change["who"]: changes.append(change) change = empty_change() else: change["who"] = who change["files"].append( "%s/%s" % (dirname, filename) ) change["comments"] = desc if last_checkin == None or ci_when > last_checkin: last_checkin = ci_when if last_checkin: self.last_checkin = last_checkin return changes poller = ViewCvsPoller() def error(*args): log.err() reactor.stop() def poll_changes(remote): print "GET CHANGES SINCE", poller.last_checkin, changes = poller.get_changes() for change in changes: print change["who"], "\n *", "\n * ".join(change["files"]) remote.callRemote('addChange', change).addErrback(error) print reactor.callLater(60, poll_changes, remote) factory = pb.PBClientFactory() reactor.connectTCP("localhost", 9999, factory ) deferred = factory.login(credentials.UsernamePassword("change", "changepw")) deferred.addCallback(poll_changes).addErrback(error) reactor.run() From warner at users.sourceforge.net Mon Apr 17 18:31:43 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 18:31:43 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.592,1.593 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16215 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-498 Creator: Brian Warner added contrib/viewcvspoll.py * contrib/viewcvspoll.py: script to poll a viewcvs database for changes, then deliver them over PB to a remote buildmaster. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.592 retrieving revision 1.593 diff -u -d -r1.592 -r1.593 --- ChangeLog 17 Apr 2006 18:11:43 -0000 1.592 +++ ChangeLog 17 Apr 2006 18:31:40 -0000 1.593 @@ -1,5 +1,8 @@ 2006-04-17 Brian Warner + * contrib/viewcvspoll.py: script to poll a viewcvs database for + changes, then deliver them over PB to a remote buildmaster. + * contrib/svnpoller.py: added script by John Pye to poll a remote SVN repository (by running 'svn log') from a cronjob, and run 'buildbot sendchange' to deliver the changes to a remote From warner at users.sourceforge.net Mon Apr 17 19:22:36 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 19:22:36 +0000 Subject: [Buildbot-commits] buildbot/buildbot/status builder.py,1.77,1.78 mail.py,1.23,1.24 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/status In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23634/buildbot/status Modified Files: builder.py mail.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-500 Creator: Brian Warner fix process_twisted.py factories, other style changes * all: use isinstance() instead of 'type(x) is foo', suggested by Neal Norwitz * buildbot/process/process_twisted.py (QuickTwistedBuildFactory): oops, fix a brain-fade from the other week, when making the addStep changes. I changed all the __init__ upcalls to use the wrong superclass name. (FullTwistedBuildFactory.__init__): same (TwistedDebsBuildFactory.__init__): same (TwistedReactorsBuildFactory.__init__): same (TwistedBuild.isFileImportant): use .startswith for clarity, thanks to Neal Norwitz for the suggestions. Index: builder.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/status/builder.py,v retrieving revision 1.77 retrieving revision 1.78 diff -u -d -r1.77 -r1.78 --- builder.py 16 Apr 2006 23:05:41 -0000 1.77 +++ builder.py 17 Apr 2006 19:22:34 -0000 1.78 @@ -539,7 +539,7 @@ __implements__ = interfaces.ITestResult, def __init__(self, name, results, text, logs): - assert type(name) is tuple + assert isinstance(name, tuple) self.name = name self.results = results self.text = text @@ -1115,7 +1115,7 @@ self.slavename = slavename def setText(self, text): - assert type(text) in (list, tuple) + assert isinstance(text, (list, tuple)) self.text = text def setColor(self, color): self.color = color Index: mail.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/status/mail.py,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- mail.py 15 Nov 2005 08:41:21 -0000 1.23 +++ mail.py 17 Apr 2006 19:22:34 -0000 1.24 @@ -140,9 +140,9 @@ """ base.StatusReceiverMultiService.__init__(self) - assert type(extraRecipients) in (list, tuple) + assert isinstance(extraRecipients, (list, tuple)) for r in extraRecipients: - assert type(r) is str + assert isinstance(r, str) assert "@" in r # require full email addresses, not User names self.extraRecipients = extraRecipients self.sendToInterestedUsers = sendToInterestedUsers From warner at users.sourceforge.net Mon Apr 17 19:22:36 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 19:22:36 +0000 Subject: [Buildbot-commits] buildbot/buildbot/process factory.py,1.12,1.13 step.py,1.82,1.83 builder.py,1.35,1.36 process_twisted.py,1.42,1.43 step_twisted.py,1.73,1.74 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/process In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23634/buildbot/process Modified Files: factory.py step.py builder.py process_twisted.py step_twisted.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-500 Creator: Brian Warner fix process_twisted.py factories, other style changes * all: use isinstance() instead of 'type(x) is foo', suggested by Neal Norwitz * buildbot/process/process_twisted.py (QuickTwistedBuildFactory): oops, fix a brain-fade from the other week, when making the addStep changes. I changed all the __init__ upcalls to use the wrong superclass name. (FullTwistedBuildFactory.__init__): same (TwistedDebsBuildFactory.__init__): same (TwistedReactorsBuildFactory.__init__): same (TwistedBuild.isFileImportant): use .startswith for clarity, thanks to Neal Norwitz for the suggestions. Index: builder.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/builder.py,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- builder.py 12 Mar 2006 11:28:04 -0000 1.35 +++ builder.py 17 Apr 2006 19:22:34 -0000 1.36 @@ -61,7 +61,7 @@ return self def _attachFailure(self, why, where): - assert type(where) is str + assert isinstance(where, str) log.msg(where) log.err(why) return why Index: factory.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/factory.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- factory.py 7 Apr 2006 04:10:56 -0000 1.12 +++ factory.py 17 Apr 2006 19:22:33 -0000 1.13 @@ -45,7 +45,7 @@ configureFlags=[], compile=["make", "all"], test=["make", "check"]): - assert type(source) is tuple + assert isinstance(source, tuple) assert issubclass(source[0], step.BuildStep) BuildFactory.__init__(self, [source]) if configure is not None: @@ -59,7 +59,7 @@ else: command = configure else: - assert type(configure) in (list, tuple) + assert isinstance(configure, (list, tuple)) command = configure + configureFlags self.addStep(step.Configure, command=command, env=configureEnv) if compile is not None: @@ -69,7 +69,7 @@ class CPAN(BuildFactory): def __init__(self, source, perl="perl"): - assert type(source) is tuple + assert isinstance(source, tuple) assert issubclass(source[0], step.BuildStep) BuildFactory.__init__(self, [source]) self.addStep(step.Configure, command=[perl, "Makefile.PL"]) @@ -78,7 +78,7 @@ class Distutils(BuildFactory): def __init__(self, source, python="python", test=None): - assert type(source) is tuple + assert isinstance(source, tuple) assert issubclass(source[0], step.BuildStep) BuildFactory.__init__(self, [source]) self.addStep(step.Compile, command=[python, "./setup.py", "build"]) @@ -105,7 +105,7 @@ testpath=".", randomly=None, recurse=None, tests=None, useTestCaseNames=False, env=None): BuildFactory.__init__(self, [source]) - assert type(source) is tuple + assert isinstance(source, tuple) assert issubclass(source[0], step.BuildStep) assert tests or useTestCaseNames, "must use one or the other" if trial is not None: Index: process_twisted.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/process_twisted.py,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- process_twisted.py 7 Apr 2006 04:10:57 -0000 1.42 +++ process_twisted.py 17 Apr 2006 19:22:34 -0000 1.43 @@ -11,9 +11,9 @@ class TwistedBuild(Build): workdir = "Twisted" # twisted's bin/trial expects to live in here def isFileImportant(self, filename): - if filename.find("doc/fun/") == 0: + if filename.startswith("doc/fun/") == 0: return 0 - if filename.find("sandbox/") == 0: + if filename.startswith("sandbox/") == 0: return 0 return 1 @@ -40,7 +40,7 @@ useProgress = 0 def __init__(self, source, python="python"): - TwistedBuildFactory.__init__(self, source) + TwistedBaseFactory.__init__(self, source) if type(python) is str: python = [python] self.addStep(HLint, python=python[0]) @@ -56,14 +56,14 @@ def __init__(self, source, python="python", processDocs=False, runTestsRandomly=False, compileOpts=[], compileOpts2=[]): - TwistedBuildFactory.__init__(self, source) + TwistedBaseFactory.__init__(self, source) if processDocs: self.addStep(ProcessDocs) if type(python) == str: python = [python] - assert type(compileOpts) is list - assert type(compileOpts2) is list + assert isinstance(compileOpts, list) + assert isinstance(compileOpts2, list) cmd = (python + compileOpts + ["setup.py", "all", "build_ext"] + compileOpts2 + ["-i"]) @@ -75,7 +75,7 @@ treeStableTimer = 10*60 def __init__(self, source, python="python"): - TwistedBuildFactory.__init__(self, source) + TwistedBaseFactory.__init__(self, source) self.addStep(ProcessDocs, haltOnFailure=True) self.addStep(BuildDebs, warnOnWarnings=True) @@ -85,12 +85,12 @@ def __init__(self, source, python="python", compileOpts=[], compileOpts2=[], reactors=None): - TwistedBuildFactory.__init__(self, source) + TwistedBaseFactory.__init__(self, source) if type(python) == str: python = [python] - assert type(compileOpts) is list - assert type(compileOpts2) is list + assert isinstance(compileOpts, list) + assert isinstance(compileOpts2, list) cmd = (python + compileOpts + ["setup.py", "all", "build_ext"] + compileOpts2 + ["-i"]) Index: step.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step.py,v retrieving revision 1.82 retrieving revision 1.83 diff -u -d -r1.82 -r1.83 --- step.py 16 Apr 2006 23:05:40 -0000 1.82 +++ step.py 17 Apr 2006 19:22:33 -0000 1.83 @@ -1022,7 +1022,7 @@ assert mode in ("update", "copy", "clobber", "export") if retry: delay, repeats = retry - assert type(repeats) is int + assert isinstance(repeats, int) assert repeats > 0 self.args = {'mode': mode, 'workdir': workdir, Index: step_twisted.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step_twisted.py,v retrieving revision 1.73 retrieving revision 1.74 diff -u -d -r1.73 -r1.74 --- step_twisted.py 16 Apr 2006 23:05:40 -0000 1.73 +++ step_twisted.py 17 Apr 2006 19:22:34 -0000 1.74 @@ -323,7 +323,7 @@ self.testpath = testpath if self.testpath is UNSPECIFIED: raise ValueError("You must specify testpath= (it can be None)") - assert type(self.testpath) is str or self.testpath is None + assert isinstance(self.testpath, str) or self.testpath is None if reactor is not UNSPECIFIED: self.reactor = reactor From warner at users.sourceforge.net Mon Apr 17 19:22:36 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 19:22:36 +0000 Subject: [Buildbot-commits] buildbot/buildbot scheduler.py,1.15,1.16 master.py,1.91,1.92 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23634/buildbot Modified Files: scheduler.py master.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-500 Creator: Brian Warner fix process_twisted.py factories, other style changes * all: use isinstance() instead of 'type(x) is foo', suggested by Neal Norwitz * buildbot/process/process_twisted.py (QuickTwistedBuildFactory): oops, fix a brain-fade from the other week, when making the addStep changes. I changed all the __init__ upcalls to use the wrong superclass name. (FullTwistedBuildFactory.__init__): same (TwistedDebsBuildFactory.__init__): same (TwistedReactorsBuildFactory.__init__): same (TwistedBuild.isFileImportant): use .startswith for clarity, thanks to Neal Norwitz for the suggestions. Index: master.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/master.py,v retrieving revision 1.91 retrieving revision 1.92 diff -u -d -r1.91 -r1.92 --- master.py 13 Jan 2006 08:34:28 -0000 1.91 +++ master.py 17 Apr 2006 19:22:34 -0000 1.92 @@ -746,15 +746,15 @@ if config.has_key('interlocks'): raise KeyError("c['interlocks'] is no longer accepted") - assert type(sources) in (list, tuple) + assert isinstance(sources, (list, tuple)) for s in sources: assert interfaces.IChangeSource(s, None) # this assertion catches c['schedulers'] = Scheduler(), since # Schedulers are service.MultiServices and thus iterable. - assert type(schedulers) in (list, tuple) + assert isinstance(schedulers, (list, tuple)) for s in schedulers: assert interfaces.IScheduler(s, None) - assert type(status) in (list, tuple) + assert isinstance(status, (list, tuple)) for s in status: assert interfaces.IStatusReceiver(s, None) Index: scheduler.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/scheduler.py,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- scheduler.py 12 Mar 2006 11:28:04 -0000 1.15 +++ scheduler.py 17 Apr 2006 19:22:34 -0000 1.16 @@ -108,7 +108,7 @@ BaseUpstreamScheduler.__init__(self, name) self.treeStableTimer = treeStableTimer for b in builderNames: - assert type(b) is str + assert isinstance(b, str) self.builderNames = builderNames self.branch = branch if fileIsImportant: @@ -225,7 +225,7 @@ BaseUpstreamScheduler.__init__(self, name) self.treeStableTimer = treeStableTimer for b in builderNames: - assert type(b) is str + assert isinstance(b, str) self.builderNames = builderNames self.branches = branches if self.branches == []: From warner at users.sourceforge.net Mon Apr 17 19:22:36 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 19:22:36 +0000 Subject: [Buildbot-commits] buildbot/buildbot/slave commands.py,1.43,1.44 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/slave In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23634/buildbot/slave Modified Files: commands.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-500 Creator: Brian Warner fix process_twisted.py factories, other style changes * all: use isinstance() instead of 'type(x) is foo', suggested by Neal Norwitz * buildbot/process/process_twisted.py (QuickTwistedBuildFactory): oops, fix a brain-fade from the other week, when making the addStep changes. I changed all the __init__ upcalls to use the wrong superclass name. (FullTwistedBuildFactory.__init__): same (TwistedDebsBuildFactory.__init__): same (TwistedReactorsBuildFactory.__init__): same (TwistedBuild.isFileImportant): use .startswith for clarity, thanks to Neal Norwitz for the suggestions. Index: commands.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/slave/commands.py,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- commands.py 11 Apr 2006 06:48:26 -0000 1.43 +++ commands.py 17 Apr 2006 19:22:34 -0000 1.44 @@ -484,7 +484,7 @@ if type(rc) is not int: log.msg("weird, _abandonOnFailure was given rc=%s (%s)" % \ (rc, type(rc))) - assert type(rc) is int + assert isinstance(rc, int) if rc != 0: raise AbandonChain(rc) return rc From warner at users.sourceforge.net Mon Apr 17 19:22:36 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 19:22:36 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.593,1.594 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23634 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-500 Creator: Brian Warner fix process_twisted.py factories, other style changes * all: use isinstance() instead of 'type(x) is foo', suggested by Neal Norwitz * buildbot/process/process_twisted.py (QuickTwistedBuildFactory): oops, fix a brain-fade from the other week, when making the addStep changes. I changed all the __init__ upcalls to use the wrong superclass name. (FullTwistedBuildFactory.__init__): same (TwistedDebsBuildFactory.__init__): same (TwistedReactorsBuildFactory.__init__): same (TwistedBuild.isFileImportant): use .startswith for clarity, thanks to Neal Norwitz for the suggestions. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.593 retrieving revision 1.594 diff -u -d -r1.593 -r1.594 --- ChangeLog 17 Apr 2006 18:31:40 -0000 1.593 +++ ChangeLog 17 Apr 2006 19:22:34 -0000 1.594 @@ -1,5 +1,18 @@ 2006-04-17 Brian Warner + * all: use isinstance() instead of 'type(x) is foo', suggested by + Neal Norwitz + + * buildbot/process/process_twisted.py (QuickTwistedBuildFactory): + oops, fix a brain-fade from the other week, when making the + addStep changes. I changed all the __init__ upcalls to use the + wrong superclass name. + (FullTwistedBuildFactory.__init__): same + (TwistedDebsBuildFactory.__init__): same + (TwistedReactorsBuildFactory.__init__): same + (TwistedBuild.isFileImportant): use .startswith for clarity, + thanks to Neal Norwitz for the suggestions. + * contrib/viewcvspoll.py: script to poll a viewcvs database for changes, then deliver them over PB to a remote buildmaster. From warner at users.sourceforge.net Mon Apr 17 20:43:48 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 20:43:48 +0000 Subject: [Buildbot-commits] buildbot/buildbot twcompat.py,1.3,1.4 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21569/buildbot Modified Files: twcompat.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-502 Creator: Brian Warner handle SkipTest properly under Twisted-1.3.0 * buildbot/twcompat.py (maybeWait): handle SkipTest properly when running under Twisted-1.3.0, otherwise skipped tests are reported as errors. Index: twcompat.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/twcompat.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- twcompat.py 16 Apr 2006 23:05:41 -0000 1.3 +++ twcompat.py 17 Apr 2006 20:43:46 -0000 1.4 @@ -45,15 +45,21 @@ # use this at the end of setUp/testFoo/tearDown methods def maybeWait(d, timeout="none"): + from twisted.python import failure from twisted.trial import unittest if oldtrial: # this is required for oldtrial (twisted-1.3.0) compatibility. When we # move to retrial (twisted-2.0.0), replace these with a simple 'return # d'. - if timeout == "none": - unittest.deferredResult(d) - else: - unittest.deferredResult(d, timeout) + try: + if timeout == "none": + unittest.deferredResult(d) + else: + unittest.deferredResult(d, timeout) + except failure.Failure, f: + if f.check(unittest.SkipTest): + raise f.value + raise return None return d From warner at users.sourceforge.net Mon Apr 17 20:43:48 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 17 Apr 2006 20:43:48 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.594,1.595 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21569 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-502 Creator: Brian Warner handle SkipTest properly under Twisted-1.3.0 * buildbot/twcompat.py (maybeWait): handle SkipTest properly when running under Twisted-1.3.0, otherwise skipped tests are reported as errors. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.594 retrieving revision 1.595 diff -u -d -r1.594 -r1.595 --- ChangeLog 17 Apr 2006 19:22:34 -0000 1.594 +++ ChangeLog 17 Apr 2006 20:43:46 -0000 1.595 @@ -1,5 +1,9 @@ 2006-04-17 Brian Warner + * buildbot/twcompat.py (maybeWait): handle SkipTest properly when + running under Twisted-1.3.0, otherwise skipped tests are reported + as errors. + * all: use isinstance() instead of 'type(x) is foo', suggested by Neal Norwitz From warner at users.sourceforge.net Tue Apr 18 07:48:00 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 18 Apr 2006 07:48:00 +0000 Subject: [Buildbot-commits] buildbot/docs buildbot.texinfo,1.43,1.44 Message-ID: Update of /cvsroot/buildbot/buildbot/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16807/docs Modified Files: buildbot.texinfo Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-504 Creator: Brian Warner docs: improve the cross-references between PBListener and statusgui * docs/buildbot.texinfo (PBListener): improve cross-references between PBListener and 'buildbot statusgui', thanks to John Pye for the suggestion. Index: buildbot.texinfo =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- buildbot.texinfo 11 Apr 2006 06:12:59 -0000 1.43 +++ buildbot.texinfo 18 Apr 2006 07:47:58 -0000 1.44 @@ -3837,13 +3837,18 @@ @cindex PBListener - at code{buildbot.status.client.PBListener(port=int, user=str, -passwd=str)} + at example +import buildbot.status.client +pbl = buildbot.status.client.PBListener(port=int, user=str, + passwd=str) +c['status'].append(pbl) + at end example This sets up a PB listener on the given TCP port, to which a PB-based status client can connect and retrieve status information. - at code{buildbot statusgui} is an example of such a status client. The - at code{port} argument can also be a strports specification string. + at code{buildbot statusgui} (@pxref{statusgui}) is an example of such a +status client. The @code{port} argument can also be a strports +specification string. @node Command-line tool, Resources, Status Delivery, Top @chapter Command-line tool @@ -3952,6 +3957,12 @@ @node statusgui, try, statuslog, Developer Tools @subsection statusgui + at cindex statusgui + +If you have set up a PBListener (@pxref{PBListener}), you will be able +to monitor your Buildbot using a simple Gtk+ application invoked with +the @code{buildbot statusgui} command: + @example buildbot statusgui --master @var{MASTERHOST}:@var{PORT} @end example From warner at users.sourceforge.net Tue Apr 18 07:48:00 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Tue, 18 Apr 2006 07:48:00 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.595,1.596 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16807 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-504 Creator: Brian Warner docs: improve the cross-references between PBListener and statusgui * docs/buildbot.texinfo (PBListener): improve cross-references between PBListener and 'buildbot statusgui', thanks to John Pye for the suggestion. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.595 retrieving revision 1.596 diff -u -d -r1.595 -r1.596 --- ChangeLog 17 Apr 2006 20:43:46 -0000 1.595 +++ ChangeLog 18 Apr 2006 07:47:58 -0000 1.596 @@ -1,3 +1,9 @@ +2006-04-18 Brian Warner + + * docs/buildbot.texinfo (PBListener): improve cross-references + between PBListener and 'buildbot statusgui', thanks to John Pye + for the suggestion. + 2006-04-17 Brian Warner * buildbot/twcompat.py (maybeWait): handle SkipTest properly when From warner at users.sourceforge.net Mon Apr 24 06:45:38 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:38 +0000 Subject: [Buildbot-commits] buildbot/buildbot interfaces.py,1.39,1.40 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/buildbot Modified Files: interfaces.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506 Creator: Brian Warner add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * buildbot/test/test_vc.py: rename testBranch to testCheckoutBranch to keep the tests in about the right alphabetical order Index: interfaces.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/interfaces.py,v retrieving revision 1.39 retrieving revision 1.40 diff -u -d -r1.39 -r1.40 --- interfaces.py 27 Nov 2005 00:46:13 -0000 1.39 +++ interfaces.py 24 Apr 2006 06:45:36 -0000 1.40 @@ -296,6 +296,8 @@ build has already finished, this deferred will fire right away. The callback is given this IBuildStatus instance as an argument.""" + def getProperty(propname): + """Return the value of the build property with the given name.""" def getReason(): """Return a string that indicates why the build was run. 'changes', From warner at users.sourceforge.net Mon Apr 24 06:45:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:39 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.596,1.597 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506 Creator: Brian Warner add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * buildbot/test/test_vc.py: rename testBranch to testCheckoutBranch to keep the tests in about the right alphabetical order Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.596 retrieving revision 1.597 diff -u -d -r1.596 -r1.597 --- ChangeLog 18 Apr 2006 07:47:58 -0000 1.596 +++ ChangeLog 24 Apr 2006 06:45:37 -0000 1.597 @@ -1,3 +1,69 @@ +2006-04-23 Brian Warner + + * 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 + + * buildbot/test/test_vc.py: rename testBranch to + testCheckoutBranch to keep the tests in about the right + alphabetical order + 2006-04-18 Brian Warner * docs/buildbot.texinfo (PBListener): improve cross-references From warner at users.sourceforge.net Mon Apr 24 06:45:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:39 +0000 Subject: [Buildbot-commits] buildbot/buildbot/slave commands.py,1.44,1.45 Message-ID: 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 add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * 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) From warner at users.sourceforge.net Mon Apr 24 06:45:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:39 +0000 Subject: [Buildbot-commits] buildbot/docs buildbot.texinfo,1.44,1.45 Message-ID: Update of /cvsroot/buildbot/buildbot/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/docs Modified Files: buildbot.texinfo Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506 Creator: Brian Warner add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * buildbot/test/test_vc.py: rename testBranch to testCheckoutBranch to keep the tests in about the right alphabetical order Index: buildbot.texinfo =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- buildbot.texinfo 18 Apr 2006 07:47:58 -0000 1.44 +++ buildbot.texinfo 24 Apr 2006 06:45:37 -0000 1.45 @@ -157,6 +157,8 @@ * Configure:: * Compile:: * Test:: +* Writing New BuildSteps:: +* Build Properties:: Build Factories @@ -3013,6 +3015,8 @@ * Configure:: * Compile:: * Test:: +* Writing New BuildSteps:: +* Build Properties:: @end menu @node Configure, Compile, Simple ShellCommand Subclasses, Simple ShellCommand Subclasses @@ -3032,12 +3036,171 @@ created with any problems that were seen (TODO: the summary is not yet created). - at node Test, , Compile, Simple ShellCommand Subclasses + at node Test, Writing New BuildSteps, Compile, Simple ShellCommand Subclasses @subsubsection Test This is meant to handle unit tests. The default command is @code{make test}, and the @code{warnOnFailure} flag is set. + + + + + at node Writing New BuildSteps, Build Properties, Test, Simple ShellCommand Subclasses + at subsubsection Writing New BuildSteps + +While it is a good idea to keep your build process self-contained in +the source code tree, sometimes it is convenient to put more +intelligence into your Buildbot configuration. One was to do this is +to write a custom BuildStep. Once written, this Step can be used in +the @file{master.cfg} file. + +The best reason for writing a custom BuildStep is to better parse the +results of the command being run. For example, a BuildStep that knows +about JUnit could look at the logfiles to determine which tests had +been run, how many passed and how many failed, and then report more +detailed information than a simple @code{rc==0} -based ``good/bad'' +decision. + +TODO: add more description of BuildSteps. + + + at node Build Properties, , Writing New BuildSteps, Simple ShellCommand Subclasses + at subsubsection Build Properties + + at cindex build properties + +Each build has a set of ``Build Properties'', which can be used by its +BuildStep to modify their actions. For example, the SVN revision +number of the source code being built is available as a build +property, and a ShellCommand step could incorporate this number into a +command which create a numbered release tarball. + +Some build properties are set when the build starts, such as the +SourceStamp information. Other properties can be set by BuildSteps as +they run, for example the various Source steps will set the + at code{got_revision} property to the source revision that was actually +checked out (which can be useful when the SourceStamp in use merely +requested the ``latest revision'': @code{got_revision} will tell you +what was actually built). + +In custom BuildSteps, you can get and set the build properties with +the @code{getProperty}/@code{setProperty} methods. Each takes a string +for the name of the property, and returns or accepts an +arbitrary at footnote{Build properties are serialized along with the +build results, so they must be serializable. For this reason, the +value of any build property should be simple inert data: strings, +numbers, lists, tuples, and dictionaries. They should not include +class instances.} object. For example: + + at example +class MakeTarball(step.ShellCommand): + def start(self): + self.setCommand(["tar", "czf", + "build-%s.tar.gz" % self.getProperty("revision"), + "source"]) + step.ShellCommand.start(self) + at end example + + at cindex WithProperties + +You can use build properties in ShellCommands by using the + at code{WithProperties} wrapper when setting the arguments of the +ShellCommand. This interpolates the named build properties into the +generated shell command. + + at example +from buildbot.process.step import ShellCommand, WithProperties + +s(ShellCommand, + command=["tar", "czf", + WithProperties("build-%s.tar.gz", "revision"), + "source"], + ) + at end example + +If this BuildStep were used in a tree obtained from Subversion, it +would create a tarball with a name like @file{build-1234.tar.gz}. + +The @code{WithProperties} function does @code{printf}-style string +interpolation, using strings obtained by calling + at code{build.getProperty(propname)}. You can also use python +dictionary-style string interpolation by using the @code{%(propname)s} +syntax: + + at example +s(ShellCommand, + command=["tar", "czf", + WithProperties("build-%(revision)s.tar.gz"), + "source"], + ) + at end example + +Note that, like python, you can either do positional-argument +interpolation @emph{or} keyword-argument interpolation, not both. Thus +you cannot use a string like + at code{WithProperties("foo-%(revision)s-%s", "branch")}. + +At the moment, the only way to set build properties is by writing a +custom BuildStep. + + at heading Common Build Properties + +The following build properties are set when the build is started, and +are available to all steps. + + at table @code + at item branch + +This comes from the build's SourceStamp, and describes which branch is +being checked out. This will be @code{None} (which interpolates into + at code{WithProperties} as an empty string) if the build is on the +default branch, which is generally the trunk. Otherwise it will be a +string like ``branches/beta1.4''. The exact syntax depends upon the VC +system being used. + + at item revision + +This also comes from the SourceStamp, and is the revision of the +source code tree that was requested from the VC system. When a build +is requested of a specific revision (as is generally the case when the +build is triggered by Changes), this will contain the revision +specification. The syntax depends upon the VC system in use: for SVN +it is an integer, for Mercurial it is a short string, for Darcs it is +a rather large string, etc. + +If the ``force build'' button was pressed, the revision will be + at code{None}, which means to use the most recent revision available. +This is a ``trunk build''. This will be interpolated as an empty +string. + + at item got_revision + +This is set when a Source 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 @code{revision}, except for +trunk builds, where @code{got_revision} indicates what revision was +current when the checkout was performed. This can be used to rebuild +the same source code later. + +Note that for some VC systems (Darcs in particular), the revision is a +large string containing newlines, and is not suitable for +interpolation into a filename. + + at item slavename + +This is a string which identifies which buildslave the build is +running on. + + at item buildnumber + +Each build gets a number, scoped to the Builder (so the first build +performed on any given Builder will have a build number of 0). This +integer property contains the build's number. + + at end table + + @node Interlocks, Build Factories, Build Steps, Build Process @section Interlocks From warner at users.sourceforge.net Mon Apr 24 06:45:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:39 +0000 Subject: [Buildbot-commits] buildbot/buildbot/status builder.py,1.78,1.79 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/status In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/buildbot/status Modified Files: builder.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506 Creator: Brian Warner add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * buildbot/test/test_vc.py: rename testBranch to testCheckoutBranch to keep the tests in about the right alphabetical order Index: builder.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/status/builder.py,v retrieving revision 1.78 retrieving revision 1.79 diff -u -d -r1.78 -r1.79 --- builder.py 17 Apr 2006 19:22:34 -0000 1.78 +++ builder.py 24 Apr 2006 06:45:37 -0000 1.79 @@ -907,7 +907,7 @@ implements(interfaces.IBuildStatus, interfaces.IStatusEvent) else: __implements__ = interfaces.IBuildStatus, interfaces.IStatusEvent - persistenceVersion = 1 + persistenceVersion = 2 source = None reason = None @@ -943,6 +943,7 @@ self.finishedWatchers = [] self.steps = [] self.testResults = {} + self.properties = {} # IBuildStatus @@ -952,6 +953,9 @@ """ return self.builder + def getProperty(self, propname): + return self.properties[propname] + def getNumber(self): return self.number @@ -1088,6 +1092,9 @@ step.step_status = s self.steps.append(s) + def setProperty(self, propname, value): + self.properties[propname] = value + def addTestResult(self, result): self.testResults[result.getName()] = result @@ -1237,6 +1244,9 @@ self.changes = source.changes del self.sourceStamp + def upgradeToVersion2(self): + self.properties = {} + def upgradeLogfiles(self): # upgrade any LogFiles that need it. This must occur after we've been # attached to our Builder, and after we know about all LogFiles of From warner at users.sourceforge.net Mon Apr 24 06:45:38 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:38 +0000 Subject: [Buildbot-commits] buildbot/buildbot/test test_properties.py,NONE,1.1 test_vc.py,1.47,1.48 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/buildbot/test Modified Files: test_vc.py Added Files: test_properties.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506 Creator: Brian Warner add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * buildbot/test/test_vc.py: rename testBranch to testCheckoutBranch to keep the tests in about the right alphabetical order --- NEW FILE: test_properties.py --- # -*- test-case-name: buildbot.test.test_properties -*- import os from twisted.trial import unittest from buildbot.sourcestamp import SourceStamp from buildbot.process import base from buildbot.process.step import ShellCommand, WithProperties from buildbot.status import builder from buildbot.slave.commands import rmdirRecursive class MyBuildStep(ShellCommand): def _interpolateProperties(self, command): command = ["tar", "czf", "build-%s.tar.gz" % self.getProperty("revision"), "source"] return ShellCommand._interpolateProperties(self, command) class FakeBuild: pass class FakeBuilder: statusbag = None name = "fakebuilder" class FakeSlave: slavename = "bot12" class FakeSlaveBuilder: slave = FakeSlave() def getSlaveCommandVersion(self, command, oldversion=None): return "1.10" class Interpolate(unittest.TestCase): def setUp(self): self.builder = FakeBuilder() self.builder_status = builder.BuilderStatus("fakebuilder") self.builder_status.basedir = "test_properties" self.builder_status.nextBuildNumber = 0 rmdirRecursive(self.builder_status.basedir) os.mkdir(self.builder_status.basedir) self.build_status = self.builder_status.newBuild() req = base.BuildRequest("reason", SourceStamp(branch="branch2", revision=1234)) self.build = base.Build([req]) self.build.setBuilder(self.builder) self.build.setupStatus(self.build_status) self.build.setupSlaveBuilder(FakeSlaveBuilder()) def testWithProperties(self): self.build.setProperty("revision", 47) self.failUnlessEqual(self.build_status.getProperty("revision"), 47) c = ShellCommand(workdir=dir, build=self.build, command=["tar", "czf", WithProperties("build-%s.tar.gz", "revision"), "source"]) cmd = c._interpolateProperties(c.command) self.failUnlessEqual(cmd, ["tar", "czf", "build-47.tar.gz", "source"]) def testWithPropertiesDict(self): self.build.setProperty("other", "foo") self.build.setProperty("missing", None) c = ShellCommand(workdir=dir, build=self.build, command=["tar", "czf", WithProperties("build-%(other)s.tar.gz"), "source"]) cmd = c._interpolateProperties(c.command) self.failUnlessEqual(cmd, ["tar", "czf", "build-foo.tar.gz", "source"]) def testWithPropertiesMissing(self): self.build.setProperty("missing", None) c = ShellCommand(workdir=dir, build=self.build, command=["tar", "czf", WithProperties("build-%(missing)s.tar.gz"), "source"]) cmd = c._interpolateProperties(c.command) self.failUnlessEqual(cmd, ["tar", "czf", "build-.tar.gz", "source"]) def testCustomBuildStep(self): c = MyBuildStep(workdir=dir, build=self.build) cmd = c._interpolateProperties(c.command) self.failUnlessEqual(cmd, ["tar", "czf", "build-1234.tar.gz", "source"]) def testSourceStamp(self): c = ShellCommand(workdir=dir, build=self.build, command=["touch", WithProperties("%s-dir", "branch"), WithProperties("%s-rev", "revision"), ]) cmd = c._interpolateProperties(c.command) self.failUnlessEqual(cmd, ["touch", "branch2-dir", "1234-rev"]) def testSlaveName(self): c = ShellCommand(workdir=dir, build=self.build, command=["touch", WithProperties("%s-slave", "slavename"), ]) cmd = c._interpolateProperties(c.command) self.failUnlessEqual(cmd, ["touch", "bot12-slave"]) # we test got_revision in test_vc Index: test_vc.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_vc.py,v retrieving revision 1.47 retrieving revision 1.48 diff -u -d -r1.47 -r1.48 --- test_vc.py 11 Apr 2006 06:12:59 -0000 1.47 +++ test_vc.py 24 Apr 2006 06:45:36 -0000 1.48 @@ -253,6 +253,8 @@ httpServer = None httpPort = None skip = None + has_got_revision = False + has_got_revision_branches_are_merged = False # for SVN def failUnlessIn(self, substring, string, msg=None): # trial provides a version of this that requires python-2.3 to test @@ -431,6 +433,16 @@ c = open(os.path.join(d, f), "r").read() self.failUnlessIn(contents, c) + def checkGotRevision(self, bs, expected): + if self.has_got_revision: + self.failUnlessEqual(bs.getProperty("got_revision"), expected) + + def checkGotRevisionIsLatest(self, bs): + expected = self.trunk[-1] + if self.has_got_revision_branches_are_merged: + expected = self.allrevs[-1] + self.checkGotRevision(bs, expected) + def do_vctest(self, testRetry=True): vctype = self.vctype args = self.vcargs @@ -473,12 +485,15 @@ d = self.doBuild() # initial checkout d.addCallback(self._do_vctest_clobber_1) return d - def _do_vctest_clobber_1(self, res): + def _do_vctest_clobber_1(self, bs): self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldExist(self.workdir, "subdir", "subdir.c") if self.metadir: self.shouldExist(self.workdir, self.metadir) + self.failUnlessEqual(bs.getProperty("revision"), None) + self.failUnlessEqual(bs.getProperty("branch"), None) + self.checkGotRevisionIsLatest(bs) self.touch(self.workdir, "newfile") self.shouldExist(self.workdir, "newfile") @@ -493,7 +508,7 @@ d = self.doBuild() # rebuild with update d.addCallback(self._do_vctest_update_1) return d - def _do_vctest_update_1(self, res): + def _do_vctest_update_1(self, bs): log.msg("_do_vctest_update_1") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") @@ -501,12 +516,14 @@ "version=%d" % self.version) if self.metadir: self.shouldExist(self.workdir, self.metadir) + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) self.touch(self.workdir, "newfile") d = self.doBuild() # update rebuild leaves new files d.addCallback(self._do_vctest_update_2) return d - def _do_vctest_update_2(self, res): + def _do_vctest_update_2(self, bs): log.msg("_do_vctest_update_2") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") @@ -516,33 +533,41 @@ d.addCallback(lambda res: self.doBuild()) d.addCallback(self._do_vctest_update_3) return d - def _do_vctest_update_3(self, res): + def _do_vctest_update_3(self, bs): log.msg("_do_vctest_update_3") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", "version=%d" % self.version) self.shouldExist(self.workdir, "newfile") + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) + # now "update" to an older revision d = self.doBuild(ss=SourceStamp(revision=self.trunk[-2])) d.addCallback(self._do_vctest_update_4) return d - def _do_vctest_update_4(self, res): + def _do_vctest_update_4(self, bs): log.msg("_do_vctest_update_4") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", "version=%d" % (self.version-1)) + self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-2]) + self.checkGotRevision(bs, self.trunk[-2]) + # now update to the newer revision d = self.doBuild(ss=SourceStamp(revision=self.trunk[-1])) d.addCallback(self._do_vctest_update_5) return d - def _do_vctest_update_5(self, res): + def _do_vctest_update_5(self, bs): log.msg("_do_vctest_update_5") self.shouldExist(self.workdir, "main.c") self.shouldExist(self.workdir, "version.c") self.shouldContain(self.workdir, "version.c", "version=%d" % self.version) + self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-1]) + self.checkGotRevision(bs, self.trunk[-1]) def _do_vctest_update_retry(self, res): @@ -558,46 +583,54 @@ d = self.doBuild() # update, but must clobber to handle the error d.addCallback(self._do_vctest_update_retry_1) return d - def _do_vctest_update_retry_1(self, res): + def _do_vctest_update_retry_1(self, bs): self.shouldNotExist(self.workdir, "newfile") def _do_vctest_copy(self, res): d = self.doBuild() # copy rebuild clobbers new files d.addCallback(self._do_vctest_copy_1) return d - def _do_vctest_copy_1(self, res): + def _do_vctest_copy_1(self, bs): if self.metadir: self.shouldExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") self.touch(self.workdir, "newfile") self.touch(self.vcdir, "newvcfile") + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) d = self.doBuild() # copy rebuild clobbers new files d.addCallback(self._do_vctest_copy_2) return d - def _do_vctest_copy_2(self, res): + def _do_vctest_copy_2(self, bs): if self.metadir: self.shouldExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") self.shouldExist(self.vcdir, "newvcfile") self.shouldExist(self.workdir, "newvcfile") + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) self.touch(self.workdir, "newfile") def _do_vctest_export(self, res): d = self.doBuild() # export rebuild clobbers new files d.addCallback(self._do_vctest_export_1) return d - def _do_vctest_export_1(self, res): + def _do_vctest_export_1(self, bs): self.shouldNotExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) self.touch(self.workdir, "newfile") d = self.doBuild() # export rebuild clobbers new files d.addCallback(self._do_vctest_export_2) return d - def _do_vctest_export_2(self, res): + def _do_vctest_export_2(self, bs): self.shouldNotExist(self.workdir, self.metadir) self.shouldNotExist(self.workdir, "newfile") + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) def do_patch(self): vctype = self.vctype @@ -621,7 +654,7 @@ d.addCallback(lambda res: self.doBuild(ss=ss)) d.addCallback(self._doPatch_1) return d - def _doPatch_1(self, res): + def _doPatch_1(self, bs): self.shouldContain(self.workdir, "version.c", "version=%d" % self.version) # make sure the file actually got patched @@ -629,18 +662,22 @@ "subdir", "subdir.c") data = open(subdir_c, "r").read() self.failUnlessIn("Hello patched subdir.\\n", data) + self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-1]) + self.checkGotRevision(bs, self.trunk[-1]) # make sure that a rebuild does not use the leftover patched workdir d = self.master.loadConfig(self.config % "update") d.addCallback(lambda res: self.doBuild(ss=None)) d.addCallback(self._doPatch_2) return d - def _doPatch_2(self, res): + def _doPatch_2(self, bs): # make sure the file is back to its original subdir_c = os.path.join(self.slavebase, "vc-dir", "build", "subdir", "subdir.c") data = open(subdir_c, "r").read() self.failUnlessIn("Hello subdir.\\n", data) + self.failUnlessEqual(bs.getProperty("revision"), None) + self.checkGotRevisionIsLatest(bs) # now make sure we can patch an older revision. We need at least two # revisions here, so we might have to create one first @@ -655,7 +692,7 @@ d = self.doBuild(ss=ss) d.addCallback(self._doPatch_4) return d - def _doPatch_4(self, res): + def _doPatch_4(self, bs): self.shouldContain(self.workdir, "version.c", "version=%d" % (self.version-1)) # and make sure the file actually got patched @@ -663,6 +700,8 @@ "subdir", "subdir.c") data = open(subdir_c, "r").read() self.failUnlessIn("Hello patched subdir.\\n", data) + self.failUnlessEqual(bs.getProperty("revision"), self.trunk[-2]) + self.checkGotRevision(bs, self.trunk[-2]) # now check that we can patch a branch ss = SourceStamp(branch=self.branchname, revision=self.branch[-1], @@ -670,7 +709,7 @@ d = self.doBuild(ss=ss) d.addCallback(self._doPatch_5) return d - def _doPatch_5(self, res): + def _doPatch_5(self, bs): self.shouldContain(self.workdir, "version.c", "version=%d" % 1) self.shouldContain(self.workdir, "main.c", "Hello branch.") @@ -678,6 +717,9 @@ "subdir", "subdir.c") data = open(subdir_c, "r").read() self.failUnlessIn("Hello patched subdir.\\n", data) + self.failUnlessEqual(bs.getProperty("revision"), self.branch[-1]) + self.failUnlessEqual(bs.getProperty("branch"), self.branchname) + self.checkGotRevision(bs, self.branch[-1]) def do_vctest_once(self, shouldSucceed): @@ -723,7 +765,7 @@ d.addCallback(lambda res: self.doBuild(ss=SourceStamp())) d.addCallback(self._doBranch_1) return d - def _doBranch_1(self, res): + def _doBranch_1(self, bs): log.msg("_doBranch_1") # make sure the checkout was of the trunk main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") @@ -736,7 +778,7 @@ d = self.doBuild(ss=SourceStamp(branch=self.branchname)) d.addCallback(self._doBranch_2) return d - def _doBranch_2(self, res): + def _doBranch_2(self, bs): log.msg("_doBranch_2") # make sure it was on the branch main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") @@ -750,7 +792,7 @@ d = self.doBuild(ss=SourceStamp(branch=self.branchname)) d.addCallback(self._doBranch_3) return d - def _doBranch_3(self, res): + def _doBranch_3(self, bs): log.msg("_doBranch_3") # make sure it is still on the branch main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") @@ -763,7 +805,7 @@ d = self.doBuild(ss=SourceStamp()) d.addCallback(self._doBranch_4) return d - def _doBranch_4(self, res): + def _doBranch_4(self, bs): log.msg("_doBranch_4") # make sure it was on the trunk main_c = os.path.join(self.slavebase, "vc-dir", "build", "main.c") @@ -938,6 +980,11 @@ try_branchname = "branch" vctype = "step.CVS" vctype_try = "cvs" + # CVS gives us got_revision, but it is based entirely upon the local + # clock, which means it is unlikely to match the timestamp taken earlier. + # This might be enough for common use, but won't be good enough for our + # tests to accept, so pretend it doesn't have got_revision at all. + has_got_revision = False def capable(self): global VCS @@ -1042,7 +1089,7 @@ d = self.do_patch() return maybeWait(d) - def testBranch(self): + def testCheckoutBranch(self): d = self.do_branch() return maybeWait(d) @@ -1057,6 +1104,8 @@ try_branchname = "sample/branch" vctype = "step.SVN" vctype_try = "svn" + has_got_revision = True + has_got_revision_branches_are_merged = True def capable(self): global VCS @@ -1171,7 +1220,7 @@ def testCheckout(self): # we verify this one with the svnurl style of vcargs. We test the - # baseURL/defaultBranch style in testPatch and testBranch. + # baseURL/defaultBranch style in testPatch and testCheckoutBranch. self.vcargs = { 'svnurl': self.svnurl_trunk } d = self.do_vctest() return maybeWait(d) @@ -1183,7 +1232,7 @@ d = self.do_patch() return maybeWait(d) - def testBranch(self): + def testCheckoutBranch(self): self.vcargs = { 'baseURL': self.svnurl + "/", 'defaultBranch': "sample/trunk", } @@ -1208,6 +1257,7 @@ try_branchname = "branch" vctype = "step.Darcs" vctype_try = "darcs" + has_got_revision = True def capable(self): global VCS @@ -1312,7 +1362,7 @@ d = self.do_patch() return maybeWait(d) - def testBranch(self): + def testCheckoutBranch(self): self.vcargs = { 'baseURL': self.darcs_base + "/", 'defaultBranch': "trunk" } d = self.do_branch() @@ -1367,6 +1417,7 @@ vctype = "step.Arch" vctype_try = "tla" archcmd = "tla" + has_got_revision = True def capable(self): global VCS @@ -1624,7 +1675,7 @@ d = self.do_patch() return maybeWait(d) - def testBranch(self): + def testCheckoutBranch(self): d = self.do_branch() return maybeWait(d) @@ -1636,6 +1687,7 @@ vctype = "step.Bazaar" vctype_try = "baz" archcmd = "baz" + has_got_revision = True def capable(self): global VCS @@ -1687,7 +1739,7 @@ d = self.do_patch() return maybeWait(d) - def testBranch(self): + def testCheckoutBranch(self): d = self.do_branch() return maybeWait(d) @@ -1767,6 +1819,7 @@ try_branchname = "branch" vctype = "step.Mercurial" vctype_try = "hg" + has_got_revision = True def capable(self): global VCS @@ -1879,7 +1932,7 @@ d = self.do_patch() return maybeWait(d) - def testBranch(self): + def testCheckoutBranch(self): self.vcargs = { 'baseURL': self.hg_base + "/", 'defaultBranch': "trunk" } d = self.do_branch() From warner at users.sourceforge.net Mon Apr 24 06:45:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 06:45:39 +0000 Subject: [Buildbot-commits] buildbot/buildbot/process step.py,1.83,1.84 base.py,1.62,1.63 step_twisted.py,1.74,1.75 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/process In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25669/buildbot/process Modified Files: step.py base.py step_twisted.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-506 Creator: Brian Warner add 'build properties', update test_vc 2006-04-23 Brian Warner * 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 * buildbot/test/test_vc.py: rename testBranch to testCheckoutBranch to keep the tests in about the right alphabetical order Index: base.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/base.py,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- base.py 12 Mar 2006 11:28:04 -0000 1.62 +++ base.py 24 Apr 2006 06:45:36 -0000 1.63 @@ -157,6 +157,7 @@ @ivar build_status: the L{buildbot.status.builder.BuildStatus} that collects our status """ + if implements: implements(interfaces.IBuildControl) else: @@ -197,6 +198,16 @@ def getSourceStamp(self): return self.source + def setProperty(self, propname, value): + """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) + + def getProperty(self, propname): + return self.build_status.properties[propname] + + def allChanges(self): return self.source.changes @@ -253,6 +264,16 @@ def getSlaveCommandVersion(self, command, oldversion=None): return self.slavebuilder.getSlaveCommandVersion(command, oldversion) + def setupStatus(self, build_status): + self.build_status = build_status + self.setProperty("branch", self.source.branch) + self.setProperty("revision", self.source.revision) + + def setupSlaveBuilder(self, slavebuilder): + self.slavebuilder = slavebuilder + self.slavename = slavebuilder.slave.slavename + self.setProperty("slavename", self.slavename) + def startBuild(self, build_status, expectations, slavebuilder): """This method sets up the build, then starts it by invoking the first Step. It returns a Deferred which will fire when the build @@ -264,9 +285,10 @@ # the Deferred returned by this method. log.msg("%s.startBuild" % self) - self.build_status = build_status - self.slavebuilder = slavebuilder - self.slavename = slavebuilder.slave.slavename + self.setupStatus(build_status) + # now that we have a build_status, we can set properties + self.setupSlaveBuilder(slavebuilder) + # convert all locks into their real forms self.locks = [self.builder.botmaster.getLockByID(l) for l in self.locks] Index: step.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step.py,v retrieving revision 1.83 retrieving revision 1.84 diff -u -d -r1.83 -r1.84 --- step.py 17 Apr 2006 19:22:33 -0000 1.83 +++ step.py 24 Apr 2006 06:45:36 -0000 1.84 @@ -253,6 +253,7 @@ # orphan LogFile, cannot be subscribed to self.log = builder.LogFile(None) self.closeWhenFinished = True + self.updates = {} log.msg("LoggedRemoteCommand.start", self.log) return RemoteCommand.start(self) @@ -276,6 +277,11 @@ rc = self.rc = update['rc'] log.msg("%s rc=%s" % (self, rc)) self.addHeader("program finished with exit code %d\n" % rc) + for k in update: + if k not in ('stdout', 'stderr', 'header', 'rc'): + if k not in self.updates: + self.updates[k] = [] + self.updates[k].append(update[k]) def remoteComplete(self, maybeFailure): if self.closeWhenFinished: @@ -408,6 +414,14 @@ flunkOnFailure = False warnOnWarnings = False warnOnFailure = False + + # 'parms' holds a list of all the parameters we care about, to allow + # users to instantiate a subclass of BuildStep with a mixture of + # arguments, some of which are for us, some of which are for the subclass + # (or a delegate of the subclass, like how ShellCommand delivers many + # arguments to the RemoteShellCommand that it creates). Such delegating + # subclasses will use this list to figure out which arguments are meant + # for us and which should be given to someone else. parms = ['build', 'name', 'locks', 'haltOnFailure', 'flunkOnWarnings', @@ -425,8 +439,8 @@ step_status = None progress = None - def __init__(self, **kwargs): - self.build = kwargs['build'] # required + def __init__(self, build, **kwargs): + self.build = build for p in self.__class__.parms: if kwargs.has_key(p): setattr(self, p, kwargs[p]) @@ -449,6 +463,12 @@ return sp return None + def getProperty(self, propname): + return self.build.getProperty(propname) + + def setProperty(self, propname, value): + self.build.setProperty(propname, value) + def startStep(self, remote): """Begin the step. This returns a Deferred that will fire when the step finishes. @@ -673,107 +693,32 @@ return d -class ShellCommand(BuildStep): - """I run a single shell command on the buildslave. I return FAILURE if - the exit code of that command is non-zero, SUCCESS otherwise. To change - this behavior, override my .evaluateCommand method. - - I create a single Log named 'log' which contains the output of the - command. To create additional summary Logs, override my .createSummary - method. - The shell command I run (a list of argv strings) can be provided in - several ways: - - a class-level .command attribute - - a command= parameter to my constructor (overrides .command) - - set explicitly with my .setCommand() method (overrides both) - - """ +class LoggingBuildStep(BuildStep): + # This is an abstract base class, suitable for inheritance by all + # BuildSteps that invoke RemoteCommands which emit stdout/stderr messages - name = "shell" - description = None # set this to a list of short strings to override - descriptionDone = None # alternate description when the step is complete - command = None # set this to a command, or set in kwargs progressMetrics = ['output'] - parms = BuildStep.parms + [ - 'description', - 'descriptionDone', - ] - - def __init__(self, **kwargs): - # most of our arguments get passed through to the RemoteShellCommand - # that we create, but first strip out the ones that we pass to - # BuildStep (like haltOnFailure and friends) - self.workdir = kwargs['workdir'] # required by RemoteShellCommand - buildstep_kwargs = {} - for k in kwargs.keys()[:]: - if k in self.__class__.parms: - buildstep_kwargs[k] = kwargs[k] - del kwargs[k] - BuildStep.__init__(self, **buildstep_kwargs) - kwargs['command'] = kwargs.get('command', self.command) - self.cmd = RemoteShellCommand(**kwargs) - - def setCommand(self, command): - self.cmd.command = command - def describe(self, done=False): - """Return a list of short strings to describe this step, for the - status display. This uses the first few words of the shell command. - You can replace this by setting .description in your subclass, or by - overriding this method to describe the step better. + raise NotImplementedError("implement this in a subclass") - @type done: boolean - @param done: whether the command is complete or not, to improve the - way the command is described. C{done=False} is used - while the command is still running, so a single - imperfect-tense verb is appropriate ('compiling', - 'testing', ...) C{done=True} is used when the command - has finished, and the default getText() method adds some - text, so a simple noun is appropriate ('compile', - 'tests' ...) + def startCommand(self, cmd, errorMessages=[]): """ - - if done and self.descriptionDone is not None: - return self.descriptionDone - if self.description is not None: - return self.description - - words = self.cmd.command - if type(words) in types.StringTypes: - words = words.split() - if len(words) < 1: - return ["???"] - if len(words) == 1: - return ["'%s'" % words[0]] - if len(words) == 2: - return ["'%s" % words[0], "%s'" % words[1]] - return ["'%s" % words[0], "%s" % words[1], "...'"] - - def start(self, errorMessages=[]): - # merge in anything from Build.slaveEnvironment . Earlier steps - # (perhaps ones which compile libraries or sub-projects that need to - # be referenced by later steps) can add keys to - # self.build.slaveEnvironment to affect later steps. - slaveEnv = self.build.slaveEnvironment - if slaveEnv: - if self.cmd.args['env'] is None: - self.cmd.args['env'] = {} - self.cmd.args['env'].update(slaveEnv) - # note that each RemoteShellCommand gets its own copy of the - # dictionary, so we shouldn't be affecting anyone but ourselves. - + @param cmd: a suitable RemoteCommand which will be launched, with + all output being put into a LogFile named 'log' + """ + self.cmd = cmd # so we can interrupt it self.step_status.setColor("yellow") self.step_status.setText(self.describe(False)) loog = self.addLog("log") for em in errorMessages: loog.addHeader(em) log.msg("ShellCommand.start using log", loog) - log.msg(" for cmd", self.cmd) - self.cmd.useLog(loog, True) + log.msg(" for cmd", cmd) + cmd.useLog(loog, True) loog.logProgressTo(self.progress, "output") - d = self.runCommand(self.cmd) + d = self.runCommand(cmd) d.addCallbacks(self._commandComplete, self.checkDisconnect) d.addErrback(self.failed) @@ -896,8 +841,168 @@ self.step_status.setText2(self.maybeGetText2(cmd, results)) +# -*- test-case-name: buildbot.test.test_properties -*- + +class _BuildPropertyDictionary: + 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: + """This is a marker class, used in ShellCommand's command= argument to + indicate that we want to interpolate a build property. + """ + + def __init__(self, fmtstring, *args): + self.fmtstring = fmtstring + self.args = args + + def render(self, build): + if self.args: + strings = [] + for name in self.args: + p = build.getProperty(name) + if p is None: + p = "" + strings.append(p) + s = self.fmtstring % tuple(strings) + else: + s = self.fmtstring % _BuildPropertyDictionary(build) + return s + +class ShellCommand(LoggingBuildStep): + """I run a single shell command on the buildslave. I return FAILURE if + the exit code of that command is non-zero, SUCCESS otherwise. To change + this behavior, override my .evaluateCommand method. + + I create a single Log named 'log' which contains the output of the + command. To create additional summary Logs, override my .createSummary + method. + + The shell command I run (a list of argv strings) can be provided in + several ways: + - a class-level .command attribute + - a command= parameter to my constructor (overrides .command) + - set explicitly with my .setCommand() method (overrides both) + + @ivar command: a list of argv strings (or WithProperties instances). + This will be used by start() to create a + RemoteShellCommand instance. + + """ + + name = "shell" + description = None # set this to a list of short strings to override + descriptionDone = None # alternate description when the step is complete + command = None # set this to a command, or set in kwargs + + def __init__(self, workdir, + description=None, descriptionDone=None, + command=None, + **kwargs): + # most of our arguments get passed through to the RemoteShellCommand + # that we create, but first strip out the ones that we pass to + # BuildStep (like haltOnFailure and friends), and a couple that we + # consume ourselves. + self.workdir = workdir # required by RemoteShellCommand + if description: + self.description = description + if descriptionDone: + self.descriptionDone = descriptionDone + if command: + self.command = command + + # pull out the ones that BuildStep wants, then upcall + buildstep_kwargs = {} + for k in kwargs.keys()[:]: + if k in self.__class__.parms: + buildstep_kwargs[k] = kwargs[k] + del kwargs[k] + LoggingBuildStep.__init__(self, **buildstep_kwargs) + + # everything left over goes to the RemoteShellCommand + kwargs['workdir'] = workdir # including a copy of 'workdir' + self.remote_kwargs = kwargs + + + def setCommand(self, command): + self.command = command + + def describe(self, done=False): + """Return a list of short strings to describe this step, for the + status display. This uses the first few words of the shell command. + You can replace this by setting .description in your subclass, or by + overriding this method to describe the step better. + + @type done: boolean + @param done: whether the command is complete or not, to improve the + way the command is described. C{done=False} is used + while the command is still running, so a single + imperfect-tense verb is appropriate ('compiling', + 'testing', ...) C{done=True} is used when the command + has finished, and the default getText() method adds some + text, so a simple noun is appropriate ('compile', + 'tests' ...) + """ + + if done and self.descriptionDone is not None: + return self.descriptionDone + if self.description is not None: + return self.description + + words = self.command + # TODO: handle WithProperties here + if isinstance(words, types.StringTypes): + words = words.split() + if len(words) < 1: + return ["???"] + if len(words) == 1: + return ["'%s'" % words[0]] + if len(words) == 2: + return ["'%s" % words[0], "%s'" % words[1]] + return ["'%s" % words[0], "%s" % words[1], "...'"] + + def _interpolateProperties(self, command): + # interpolate any build properties into our command + if not isinstance(command, (list, tuple)): + return + command_argv = [] + for argv in command: + if isinstance(argv, WithProperties): + command_argv.append(argv.render(self.build)) + else: + command_argv.append(argv) + return command_argv + + def setupEnvironment(self, cmd): + # merge in anything from Build.slaveEnvironment . Earlier steps + # (perhaps ones which compile libraries or sub-projects that need to + # be referenced by later steps) can add keys to + # self.build.slaveEnvironment to affect later steps. + slaveEnv = self.build.slaveEnvironment + if slaveEnv: + if cmd.args['env'] is None: + cmd.args['env'] = {} + cmd.args['env'].update(slaveEnv) + # note that each RemoteShellCommand gets its own copy of the + # dictionary, so we shouldn't be affecting anyone but ourselves. + + def start(self): + command = self._interpolateProperties(self.command) + # create the actual RemoteShellCommand instance now + kwargs = self.remote_kwargs + kwargs['command'] = self.command + cmd = RemoteShellCommand(**kwargs) + self.setupEnvironment(cmd) + self.startCommand(cmd) + + + - class TreeSize(ShellCommand): name = "treesize" command = ["du", "-s", "."] @@ -922,7 +1027,7 @@ return ["treesize", "unknown"] -class Source(ShellCommand): +class Source(LoggingBuildStep): """This is a base class to generate a source tree in the buildslave. Each version control system has a specialized subclass, and is expected to override __init__ and implement computeSourceRevision() and @@ -1018,7 +1123,8 @@ """ - BuildStep.__init__(self, **kwargs) + LoggingBuildStep.__init__(self, **kwargs) + assert mode in ("update", "copy", "clobber", "export") if retry: delay, repeats = retry @@ -1042,11 +1148,13 @@ elif mode == "export": description = ["exporting"] descriptionDone = ["export"] - # Initialize descriptions if not already set: - if self.description is None: - self.description = description - if self.descriptionDone is None: - self.descriptionDone = descriptionDone + self.description = description + self.descriptionDone = descriptionDone + + def describe(self, done=False): + if done: + return self.descriptionDone + return self.description def computeSourceRevision(self, changes): """Each subclass must implement this method to do something more @@ -1083,6 +1191,13 @@ self.startVC(branch, revision, patch) + def commandComplete(self, cmd): + got_revision = None + if cmd.updates.has_key("got_revision"): + got_revision = cmd.updates["got_revision"][-1] + self.setProperty("got_revision", got_revision) + + class CVS(Source): """I do CVS checkout/update operations. @@ -1241,8 +1356,8 @@ self.args['tag'] = self.args['branch'] assert not self.args['patch'] # 0.5.0 slave can't do patch - self.cmd = LoggedRemoteCommand("cvs", self.args) - ShellCommand.start(self, warnings) + cmd = LoggedRemoteCommand("cvs", self.args) + self.startCommand(cmd, warnings) class SVN(Source): @@ -1363,8 +1478,8 @@ self.description.extend(revstuff) self.descriptionDone.extend(revstuff) - self.cmd = LoggedRemoteCommand("svn", self.args) - ShellCommand.start(self, warnings) + cmd = LoggedRemoteCommand("svn", self.args) + self.startCommand(cmd, warnings) class Darcs(Source): @@ -1451,8 +1566,8 @@ self.description.extend(revstuff) self.descriptionDone.extend(revstuff) - self.cmd = LoggedRemoteCommand("darcs", self.args) - ShellCommand.start(self) + cmd = LoggedRemoteCommand("darcs", self.args) + self.startCommand(cmd) class Git(Source): @@ -1477,8 +1592,8 @@ if not slavever: raise BuildSlaveTooOldError("slave is too old, does not know " "about git") - self.cmd = LoggedRemoteCommand("git", self.args) - ShellCommand.start(self) + cmd = LoggedRemoteCommand("git", self.args) + self.startCommand(cmd) class Arch(Source): @@ -1590,8 +1705,8 @@ self.description.extend(revstuff) self.descriptionDone.extend(revstuff) - self.cmd = LoggedRemoteCommand("arch", self.args) - ShellCommand.start(self, warnings) + cmd = LoggedRemoteCommand("arch", self.args) + self.startCommand(cmd, warnings) class Bazaar(Arch): @@ -1636,8 +1751,8 @@ self.description.extend(revstuff) self.descriptionDone.extend(revstuff) - self.cmd = LoggedRemoteCommand("bazaar", self.args) - ShellCommand.start(self, warnings) + cmd = LoggedRemoteCommand("bazaar", self.args) + self.startCommand(cmd, warnings) class Mercurial(Source): """Check out a source tree from a mercurial repository 'repourl'.""" @@ -1693,8 +1808,8 @@ self.description.extend(revstuff) self.descriptionDone.extend(revstuff) - self.cmd = LoggedRemoteCommand("hg", self.args) - ShellCommand.start(self) + cmd = LoggedRemoteCommand("hg", self.args) + self.startCommand(cmd) class todo_P4(Source): @@ -1714,8 +1829,8 @@ }) def startVC(self, branch, revision, patch): - self.cmd = LoggedRemoteCommand("p4", self.args) - ShellCommand.start(self) + cmd = LoggedRemoteCommand("p4", self.args) + self.startCommand(cmd) class P4Sync(Source): """This is a partial solution for using a P4 source repository. You are @@ -1755,8 +1870,8 @@ def startVC(self, branch, revision, patch): slavever = self.slaveVersion("p4sync") assert slavever, "slave is too old, does not know about p4" - self.cmd = LoggedRemoteCommand("p4sync", self.args) - ShellCommand.start(self) + cmd = LoggedRemoteCommand("p4sync", self.args) + self.startCommand(cmd) class Dummy(BuildStep): @@ -1808,8 +1923,7 @@ self.step_status.setColor("red") self.finished(FAILURE) -# subclasses from Shell Command to get the output reporting -class RemoteDummy(ShellCommand): +class RemoteDummy(LoggingBuildStep): """I am a dummy no-op step that runs on the remote side and simply waits 5 seconds before completing with success. See L{buildbot.slave.commands.DummyCommand} @@ -1823,11 +1937,18 @@ @type timeout: int @param timeout: the number of seconds to delay """ - BuildStep.__init__(self, **kwargs) - args = {'timeout': timeout} - self.cmd = LoggedRemoteCommand("dummy", args) + LoggingBuildStep.__init__(self, **kwargs) + self.timeout = timeout self.description = ["remote", "delay", "%s secs" % timeout] + def describe(self, done=False): + return self.description + + def start(self): + args = {'timeout': self.timeout} + cmd = LoggedRemoteCommand("dummy", args) + self.startCommand(cmd) + class Configure(ShellCommand): name = "configure" @@ -1835,7 +1956,7 @@ description = ["configuring"] descriptionDone = ["configure"] command = ["./configure"] - + class Compile(ShellCommand): name = "compile" Index: step_twisted.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step_twisted.py,v retrieving revision 1.74 retrieving revision 1.75 diff -u -d -r1.74 -r1.75 --- step_twisted.py 17 Apr 2006 19:22:34 -0000 1.74 +++ step_twisted.py 24 Apr 2006 06:45:37 -0000 1.75 @@ -367,17 +367,8 @@ self.description = ["testing"] self.descriptionDone = ["tests"] - def start(self): - # now that self.build.allFiles() is nailed down, finish building the - # command - if self.testChanges: - for f in self.build.allFiles(): - if f.endswith(".py"): - self.command.append("--testmodule=%s" % f) - else: - self.command.extend(self.tests) - log.msg("RunUnitTests.start: command is", self.command) - self.setCommand(self.command) + def setupEnvironment(self, cmd): + ShellCommand.setupEnvironment(self, cmd) if self.testpath != None: e = self.cmd.args['env'] if e is None: @@ -399,6 +390,17 @@ # KeyError if args['env'] doesn't have ['PYTHONPATH'] # TypeError if args is None pass + + def start(self): + # now that self.build.allFiles() is nailed down, finish building the + # command + if self.testChanges: + for f in self.build.allFiles(): + if f.endswith(".py"): + self.command.append("--testmodule=%s" % f) + else: + self.command.extend(self.tests) + log.msg("Trial.start: command is", self.command) ShellCommand.start(self) def _commandComplete(self, cmd): From warner at users.sourceforge.net Mon Apr 24 07:47:04 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 07:47:04 +0000 Subject: [Buildbot-commits] buildbot/buildbot/status html.py,1.82,1.83 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/status In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3497/buildbot/status Modified Files: html.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-508 Creator: Brian Warner CSS cleanup: implement the acceptable parts of SF#1461675 * buildbot/status/html.py (StatusResourceBuild.body): replace the bare buildbotURL/projectName line with a proper DIV, along with a CSS class of "title", from Stefan Seefeld (SF#1461675). (WaterfallStatusResource.body0): remove the redundant 'table' class from the table (WaterfallStatusResource.body): same. Also add class="LastBuild" to the top-row TR, and class="Activity" to the second-row TR, rather than putting them in the individual TD nodes. Index: html.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/status/html.py,v retrieving revision 1.82 retrieving revision 1.83 diff -u -d -r1.82 -r1.83 --- html.py 16 Apr 2006 23:05:41 -0000 1.82 +++ html.py 24 Apr 2006 07:47:02 -0000 1.83 @@ -321,7 +321,8 @@ b = self.build buildbotURL = self.status.getBuildbotURL() projectName = self.status.getProjectName() - data = "%s\n" % (buildbotURL, projectName) + data = '\n'%(buildbotURL, + projectName) # the color in the following line gives python-mode trouble data += ("

Build %s:#%d

\n" "

Reason:

\n%s\n" @@ -1071,6 +1072,12 @@ def body(self, request): "This method builds the main waterfall display." + + data = '' + + projectName = self.status.getProjectName() + projectURL = self.status.getProjectURL() + phase = request.args.get("phase",["2"]) phase = int(phase[0]) @@ -1097,27 +1104,23 @@ return self.phase0(request, (changeNames + builderNames), timestamps, eventGrid) # start the table: top-header material - data = "\n" - #data = "
\n" + data += '
\n' - data += " \n" - projectName = self.status.getProjectName() - projectURL = self.status.getProjectURL() if projectName and projectURL: # TODO: this is going to look really ugly topleft = "%s
last build" % \ (projectURL, projectName) else: topleft = "last build" + data += ' \n' data += td(topleft, align="right", colspan=2, class_="Project") for b in builders: box = ITopBox(b).getBox() data += box.td(align="center") data += " \n" - data += " \n" - data += td("current activity", align="right", colspan=2, - class_="Activity") + data += ' \n' + data += td('current activity', align='right', colspan=2) for b in builders: box = ICurrentBox(b).getBox(self.status) data += box.td(align="center") @@ -1173,9 +1176,7 @@ urllib.quote(request.childLink("waterfall")) data += " for the waterfall display

\n" - #data += "
\n" - #data += "
\n" - data += "
\n" + data += '
\n' names = map(lambda builder: builder.name, builders) # the top row is two blank spaces, then the top-level status boxes From warner at users.sourceforge.net Mon Apr 24 07:47:04 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 07:47:04 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.597,1.598 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3497 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-508 Creator: Brian Warner CSS cleanup: implement the acceptable parts of SF#1461675 * buildbot/status/html.py (StatusResourceBuild.body): replace the bare buildbotURL/projectName line with a proper DIV, along with a CSS class of "title", from Stefan Seefeld (SF#1461675). (WaterfallStatusResource.body0): remove the redundant 'table' class from the table (WaterfallStatusResource.body): same. Also add class="LastBuild" to the top-row TR, and class="Activity" to the second-row TR, rather than putting them in the individual TD nodes. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.597 retrieving revision 1.598 diff -u -d -r1.597 -r1.598 --- ChangeLog 24 Apr 2006 06:45:37 -0000 1.597 +++ ChangeLog 24 Apr 2006 07:47:02 -0000 1.598 @@ -1,5 +1,14 @@ 2006-04-23 Brian Warner + * buildbot/status/html.py (StatusResourceBuild.body): replace the + bare buildbotURL/projectName line with a proper DIV, along with a + CSS class of "title", from Stefan Seefeld (SF#1461675). + (WaterfallStatusResource.body0): remove the redundant 'table' + class from the table + (WaterfallStatusResource.body): same. Also add class="LastBuild" + to the top-row TR, and class="Activity" to the second-row TR, + rather than putting them in the individual TD nodes. + * 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. From warner at users.sourceforge.net Mon Apr 24 09:03:09 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:03:09 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.598,1.599 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25026 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-510 Creator: Brian Warner improve the windowsness of test_vc and tryclient * buildbot/test/test_vc.py (*.capable): store the actual VC binary's pathname in VCS[vcname], so it can be retrieved later (CVSSupport.vc_try_checkout): incorporate Niklaus Giger's patch to strip out non-numeric timezone information, specifically the funky German string that his system produced that confuses CVS. (DarcsSupport.vc_create): use dovc() instead of vc(), this should allow Darcs tests to work on windows * buildbot/scripts/tryclient.py (SourceStampExtractor): use procutils.which() everywhere, to allow tryclient to work under windows. Also from Niklaus Giger, SF#1463394. * buildbot/twcompat.py (which): move the replacement for a missing twisted.python.procutils.which from test_vc.py to here, so it can be used in other places too (specifically tryclient.py) Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.598 retrieving revision 1.599 diff -u -d -r1.598 -r1.599 --- ChangeLog 24 Apr 2006 07:47:02 -0000 1.598 +++ ChangeLog 24 Apr 2006 09:03:06 -0000 1.599 @@ -1,3 +1,20 @@ +2006-04-24 Brian Warner + + * buildbot/test/test_vc.py (*.capable): store the actual VC + binary's pathname in VCS[vcname], so it can be retrieved later + (CVSSupport.vc_try_checkout): incorporate Niklaus Giger's patch to + strip out non-numeric timezone information, specifically the funky + German string that his system produced that confuses CVS. + (DarcsSupport.vc_create): use dovc() instead of vc(), this should + allow Darcs tests to work on windows + * buildbot/scripts/tryclient.py (SourceStampExtractor): use + procutils.which() everywhere, to allow tryclient to work under + windows. Also from Niklaus Giger, SF#1463394. + + * buildbot/twcompat.py (which): move the replacement for a missing + twisted.python.procutils.which from test_vc.py to here, so it can + be used in other places too (specifically tryclient.py) + 2006-04-23 Brian Warner * buildbot/status/html.py (StatusResourceBuild.body): replace the From warner at users.sourceforge.net Mon Apr 24 09:03:09 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:03:09 +0000 Subject: [Buildbot-commits] buildbot/buildbot twcompat.py,1.4,1.5 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25026/buildbot Modified Files: twcompat.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-510 Creator: Brian Warner improve the windowsness of test_vc and tryclient * buildbot/test/test_vc.py (*.capable): store the actual VC binary's pathname in VCS[vcname], so it can be retrieved later (CVSSupport.vc_try_checkout): incorporate Niklaus Giger's patch to strip out non-numeric timezone information, specifically the funky German string that his system produced that confuses CVS. (DarcsSupport.vc_create): use dovc() instead of vc(), this should allow Darcs tests to work on windows * buildbot/scripts/tryclient.py (SourceStampExtractor): use procutils.which() everywhere, to allow tryclient to work under windows. Also from Niklaus Giger, SF#1463394. * buildbot/twcompat.py (which): move the replacement for a missing twisted.python.procutils.which from test_vc.py to here, so it can be used in other places too (specifically tryclient.py) Index: twcompat.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/twcompat.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- twcompat.py 17 Apr 2006 20:43:46 -0000 1.4 +++ twcompat.py 24 Apr 2006 09:03:07 -0000 1.5 @@ -23,6 +23,8 @@ assert providedBy(obj, IFoo) """ +import os, os.path + from twisted.copyright import version from twisted.python import components @@ -249,3 +251,35 @@ executable, args, env, path, reactor) utils.getProcessOutputAndValue = getProcessOutputAndValue + + +# copied from Twisted circa 2.2.0 +def _which(name, flags=os.X_OK): + """Search PATH for executable files with the given name. + + @type name: C{str} + @param name: The name for which to search. + + @type flags: C{int} + @param flags: Arguments to L{os.access}. + + @rtype: C{list} + @param: A list of the full paths to files found, in the + order in which they were found. + """ + result = [] + exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep)) + for p in os.environ['PATH'].split(os.pathsep): + p = os.path.join(p, name) + if os.access(p, flags): + result.append(p) + for e in exts: + pext = p + e + if os.access(pext, flags): + result.append(pext) + return result + +try: + from twisted.python.procutils import which +except ImportError: + which = _which From warner at users.sourceforge.net Mon Apr 24 09:03:09 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:03:09 +0000 Subject: [Buildbot-commits] buildbot/buildbot/test test_vc.py,1.48,1.49 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25026/buildbot/test Modified Files: test_vc.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-510 Creator: Brian Warner improve the windowsness of test_vc and tryclient * buildbot/test/test_vc.py (*.capable): store the actual VC binary's pathname in VCS[vcname], so it can be retrieved later (CVSSupport.vc_try_checkout): incorporate Niklaus Giger's patch to strip out non-numeric timezone information, specifically the funky German string that his system produced that confuses CVS. (DarcsSupport.vc_create): use dovc() instead of vc(), this should allow Darcs tests to work on windows * buildbot/scripts/tryclient.py (SourceStampExtractor): use procutils.which() everywhere, to allow tryclient to work under windows. Also from Niklaus Giger, SF#1463394. * buildbot/twcompat.py (which): move the replacement for a missing twisted.python.procutils.which from test_vc.py to here, so it can be used in other places too (specifically tryclient.py) Index: test_vc.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_vc.py,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- test_vc.py 24 Apr 2006 06:45:36 -0000 1.48 +++ test_vc.py 24 Apr 2006 09:03:07 -0000 1.49 @@ -7,34 +7,6 @@ from twisted.trial import unittest from twisted.internet import defer, reactor, utils -try: - from twisted.python.procutils import which -except ImportError: - # copied from Twisted circa 2.2.0 - def which(name, flags=os.X_OK): - """Search PATH for executable files with the given name. - - @type name: C{str} - @param name: The name for which to search. - - @type flags: C{int} - @param flags: Arguments to L{os.access}. - - @rtype: C{list} - @param: A list of the full paths to files found, in the - order in which they were found. - """ - result = [] - exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep)) - for p in os.environ['PATH'].split(os.pathsep): - p = os.path.join(p, name) - if os.access(p, flags): - result.append(p) - for e in exts: - pext = p + e - if os.access(pext, flags): - result.append(pext) - return result #defer.Deferred.debug = True @@ -48,7 +20,7 @@ from buildbot.process import step, base from buildbot.changes import changes from buildbot.sourcestamp import SourceStamp -from buildbot.twcompat import maybeWait +from buildbot.twcompat import maybeWait, which from buildbot.scripts import tryclient #step.LoggedRemoteCommand.debug = True @@ -76,7 +48,7 @@ # is running). -VCS = {} +VCS = {} # maps VC name to pathname of the executable config_vc = """ @@ -989,13 +961,13 @@ def capable(self): global VCS if not VCS.has_key("cvs"): - VCS["cvs"] = False + VCS["cvs"] = None cvspaths = which('cvs') if cvspaths: - VCS["cvs"] = True - self.vcexe = cvspaths[0] + VCS["cvs"] = cvspaths[0] if not VCS["cvs"]: raise unittest.SkipTest("CVS is not installed") + self.vcexe = VCS["cvs"] def postCreate(self, res): self.vcargs = { 'cvsroot': self.cvsrep, 'cvsmodule': "sample" } @@ -1060,10 +1032,14 @@ # 'workdir' is an absolute path assert os.path.abspath(workdir) == workdir - # get rid of timezone info, which might not be parsed # TODO - #rev = re.sub("[^0-9 :-]","",rev) - #rev = re.sub(" ","",rev) - #print "res is now <"+rev+">" + # get rid of non-numeric timezone info, which might not be parsed. + # This is in response to a non-US windows box which reports timezones + # in German like "Westeuropeische Normalzeit". We retain any numeric + # timezones present. TODO: I'm not convinced this won't result in a + # multi-hour offset for such a system. Where does the timezone name + # come from anyway? + rev = re.sub(r'[^0-9 :\-+]',"",rev) + rev = re.sub(" ","",rev) cmd = [self.vcexe, "-d", self.cvsrep, "checkout", "-d", workdir, "-D", rev] @@ -1110,31 +1086,32 @@ def capable(self): global VCS if not VCS.has_key("svn"): - VCS["svn"] = False + VCS["svn"] = None svnpaths = which('svn') svnadminpaths = which('svnadmin') if svnpaths and svnadminpaths: - self.vcexe = svnpaths[0] - self.svnadmin = svnadminpaths[0] # we need svn to be compiled with the ra_local access # module log.msg("running svn --version..") - d = utils.getProcessOutput(self.vcexe, ["--version"], + d = utils.getProcessOutput(svnpaths[0], ["--version"], env=os.environ) - d.addCallback(self._capable) + d.addCallback(self._capable, svnpaths[0], svnadminpaths[0]) return d if not VCS["svn"]: raise unittest.SkipTest("No usable Subversion was found") + self.vcexe, self.svnadmin = VCS["svn"] - def _capable(self, v): + def _capable(self, v, vcexe, svnadmin): if v.find("handles 'file' schem") != -1: # older versions say 'schema', 1.2.0 and beyond say 'scheme' - VCS['svn'] = True + VCS['svn'] = (vcexe, svnadmin) + self.vcexe = vcexe + self.svnadmin = svnadmin else: log.msg(("%s found but it does not support 'file:' " + "schema, skipping svn tests") % os.path.join(p, "svn")) - VCS['svn'] = False + VCS['svn'] = None raise unittest.SkipTest("Found SVN, but it can't use file: schema") def vc_create(self): @@ -1262,12 +1239,13 @@ def capable(self): global VCS if not VCS.has_key("darcs"): - VCS["darcs"] = False - for p in os.environ['PATH'].split(os.pathsep): - if os.path.exists(os.path.join(p, 'darcs')): - VCS["darcs"] = True + VCS["darcs"] = None + darcspaths = which('darcs') + if darcspaths: + VCS["darcs"] = darcspaths[0] if not VCS["darcs"]: raise unittest.SkipTest("Darcs is not installed") + self.vcexe = VCS["darcs"] def vc_create(self): self.darcs_base = os.path.join(self.repbase, "Darcs-Repository") @@ -1276,31 +1254,31 @@ tmp = os.path.join(self.repbase, "darcstmp") os.makedirs(self.rep_trunk) - w = self.do(self.rep_trunk, "darcs initialize") + w = self.dovc(self.rep_trunk, "initialize") yield w; w.getResult() os.makedirs(self.rep_branch) - w = self.do(self.rep_branch, "darcs initialize") + w = self.dovc(self.rep_branch, "initialize") yield w; w.getResult() self.populate(tmp) - w = self.do(tmp, "darcs initialize") + w = self.dovc(tmp, "initialize") yield w; w.getResult() - w = self.do(tmp, "darcs add -r .") + w = self.dovc(tmp, "add -r .") yield w; w.getResult() - w = self.do(tmp, "darcs record -a -m initial_import --skip-long-comment -A test at buildbot.sf.net") + w = self.dovc(tmp, "record -a -m initial_import --skip-long-comment -A test at buildbot.sf.net") yield w; w.getResult() - w = self.do(tmp, "darcs push -a %s" % self.rep_trunk) + w = self.dovc(tmp, "push -a %s" % self.rep_trunk) yield w; w.getResult() - w = self.do(tmp, "darcs changes --context") + w = self.dovc(tmp, "changes --context") yield w; out = w.getResult() self.addTrunkRev(out) self.populate_branch(tmp) - w = self.do(tmp, "darcs record -a --ignore-times -m commit_on_branch --skip-long-comment -A test at buildbot.sf.net") + w = self.dovc(tmp, "record -a --ignore-times -m commit_on_branch --skip-long-comment -A test at buildbot.sf.net") yield w; w.getResult() - w = self.do(tmp, "darcs push -a %s" % self.rep_branch) + w = self.dovc(tmp, "push -a %s" % self.rep_branch) yield w; w.getResult() - w = self.do(tmp, "darcs changes --context") + w = self.dovc(tmp, "changes --context") yield w; out = w.getResult() self.addBranchRev(out) rmdirRecursive(tmp) @@ -1309,19 +1287,19 @@ def vc_revise(self): tmp = os.path.join(self.repbase, "darcstmp") os.makedirs(tmp) - w = self.do(tmp, "darcs initialize") + w = self.dovc(tmp, "initialize") yield w; w.getResult() - w = self.do(tmp, "darcs pull -a %s" % self.rep_trunk) + w = self.dovc(tmp, "pull -a %s" % self.rep_trunk) yield w; w.getResult() self.version += 1 version_c = VERSION_C % self.version open(os.path.join(tmp, "version.c"), "w").write(version_c) - w = self.do(tmp, "darcs record -a --ignore-times -m revised_to_%d --skip-long-comment -A test at buildbot.sf.net" % self.version) + w = self.dovc(tmp, "record -a --ignore-times -m revised_to_%d --skip-long-comment -A test at buildbot.sf.net" % self.version) yield w; w.getResult() - w = self.do(tmp, "darcs push -a %s" % self.rep_trunk) + w = self.dovc(tmp, "push -a %s" % self.rep_trunk) yield w; w.getResult() - w = self.do(tmp, "darcs changes --context") + w = self.dovc(tmp, "changes --context") yield w; out = w.getResult() self.addTrunkRev(out) rmdirRecursive(tmp) @@ -1332,13 +1310,13 @@ if os.path.exists(workdir): rmdirRecursive(workdir) os.makedirs(workdir) - w = self.do(workdir, "darcs initialize") + w = self.dovc(workdir, "initialize") yield w; w.getResult() if not branch: rep = self.rep_trunk else: rep = os.path.join(self.darcs_base, branch) - w = self.do(workdir, "darcs pull -a %s" % rep) + w = self.dovc(workdir, "pull -a %s" % rep) yield w; w.getResult() open(os.path.join(workdir, "subdir", "subdir.c"), "w").write(TRY_C) vc_try_checkout = deferredGenerator(vc_try_checkout) @@ -1422,20 +1400,21 @@ def capable(self): global VCS if not VCS.has_key("tla"): - VCS["tla"] = False - exe = which('tla') - if len(exe) > 0: - VCS["tla"] = True + VCS["tla"] = None + tlapaths = which('tla') + if tlapaths: + VCS["tla"] = tlapaths[0] # we need to check for bazaar here too, since vc_create needs to know # about the presence of /usr/bin/baz even if we're running the tla # tests. if not VCS.has_key("baz"): - VCS["baz"] = False - exe = which('baz') - if len(exe) > 0: - VCS["baz"] = True + VCS["baz"] = None + bazpaths = which('baz') + if bazpaths: + VCS["baz"] = bazpaths[0] if not VCS["tla"]: raise unittest.SkipTest("Arch (tla) is not installed") + self.vcexe = VCS["tla"] def setUp2(self, res): # these are the coordinates of the read-write archive used by all the @@ -1692,12 +1671,13 @@ def capable(self): global VCS if not VCS.has_key("baz"): - VCS["baz"] = False - for p in os.environ['PATH'].split(os.pathsep): - if os.path.exists(os.path.join(p, 'baz')): - VCS["baz"] = True + VCS["baz"] = None + bazpaths = which('baz') + if bazpaths: + VCS["baz"] = bazpaths[0] if not VCS["baz"]: raise unittest.SkipTest("Arch (baz) is not installed") + self.vcexe = VCS["baz"] def setUp2(self, res): self.vcargs = {'url': self.archrep, @@ -1824,13 +1804,13 @@ def capable(self): global VCS if not VCS.has_key("hg"): - VCS["hg"] = False + VCS["hg"] = None hgpaths = which("hg") if hgpaths: - VCS["hg"] = True - self.vcexe = hgpaths[0] + VCS["hg"] = hgpaths[0] if not VCS["hg"]: raise unittest.SkipTest("Mercurial is not installed") + self.vcexe = VCS["hg"] def extract_id(self, output): m = re.search(r'^(\w+)', output) From warner at users.sourceforge.net Mon Apr 24 09:03:08 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:03:08 +0000 Subject: [Buildbot-commits] buildbot/buildbot/scripts tryclient.py,1.12,1.13 Message-ID: Update of /cvsroot/buildbot/buildbot/buildbot/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25026/buildbot/scripts Modified Files: tryclient.py Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-510 Creator: Brian Warner improve the windowsness of test_vc and tryclient * buildbot/test/test_vc.py (*.capable): store the actual VC binary's pathname in VCS[vcname], so it can be retrieved later (CVSSupport.vc_try_checkout): incorporate Niklaus Giger's patch to strip out non-numeric timezone information, specifically the funky German string that his system produced that confuses CVS. (DarcsSupport.vc_create): use dovc() instead of vc(), this should allow Darcs tests to work on windows * buildbot/scripts/tryclient.py (SourceStampExtractor): use procutils.which() everywhere, to allow tryclient to work under windows. Also from Niklaus Giger, SF#1463394. * buildbot/twcompat.py (which): move the replacement for a missing twisted.python.procutils.which from test_vc.py to here, so it can be used in other places too (specifically tryclient.py) Index: tryclient.py =================================================================== RCS file: /cvsroot/buildbot/buildbot/buildbot/scripts/tryclient.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- tryclient.py 11 Apr 2006 06:12:59 -0000 1.12 +++ tryclient.py 24 Apr 2006 09:03:06 -0000 1.13 @@ -10,16 +10,21 @@ from buildbot.scripts import runner from buildbot.util import now from buildbot.status import builder +from buildbot.twcompat import which class SourceStampExtractor: def __init__(self, treetop, branch): self.treetop = treetop self.branch = branch + self.exe = which(self.vcexe)[0] - def do(self, cmd): - return utils.getProcessOutput(cmd[0], cmd[1:], env=os.environ, + def dovc(self, cmd): + """This accepts the arguments of a command, without the actual + command itself.""" + return utils.getProcessOutput(self.exe, cmd, env=os.environ, path=self.treetop) + def get(self): """Return a Deferred that fires with a SourceStamp instance.""" d = self.getBaseRevision() @@ -35,6 +40,7 @@ class CVSExtractor(SourceStampExtractor): patchlevel = 0 + vcexe = "cvs" def getBaseRevision(self): # this depends upon our local clock and the repository's clock pretty # in reasonable sync with each other @@ -53,15 +59,17 @@ # find out what those checked-out versions are. raise RuntimeError("Sorry, CVS 'try' builds don't work with " "branches") - args = ['cvs', '-q', 'diff', '-u', '-D', self.baserev] - d = self.do(args) + args = ['-q', 'diff', '-u', '-D', self.baserev] + d = self.dovc(args) d.addCallback(self.readPatch, self.patchlevel) return d class SVNExtractor(SourceStampExtractor): patchlevel = 0 + vcexe = "svn" + def getBaseRevision(self): - d = self.do(['svn', "status", "-u"]) + d = self.dovc(["status", "-u"]) d.addCallback(self.parseStatus) return d def parseStatus(self, res): @@ -90,13 +98,14 @@ raise IndexError("Could not find 'Status against revision' in " "SVN output: %s" % res) def getPatch(self, res): - d = self.do(["svn", "diff", "-r%d" % self.baserev]) + d = self.dovc(["diff", "-r%d" % self.baserev]) d.addCallback(self.readPatch, self.patchlevel) return d class BazExtractor(SourceStampExtractor): + vcexe = "baz" def getBaseRevision(self): - d = self.do(["baz", "tree-id"]) + d = self.dovc(["tree-id"]) d.addCallback(self.parseStatus) return d def parseStatus(self, res): @@ -106,15 +115,16 @@ self.branch = tid[slash+1:dd] self.baserev = tid[dd+2:] def getPatch(self, res): - d = self.do(["baz", "diff"]) + d = self.dovc(["diff"]) d.addCallback(self.readPatch, 1) return d class TlaExtractor(SourceStampExtractor): + vcexe = "tla" def getBaseRevision(self): # 'tla logs --full' gives us ARCHIVE/BRANCH--REVISION # 'tla logs' gives us REVISION - d = self.do(["tla", "logs", "--full", "--reverse"]) + d = self.dovc(["logs", "--full", "--reverse"]) d.addCallback(self.parseStatus) return d def parseStatus(self, res): @@ -125,34 +135,36 @@ self.baserev = tid[dd+2:] def getPatch(self, res): - d = self.do(["tla", "changes", "--diffs"]) + d = self.dovc(["changes", "--diffs"]) d.addCallback(self.readPatch, 1) return d class MercurialExtractor(SourceStampExtractor): patchlevel = 1 + vcexe = "hg" def getBaseRevision(self): - d = self.do(["hg", "identify"]) + d = self.dovc(["identify"]) d.addCallback(self.parseStatus) return d def parseStatus(self, output): m = re.search(r'^(\w+)', output) self.baserev = m.group(0) def getPatch(self, res): - d = self.do(["hg", "diff"]) + d = self.dovc(["diff"]) d.addCallback(self.readPatch, self.patchlevel) return d class DarcsExtractor(SourceStampExtractor): patchlevel = 1 + vcexe = "darcs" def getBaseRevision(self): - d = self.do(["darcs", "changes", "--context"]) + d = self.dovc(["changes", "--context"]) d.addCallback(self.parseStatus) return d def parseStatus(self, res): self.baserev = res # the whole context file def getPatch(self, res): - d = self.do(["darcs", "diff", "-u"]) + d = self.dovc(["diff", "-u"]) d.addCallback(self.readPatch, self.patchlevel) return d From warner at users.sourceforge.net Mon Apr 24 09:10:38 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:10:38 +0000 Subject: [Buildbot-commits] buildbot/contrib/windows buildbot2.bat,NONE,1.1 Message-ID: Update of /cvsroot/buildbot/buildbot/contrib/windows In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32160/contrib/windows Added Files: buildbot2.bat Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-512 Creator: Brian Warner add utility wrapper for windows, SF#1194231. * contrib/windows/buildbot2.bat: utility wrapper for windows developers, contributed by Nick Trout (after a year of neglect.. sorry!). SF#1194231. --- NEW FILE: buildbot2.bat --- @echo off rem This is Windows helper batch file for Buildbot rem NOTE: You will need Windows NT5/XP to use some of the syntax here. rem Please note you must have Twisted Matrix installed to use this build system rem Details: http://twistedmatrix.com/ (Version 1.3.0 or more, preferrably 2.0+) rem NOTE: --reactor=win32 argument is need because of Twisted rem The Twisted default reactor is select based (ie. posix) (why?!) rem Keep environmental settings local to this file setlocal rem Change the following settings to suite your environment rem This is where you want Buildbot installed set BB_DIR=z:\Tools\PythonLibs rem Assuming you have TortoiseCVS installed [for CVS.exe]. set CVS_EXE="c:\Program Files\TortoiseCVS\cvs.exe" rem Trial: --spew will give LOADS of information. Use -o for verbose. set TRIAL=python C:\Python23\scripts\trial.py -o --reactor=win32 set BUILDBOT_TEST_VC=c:\temp if "%1"=="helper" ( goto print_help ) if "%1"=="bbinstall" ( rem You will only need to run this when you install Buildbot echo BB: Install BuildBot at the location you set in the config: echo BB: BB_DIR= %BB_DIR% echo BB: You must be in the buildbot-x.y.z directory to run this: python setup.py install --prefix %BB_DIR% --install-lib %BB_DIR% goto end ) if "%1"=="cvsco" ( echo BB: Getting Buildbot from Sourceforge CVS [if CVS in path]. if "%2"=="" ( echo BB ERROR: Please give a root path for the check out, eg. z:\temp goto end ) cd %2 echo BB: Hit return as there is no password %CVS_EXE% -d:pserver:anonymous at cvs.sourceforge.net:/cvsroot/buildbot login %CVS_EXE% -z3 -d:pserver:anonymous at cvs.sourceforge.net:/cvsroot/buildbot co -P buildbot goto end ) if "%1"=="cvsup" ( echo BB: Updating Buildbot from Sourceforge CVS [if CVS in path]. echo BB: Make sure you have the project checked out in local VCS. rem we only want buildbot code, the rest is from the install cd %BB_DIR% echo BB: Hit return as there is no password %CVS_EXE% -d:pserver:anonymous at cvs.sourceforge.net:/cvsroot/buildbot login %CVS_EXE% -z3 -d:pserver:anonymous at cvs.sourceforge.net:/cvsroot/buildbot up -P -d buildbot buildbot/buildbot goto end ) if "%1"=="test" ( rem Trial is a testing framework supplied by the Twisted Matrix package. rem It installs itself in the Python installation directory in a "scripts" folder, rem e.g. c:\python23\scripts rem This is just a convenience function because that directory is not in our path. if "%2" NEQ "" ( echo BB: TEST: buildbot.test.%2 %TRIAL% -m buildbot.test.%2 ) else ( echo BB: Running ALL buildbot tests... %TRIAL% buildbot.test ) goto end ) rem Okay, nothing that we recognised to pass to buildbot echo BB: Running buildbot... python -c "from buildbot.scripts import runner; runner.run()" %* goto end :print_help echo Buildbot helper script commands: echo helper This help message echo test Test buildbot is set up correctly echo Maintenance: echo bbinstall Install Buildbot from package echo cvsup Update from cvs echo cvsco [dir] Check buildbot out from cvs into [dir] :end rem End environment scope endlocal From warner at users.sourceforge.net Mon Apr 24 09:10:39 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:10:39 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.599,1.600 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32160 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-512 Creator: Brian Warner add utility wrapper for windows, SF#1194231. * contrib/windows/buildbot2.bat: utility wrapper for windows developers, contributed by Nick Trout (after a year of neglect.. sorry!). SF#1194231. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.599 retrieving revision 1.600 diff -u -d -r1.599 -r1.600 --- ChangeLog 24 Apr 2006 09:03:06 -0000 1.599 +++ ChangeLog 24 Apr 2006 09:10:36 -0000 1.600 @@ -1,5 +1,9 @@ 2006-04-24 Brian Warner + * contrib/windows/buildbot2.bat: utility wrapper for windows + developers, contributed by Nick Trout (after a year of neglect.. + sorry!). SF#1194231. + * buildbot/test/test_vc.py (*.capable): store the actual VC binary's pathname in VCS[vcname], so it can be retrieved later (CVSSupport.vc_try_checkout): incorporate Niklaus Giger's patch to From warner at users.sourceforge.net Mon Apr 24 09:49:27 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:49:27 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.600,1.601 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28621 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-514 Creator: Brian Warner docs: update trial invocation, SF#1469116 * docs/buildbot.texinfo (Installing the code): update trial invocation, SF#1469116 by Niklaus Giger. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.600 retrieving revision 1.601 diff -u -d -r1.600 -r1.601 --- ChangeLog 24 Apr 2006 09:10:36 -0000 1.600 +++ ChangeLog 24 Apr 2006 09:49:25 -0000 1.601 @@ -1,5 +1,8 @@ 2006-04-24 Brian Warner + * docs/buildbot.texinfo (Installing the code): update trial + invocation, SF#1469116 by Niklaus Giger. + * contrib/windows/buildbot2.bat: utility wrapper for windows developers, contributed by Nick Trout (after a year of neglect.. sorry!). SF#1194231. From warner at users.sourceforge.net Mon Apr 24 09:49:27 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:49:27 +0000 Subject: [Buildbot-commits] buildbot/docs buildbot.texinfo,1.45,1.46 Message-ID: Update of /cvsroot/buildbot/buildbot/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28621/docs Modified Files: buildbot.texinfo Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-514 Creator: Brian Warner docs: update trial invocation, SF#1469116 * docs/buildbot.texinfo (Installing the code): update trial invocation, SF#1469116 by Niklaus Giger. Index: buildbot.texinfo =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v retrieving revision 1.45 retrieving revision 1.46 diff -u -d -r1.45 -r1.46 --- buildbot.texinfo 24 Apr 2006 06:45:37 -0000 1.45 +++ buildbot.texinfo 24 Apr 2006 09:49:24 -0000 1.46 @@ -512,11 +512,11 @@ If you wish, you can run the buildbot unit test suite like this: @example -PYTHONPATH=. trial -v buildbot.test +PYTHONPATH=. trial buildbot.test @end example -This should run up to 175 tests, depending upon what VC tools you have -installed. On my desktop machine it takes about four minutes to +This should run up to 192 tests, depending upon what VC tools you have +installed. On my desktop machine it takes about five minutes to complete. Nothing should fail, a few might be skipped. If any of the tests fail, you should stop and investigate the cause before continuing the installation process, as it will probably be easier to From warner at users.sourceforge.net Mon Apr 24 09:56:21 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:56:21 +0000 Subject: [Buildbot-commits] buildbot/docs buildbot.texinfo,1.46,1.47 Message-ID: Update of /cvsroot/buildbot/buildbot/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1493/docs Modified Files: buildbot.texinfo Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-516 Creator: Brian Warner docs: updated branch-name examples to be a bit more realistic * docs/buildbot.texinfo (Attributes of Changes): updated branch-name examples to be a bit more realistic, SF#1475240 by Stephen Davis. Index: buildbot.texinfo =================================================================== RCS file: /cvsroot/buildbot/buildbot/docs/buildbot.texinfo,v retrieving revision 1.46 retrieving revision 1.47 diff -u -d -r1.46 -r1.47 --- buildbot.texinfo 24 Apr 2006 09:49:24 -0000 1.46 +++ buildbot.texinfo 24 Apr 2006 09:56:19 -0000 1.47 @@ -1294,11 +1294,11 @@ @item CVS branch='warner-newfeature', files=['src/foo.c'] @item SVN -branch='branches/trunk', files=['src/foo.c'] +branch='branches/warner-newfeature', files=['src/foo.c'] @item Darcs -branch='branches/trunk', files=['src/foo.c'] +branch='warner-newfeature', files=['src/foo.c'] @item Mercurial -branch='branches/trunk', files=['src/foo.c'] +branch='warner-newfeature', files=['src/foo.c'] @item Arch/Bazaar branch='buildbot--usebranches--0', files=['buildbot/master.py'] @end table From warner at users.sourceforge.net Mon Apr 24 09:56:21 2006 From: warner at users.sourceforge.net (Brian Warner) Date: Mon, 24 Apr 2006 09:56:21 +0000 Subject: [Buildbot-commits] buildbot ChangeLog,1.601,1.602 Message-ID: Update of /cvsroot/buildbot/buildbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1493 Modified Files: ChangeLog Log Message: Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-516 Creator: Brian Warner docs: updated branch-name examples to be a bit more realistic * docs/buildbot.texinfo (Attributes of Changes): updated branch-name examples to be a bit more realistic, SF#1475240 by Stephen Davis. Index: ChangeLog =================================================================== RCS file: /cvsroot/buildbot/buildbot/ChangeLog,v retrieving revision 1.601 retrieving revision 1.602 diff -u -d -r1.601 -r1.602 --- ChangeLog 24 Apr 2006 09:49:25 -0000 1.601 +++ ChangeLog 24 Apr 2006 09:56:19 -0000 1.602 @@ -2,6 +2,8 @@ * docs/buildbot.texinfo (Installing the code): update trial invocation, SF#1469116 by Niklaus Giger. + (Attributes of Changes): updated branch-name examples to be + a bit more realistic, SF#1475240 by Stephen Davis. * contrib/windows/buildbot2.bat: utility wrapper for windows developers, contributed by Nick Trout (after a year of neglect..