Package buildbot :: Package steps :: Package source :: Module bzr
[frames] | no frames]

Source Code for Module buildbot.steps.source.bzr

  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  import os 
 17   
 18  from twisted.python import log 
 19  from twisted.internet import defer 
 20   
 21  from buildbot.process import buildstep 
 22  from buildbot.steps.source.base import Source 
 23  from buildbot.interfaces import BuildSlaveTooOldError 
24 25 -class Bzr(Source):
26 27 name = 'bzr' 28 renderables = [ 'repourl', 'baseURL' ] 29
30 - def __init__(self, repourl=None, baseURL=None, mode='incremental', 31 method=None, defaultBranch=None, **kwargs):
32 33 self.repourl = repourl 34 self.baseURL = baseURL 35 self.branch = defaultBranch 36 self.mode = mode 37 self.method = method 38 Source.__init__(self, **kwargs) 39 if repourl and baseURL: 40 raise ValueError("you must provide exactly one of repourl and" 41 " baseURL") 42 43 if repourl is None and baseURL is None: 44 raise ValueError("you must privide at least one of repourl and" 45 " baseURL") 46 47 if baseURL is not None and defaultBranch is None: 48 raise ValueError("you must provide defaultBranch with baseURL") 49 50 assert self.mode in ['incremental', 'full'] 51 52 if self.mode == 'full': 53 assert self.method in ['clean', 'fresh', 'clobber', 'copy', None]
54
55 - def startVC(self, branch, revision, patch):
56 if branch: 57 self.branch = branch 58 self.revision = revision 59 self.method = self._getMethod() 60 self.stdio_log = self.addLog("stdio") 61 62 if self.repourl is None: 63 self.repourl = os.path.join(self.baseURL, self.branch) 64 65 d = self.checkBzr() 66 def checkInstall(bzrInstalled): 67 if not bzrInstalled: 68 raise BuildSlaveTooOldError("bzr is not installed on slave") 69 return 0
70 71 d.addCallback(checkInstall) 72 if self.mode == 'full': 73 d.addCallback(lambda _: self.full()) 74 elif self.mode == 'incremental': 75 d.addCallback(lambda _: self.incremental()) 76 77 d.addCallback(self.parseGotRevision) 78 d.addCallback(self.finish) 79 d.addErrback(self.failed) 80 return d
81
82 - def incremental(self):
83 d = self._sourcedirIsUpdatable() 84 def _cmd(updatable): 85 if updatable: 86 command = ['update'] 87 else: 88 command = ['checkout', self.repourl, '.'] 89 90 if self.revision: 91 command.extend(['-r', self.revision]) 92 return command
93 94 d.addCallback(_cmd) 95 d.addCallback(self._dovccmd) 96 return d 97 98 @defer.inlineCallbacks
99 - def full(self):
100 if self.method == 'clobber': 101 yield self.clobber() 102 return 103 elif self.method == 'copy': 104 self.workdir = 'source' 105 yield self.copy() 106 return 107 108 updatable = self._sourcedirIsUpdatable() 109 if not updatable: 110 log.msg("No bzr repo present, making full checkout") 111 yield self._doFull() 112 elif self.method == 'clean': 113 yield self.clean() 114 elif self.method == 'fresh': 115 yield self.fresh() 116 else: 117 raise ValueError("Unknown method, check your configuration")
118
119 - def clobber(self):
120 cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir, 121 'logEnviron': self.logEnviron,}) 122 cmd.useLog(self.stdio_log, False) 123 d = self.runCommand(cmd) 124 def checkRemoval(res): 125 if res != 0: 126 raise RuntimeError("Failed to delete directory") 127 return res
128 d.addCallback(lambda _: checkRemoval(cmd.rc)) 129 d.addCallback(lambda _: self._doFull()) 130 return d 131
132 - def copy(self):
133 cmd = buildstep.RemoteCommand('rmdir', {'dir': 'build', 134 'logEnviron': self.logEnviron,}) 135 cmd.useLog(self.stdio_log, False) 136 d = self.runCommand(cmd) 137 d.addCallback(lambda _: self.incremental()) 138 def copy(_): 139 cmd = buildstep.RemoteCommand('cpdir', 140 {'fromdir': 'source', 141 'todir':'build', 142 'logEnviron': self.logEnviron,}) 143 cmd.useLog(self.stdio_log, False) 144 d = self.runCommand(cmd) 145 return d
146 d.addCallback(copy) 147 return d 148
149 - def clean(self):
150 d = self._dovccmd(['clean-tree', '--ignored', '--force']) 151 command = ['update'] 152 if self.revision: 153 command.extend(['-r', self.revision]) 154 d.addCallback(lambda _: self._dovccmd(command)) 155 return d
156
157 - def fresh(self):
158 d = self._dovccmd(['clean-tree', '--force']) 159 command = ['update'] 160 if self.revision: 161 command.extend(['-r', self.revision]) 162 d.addCallback(lambda _: self._dovccmd(command)) 163 return d
164
165 - def _doFull(self):
166 command = ['checkout', self.repourl, '.'] 167 if self.revision: 168 command.extend(['-r', self.revision]) 169 d = self._dovccmd(command) 170 return d
171
172 - def finish(self, res):
173 d = defer.succeed(res) 174 def _gotResults(results): 175 self.setStatus(self.cmd, results) 176 log.msg("Closing log, sending result of the command %s " % \ 177 (self.cmd)) 178 return results
179 d.addCallback(_gotResults) 180 d.addCallbacks(self.finished, self.checkDisconnect) 181 return d 182
183 - def _sourcedirIsUpdatable(self):
184 cmd = buildstep.RemoteCommand('stat', {'file': self.workdir + '/.bzr', 185 'logEnviron': self.logEnviron,}) 186 cmd.useLog(self.stdio_log, False) 187 d = self.runCommand(cmd) 188 def _fail(tmp): 189 if cmd.didFail(): 190 return False 191 return True
192 d.addCallback(_fail) 193 return d 194
195 - def computeSourceRevision(self, changes):
196 if not changes: 197 return None 198 lastChange = max([int(c.revision) for c in changes]) 199 return lastChange
200
201 - def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False):
202 cmd = buildstep.RemoteShellCommand(self.workdir, ['bzr'] + command, 203 env=self.env, 204 logEnviron=self.logEnviron, 205 timeout=self.timeout, 206 collectStdout=collectStdout) 207 cmd.useLog(self.stdio_log, False) 208 d = self.runCommand(cmd) 209 def evaluateCommand(cmd): 210 if abandonOnFailure and cmd.didFail(): 211 log.msg("Source step failed while running command %s" % cmd) 212 raise buildstep.BuildStepFailed() 213 if collectStdout: 214 return cmd.stdout 215 else: 216 return cmd.rc
217 d.addCallback(lambda _: evaluateCommand(cmd)) 218 return d 219
220 - def checkBzr(self):
221 d = self._dovccmd(['--version']) 222 def check(res): 223 if res == 0: 224 return True 225 return False
226 d.addCallback(check) 227 return d 228
229 - def _getMethod(self):
230 if self.method is not None and self.mode != 'incremental': 231 return self.method 232 elif self.mode == 'incremental': 233 return None 234 elif self.method is None and self.mode == 'full': 235 return 'fresh'
236
237 - def parseGotRevision(self, _):
238 d = self._dovccmd(["version-info", "--custom", "--template='{revno}"], 239 collectStdout=True) 240 def setrev(stdout): 241 revision = stdout.strip("'") 242 try: 243 revision = int(revision) 244 except ValueError: 245 log.msg("Invalid revision number") 246 raise buildstep.BuildStepFailed() 247 248 log.msg("Got Git revision %s" % (revision, )) 249 self.updateSourceProperty('got_revision', revision) 250 return 0
251 d.addCallback(setrev) 252 return d 253