Package buildbot :: Package process :: Module factory
[frames] | no frames]

Source Code for Module buildbot.process.factory

  1  # This file is part of Buildbot.  Buildbot is free software: you can 
  2  # redistribute it and/or modify it under the terms of the GNU General Public 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  5  # This program is distributed in the hope that it will be useful, but WITHOUT 
  6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 10  # You should have received a copy of the GNU General Public License along with 
 11  # this program; if not, write to the Free Software Foundation, Inc., 51 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 15   
 16   
 17  from buildbot import util 
 18  from buildbot.process.build import Build 
 19  from buildbot.process.buildstep import BuildStep 
 20  from buildbot.steps.source import CVS, SVN 
 21  from buildbot.steps.shell import Configure, Compile, Test, PerlModuleTest 
 22   
 23  # deprecated, use BuildFactory.addStep 
24 -def s(steptype, **kwargs):
25 # convenience function for master.cfg files, to create step 26 # specification tuples 27 return (steptype, kwargs)
28
29 -class ArgumentsInTheWrongPlace(Exception):
30 """When calling BuildFactory.addStep(stepinstance), addStep() only takes 31 one argument. You passed extra arguments to addStep(), which you probably 32 intended to pass to your BuildStep constructor instead. For example, you 33 should do:: 34 35 f.addStep(ShellCommand(command=['echo','stuff'], haltOnFailure=True)) 36 37 instead of:: 38 39 f.addStep(ShellCommand(command=['echo','stuff']), haltOnFailure=True) 40 """
41
42 -class BuildFactory(util.ComparableMixin):
43 """ 44 @cvar buildClass: class to use when creating builds 45 @type buildClass: L{buildbot.process.build.Build} 46 """ 47 buildClass = Build 48 useProgress = 1 49 workdir = "build" 50 compare_attrs = ['buildClass', 'steps', 'useProgress', 'workdir'] 51
52 - def __init__(self, steps=None):
53 if steps is None: 54 steps = [] 55 self.steps = [self._makeStepFactory(s) for s in steps]
56
57 - def _makeStepFactory(self, step_or_factory):
58 if isinstance(step_or_factory, BuildStep): 59 return step_or_factory.getStepFactory() 60 return step_or_factory
61
62 - def newBuild(self, requests):
63 """Create a new Build instance. 64 65 @param requests: a list of buildrequest dictionaries describing what is 66 to be built 67 """ 68 b = self.buildClass(requests) 69 b.useProgress = self.useProgress 70 b.workdir = self.workdir 71 b.setStepFactories(self.steps) 72 return b
73
74 - def addStep(self, step_or_factory, **kwargs):
75 if isinstance(step_or_factory, BuildStep): 76 if kwargs: 77 raise ArgumentsInTheWrongPlace() 78 s = step_or_factory.getStepFactory() 79 elif type(step_or_factory) == type(BuildStep) and \ 80 issubclass(step_or_factory, BuildStep): 81 s = (step_or_factory, dict(kwargs)) 82 else: 83 raise ValueError('%r is not a BuildStep nor BuildStep subclass' % step_or_factory) 84 self.steps.append(s)
85
86 - def addSteps(self, steps):
87 for s in steps: 88 self.addStep(s)
89 90 # BuildFactory subclasses for common build tools 91
92 -class GNUAutoconf(BuildFactory):
93 - def __init__(self, source, configure="./configure", 94 configureEnv={}, 95 configureFlags=[], 96 compile=["make", "all"], 97 test=["make", "check"]):
98 BuildFactory.__init__(self, [source]) 99 if configure is not None: 100 # we either need to wind up with a string (which will be 101 # space-split), or with a list of strings (which will not). The 102 # list of strings is the preferred form. 103 if type(configure) is str: 104 if configureFlags: 105 assert not " " in configure # please use list instead 106 command = [configure] + configureFlags 107 else: 108 command = configure 109 else: 110 assert isinstance(configure, (list, tuple)) 111 command = configure + configureFlags 112 self.addStep(Configure, command=command, env=configureEnv) 113 if compile is not None: 114 self.addStep(Compile, command=compile) 115 if test is not None: 116 self.addStep(Test, command=test)
117
118 -class CPAN(BuildFactory):
119 - def __init__(self, source, perl="perl"):
120 BuildFactory.__init__(self, [source]) 121 self.addStep(Configure, command=[perl, "Makefile.PL"]) 122 self.addStep(Compile, command=["make"]) 123 self.addStep(PerlModuleTest, command=["make", "test"])
124
125 -class Distutils(BuildFactory):
126 - def __init__(self, source, python="python", test=None):
127 BuildFactory.__init__(self, [source]) 128 self.addStep(Compile, command=[python, "./setup.py", "build"]) 129 if test is not None: 130 self.addStep(Test, command=test)
131
132 -class Trial(BuildFactory):
133 """Build a python module that uses distutils and trial. Set 'tests' to 134 the module in which the tests can be found, or set useTestCaseNames=True 135 to always have trial figure out which tests to run (based upon which 136 files have been changed). 137 138 See docs/factories.xhtml for usage samples. Not all of the Trial 139 BuildStep options are available here, only the most commonly used ones. 140 To get complete access, you will need to create a custom 141 BuildFactory.""" 142 143 trial = "trial" 144 randomly = False 145 recurse = False 146
147 - def __init__(self, source, 148 buildpython=["python"], trialpython=[], trial=None, 149 testpath=".", randomly=None, recurse=None, 150 tests=None, useTestCaseNames=False, env=None):
151 BuildFactory.__init__(self, [source]) 152 assert tests or useTestCaseNames, "must use one or the other" 153 if trial is not None: 154 self.trial = trial 155 if randomly is not None: 156 self.randomly = randomly 157 if recurse is not None: 158 self.recurse = recurse 159 160 from buildbot.steps.python_twisted import Trial 161 buildcommand = buildpython + ["./setup.py", "build"] 162 self.addStep(Compile, command=buildcommand, env=env) 163 self.addStep(Trial, 164 python=trialpython, trial=self.trial, 165 testpath=testpath, 166 tests=tests, testChanges=useTestCaseNames, 167 randomly=self.randomly, 168 recurse=self.recurse, 169 env=env, 170 )
171 172 173 # compatibility classes, will go away. Note that these only offer 174 # compatibility at the constructor level: if you have subclassed these 175 # factories, your subclasses are unlikely to still work correctly. 176 177 ConfigurableBuildFactory = BuildFactory 178
179 -class BasicBuildFactory(GNUAutoconf):
180 # really a "GNU Autoconf-created tarball -in-CVS tree" builder 181
182 - def __init__(self, cvsroot, cvsmodule, 183 configure=None, configureEnv={}, 184 compile="make all", 185 test="make check", cvsCopy=False):
186 mode = "clobber" 187 if cvsCopy: 188 mode = "copy" 189 source = s(CVS, cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode) 190 GNUAutoconf.__init__(self, source, 191 configure=configure, configureEnv=configureEnv, 192 compile=compile, 193 test=test)
194
195 -class QuickBuildFactory(BasicBuildFactory):
196 useProgress = False 197
198 - def __init__(self, cvsroot, cvsmodule, 199 configure=None, configureEnv={}, 200 compile="make all", 201 test="make check", cvsCopy=False):
202 mode = "update" 203 source = s(CVS, cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode) 204 GNUAutoconf.__init__(self, source, 205 configure=configure, configureEnv=configureEnv, 206 compile=compile, 207 test=test)
208
209 -class BasicSVN(GNUAutoconf):
210
211 - def __init__(self, svnurl, 212 configure=None, configureEnv={}, 213 compile="make all", 214 test="make check"):
215 source = s(SVN, svnurl=svnurl, mode="update") 216 GNUAutoconf.__init__(self, source, 217 configure=configure, configureEnv=configureEnv, 218 compile=compile, 219 test=test)
220