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.base 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.base.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, request):
63 """Create a new Build instance. 64 @param request: a L{base.BuildRequest} describing what is to be built 65 """ 66 b = self.buildClass(request) 67 b.useProgress = self.useProgress 68 b.workdir = self.workdir 69 b.setStepFactories(self.steps) 70 return b
71
72 - def addStep(self, step_or_factory, **kwargs):
73 if isinstance(step_or_factory, BuildStep): 74 if kwargs: 75 raise ArgumentsInTheWrongPlace() 76 s = step_or_factory.getStepFactory() 77 elif type(step_or_factory) == type(BuildStep) and \ 78 issubclass(step_or_factory, BuildStep): 79 s = (step_or_factory, dict(kwargs)) 80 else: 81 raise ValueError('%r is not a BuildStep nor BuildStep subclass' % step_or_factory) 82 self.steps.append(s)
83
84 - def addSteps(self, steps):
85 for s in steps: 86 self.addStep(s)
87 88 # BuildFactory subclasses for common build tools 89
90 -class GNUAutoconf(BuildFactory):
91 - def __init__(self, source, configure="./configure", 92 configureEnv={}, 93 configureFlags=[], 94 compile=["make", "all"], 95 test=["make", "check"]):
96 BuildFactory.__init__(self, [source]) 97 if configure is not None: 98 # we either need to wind up with a string (which will be 99 # space-split), or with a list of strings (which will not). The 100 # list of strings is the preferred form. 101 if type(configure) is str: 102 if configureFlags: 103 assert not " " in configure # please use list instead 104 command = [configure] + configureFlags 105 else: 106 command = configure 107 else: 108 assert isinstance(configure, (list, tuple)) 109 command = configure + configureFlags 110 self.addStep(Configure, command=command, env=configureEnv) 111 if compile is not None: 112 self.addStep(Compile, command=compile) 113 if test is not None: 114 self.addStep(Test, command=test)
115
116 -class CPAN(BuildFactory):
117 - def __init__(self, source, perl="perl"):
118 BuildFactory.__init__(self, [source]) 119 self.addStep(Configure, command=[perl, "Makefile.PL"]) 120 self.addStep(Compile, command=["make"]) 121 self.addStep(PerlModuleTest, command=["make", "test"])
122
123 -class Distutils(BuildFactory):
124 - def __init__(self, source, python="python", test=None):
125 BuildFactory.__init__(self, [source]) 126 self.addStep(Compile, command=[python, "./setup.py", "build"]) 127 if test is not None: 128 self.addStep(Test, command=test)
129
130 -class Trial(BuildFactory):
131 """Build a python module that uses distutils and trial. Set 'tests' to 132 the module in which the tests can be found, or set useTestCaseNames=True 133 to always have trial figure out which tests to run (based upon which 134 files have been changed). 135 136 See docs/factories.xhtml for usage samples. Not all of the Trial 137 BuildStep options are available here, only the most commonly used ones. 138 To get complete access, you will need to create a custom 139 BuildFactory.""" 140 141 trial = "trial" 142 randomly = False 143 recurse = False 144
145 - def __init__(self, source, 146 buildpython=["python"], trialpython=[], trial=None, 147 testpath=".", randomly=None, recurse=None, 148 tests=None, useTestCaseNames=False, env=None):
149 BuildFactory.__init__(self, [source]) 150 assert tests or useTestCaseNames, "must use one or the other" 151 if trial is not None: 152 self.trial = trial 153 if randomly is not None: 154 self.randomly = randomly 155 if recurse is not None: 156 self.recurse = recurse 157 158 from buildbot.steps.python_twisted import Trial 159 buildcommand = buildpython + ["./setup.py", "build"] 160 self.addStep(Compile, command=buildcommand, env=env) 161 self.addStep(Trial, 162 python=trialpython, trial=self.trial, 163 testpath=testpath, 164 tests=tests, testChanges=useTestCaseNames, 165 randomly=self.randomly, 166 recurse=self.recurse, 167 env=env, 168 )
169 170 171 # compatibility classes, will go away. Note that these only offer 172 # compatibility at the constructor level: if you have subclassed these 173 # factories, your subclasses are unlikely to still work correctly. 174 175 ConfigurableBuildFactory = BuildFactory 176
177 -class BasicBuildFactory(GNUAutoconf):
178 # really a "GNU Autoconf-created tarball -in-CVS tree" builder 179
180 - def __init__(self, cvsroot, cvsmodule, 181 configure=None, configureEnv={}, 182 compile="make all", 183 test="make check", cvsCopy=False):
184 mode = "clobber" 185 if cvsCopy: 186 mode = "copy" 187 source = s(CVS, cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode) 188 GNUAutoconf.__init__(self, source, 189 configure=configure, configureEnv=configureEnv, 190 compile=compile, 191 test=test)
192
193 -class QuickBuildFactory(BasicBuildFactory):
194 useProgress = False 195
196 - def __init__(self, cvsroot, cvsmodule, 197 configure=None, configureEnv={}, 198 compile="make all", 199 test="make check", cvsCopy=False):
200 mode = "update" 201 source = s(CVS, cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode) 202 GNUAutoconf.__init__(self, source, 203 configure=configure, configureEnv=configureEnv, 204 compile=compile, 205 test=test)
206
207 -class BasicSVN(GNUAutoconf):
208
209 - def __init__(self, svnurl, 210 configure=None, configureEnv={}, 211 compile="make all", 212 test="make check"):
213 source = s(SVN, svnurl=svnurl, mode="update") 214 GNUAutoconf.__init__(self, source, 215 configure=configure, configureEnv=configureEnv, 216 compile=compile, 217 test=test)
218