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