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

Source Code for Module buildbot.steps.source.cvs

  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  from email.Utils import formatdate 
 17  import time 
 18   
 19  from twisted.python import log 
 20  from twisted.internet import defer 
 21   
 22  from buildbot.process import buildstep 
 23  from buildbot.steps.source import Source 
 24  from buildbot.interfaces import BuildSlaveTooOldError 
25 26 -class CVS(Source):
27 28 name = "cvs" 29 30 renderables = [ "cvsroot" ] 31
32 - def __init__(self, cvsroot=None, cvsmodule='', mode='incremental', 33 method=None, branch=None, global_options=[], extra_options=[], 34 login=None, **kwargs):
35 36 self.cvsroot = cvsroot 37 self.cvsmodule = cvsmodule 38 self.branch = branch 39 self.global_options = global_options 40 self.extra_options = extra_options 41 self.login = login 42 self.mode = mode 43 self.method = method 44 self.srcdir = 'source' 45 Source.__init__(self, **kwargs) 46 self.addFactoryArguments(cvsroot=cvsroot, 47 cvsmodule=cvsmodule, 48 mode=mode, 49 method=method, 50 global_options=global_options, 51 extra_options=extra_options, 52 login=login, 53 )
54
55 - def startVC(self, branch, revision, patch):
56 self.revision = revision 57 self.stdio_log = self.addLog("stdio") 58 self.method = self._getMethod() 59 d = self.checkCvs() 60 def checkInstall(cvsInstalled): 61 if not cvsInstalled: 62 raise BuildSlaveTooOldError("CVS is not installed on slave") 63 return 0
64 d.addCallback(checkInstall) 65 d.addCallback(self.checkLogin) 66 67 if self.mode == 'incremental': 68 d.addCallback(lambda _: self.incremental()) 69 elif self.mode == 'full': 70 d.addCallback(lambda _: self.full()) 71 72 d.addCallback(self.parseGotRevision) 73 d.addCallback(self.finish) 74 d.addErrback(self.failed) 75 return d
76 77 @defer.deferredGenerator
78 - def incremental(self):
79 wfd = defer.waitForDeferred(self._sourcedirIsUpdatable()) 80 yield wfd 81 updatable = wfd.getResult() 82 if updatable: 83 d = self.doUpdate() 84 else: 85 d = self.doCheckout(self.workdir) 86 wfd = defer.waitForDeferred(d) 87 yield wfd 88 yield wfd.getResult() 89 return
90 91 @defer.deferredGenerator
92 - def full(self):
93 if self.method == 'clobber': 94 wfd = defer.waitForDeferred(self.clobber()) 95 yield wfd 96 yield wfd.getResult() 97 return 98 99 elif self.method == 'copy': 100 wfd = defer.waitForDeferred(self.copy()) 101 yield wfd 102 yield wfd.getResult() 103 return 104 105 wfd = defer.waitForDeferred(self._sourcedirIsUpdatable()) 106 yield wfd 107 updatable = wfd.getResult() 108 if not updatable: 109 log.msg("CVS repo not present, making full checkout") 110 d = self.doCheckout(self.workdir) 111 elif self.method == 'clean': 112 d = self.clean() 113 elif self.method == 'fresh': 114 d = self.fresh() 115 else: 116 raise ValueError("Unknown method, check your configuration") 117 wfd = defer.waitForDeferred(d) 118 yield wfd 119 yield wfd.getResult()
120
121 - def clobber(self):
122 cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir, 123 'logEnviron': self.logEnviron}) 124 cmd.useLog(self.stdio_log, False) 125 d = self.runCommand(cmd) 126 def checkRemoval(res): 127 if res != 0: 128 raise RuntimeError("Failed to delete directory") 129 return res
130 d.addCallback(lambda _: checkRemoval(cmd.rc)) 131 d.addCallback(lambda _: self.doCheckout(self.workdir)) 132 return d 133
134 - def fresh(self, ):
135 d = self.purge(True) 136 d.addCallback(lambda _: self.doUpdate()) 137 return d
138
139 - def clean(self, ):
140 d = self.purge(False) 141 d.addCallback(lambda _: self.doUpdate()) 142 return d
143
144 - def copy(self):
145 cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir, 146 'logEnviron': self.logEnviron}) 147 cmd.useLog(self.stdio_log, False) 148 d = self.runCommand(cmd) 149 self.workdir = 'source' 150 d.addCallback(lambda _: self.incremental()) 151 def copy(_): 152 cmd = buildstep.RemoteCommand('cpdir', 153 {'fromdir': 'source', 154 'todir':'build', 155 'logEnviron': self.logEnviron,}) 156 cmd.useLog(self.stdio_log, False) 157 d = self.runCommand(cmd) 158 return d
159 d.addCallback(copy) 160 def resetWorkdir(_): 161 self.workdir = 'build' 162 return 0 163 d.addCallback(resetWorkdir) 164 return d 165
166 - def purge(self, ignore_ignores):
167 command = ['cvsdiscard'] 168 if ignore_ignores: 169 command += ['--ignore'] 170 cmd = buildstep.RemoteShellCommand(self.workdir, command, 171 env=self.env, 172 logEnviron=self.logEnviron) 173 cmd.useLog(self.stdio_log, False) 174 d = self.runCommand(cmd) 175 def evaluate(rc): 176 if rc != 0: 177 raise buildstep.BuildStepFailed() 178 return rc
179 d.addCallback(lambda _: evaluate(cmd.rc)) 180 return d 181
182 - def doCheckout(self, dir):
183 command = ['-d', self.cvsroot, '-z3', 'checkout', '-d', dir, 184 self.cvsmodule] 185 command = self.global_options + command + self.extra_options 186 if self.branch: 187 command += ['-r', self.branch] 188 if self.revision: 189 command += ['-D', self.revision] 190 d = self._dovccmd(command, '') 191 return d
192
193 - def doUpdate(self):
194 command = ['-z3', 'update', '-dP'] 195 if self.branch: 196 command += ['-r', self.branch] 197 if self.revision: 198 command += ['-D', self.revision] 199 d = self._dovccmd(command) 200 return d
201
202 - def finish(self, res):
203 d = defer.succeed(res) 204 def _gotResults(results): 205 self.setStatus(self.cmd, results) 206 return results
207 d.addCallback(_gotResults) 208 d.addCallbacks(self.finished, self.checkDisconnect) 209 return d 210
211 - def checkLogin(self, _):
212 if self.login: 213 d = defer.succeed(0) 214 else: 215 d = self._dovccmd(['-d', self.cvsroot, 'login']) 216 def setLogin(res): 217 # this happens only if the login command succeeds. 218 self.login = True 219 return res
220 d.addCallback(setLogin) 221 222 return d 223
224 - def _dovccmd(self, command, workdir=None):
225 if workdir is None: 226 workdir = self.workdir 227 if not command: 228 raise ValueError("No command specified") 229 cmd = buildstep.RemoteShellCommand(workdir, ['cvs'] + 230 command, 231 env=self.env, 232 logEnviron=self.logEnviron) 233 cmd.useLog(self.stdio_log, False) 234 d = self.runCommand(cmd) 235 def evaluateCommand(cmd): 236 if cmd.rc != 0: 237 log.msg("Source step failed while running command %s" % cmd) 238 raise buildstep.BuildStepFailed() 239 return cmd.rc
240 d.addCallback(lambda _: evaluateCommand(cmd)) 241 return d 242
243 - def _sourcedirIsUpdatable(self):
244 cmd = buildstep.RemoteCommand('stat', {'file': self.workdir + '/CVS', 245 'logEnviron': self.logEnviron}) 246 cmd.useLog(self.stdio_log, False) 247 d = self.runCommand(cmd) 248 def _fail(tmp): 249 if cmd.rc != 0: 250 return False 251 return True
252 d.addCallback(_fail) 253 return d 254
255 - def parseGotRevision(self, res):
256 revision = time.strftime("%Y-%m-%d %H:%M:%S +0000", time.gmtime()) 257 self.setProperty('got_revision', revision, 'Source') 258 return res
259
260 - def checkCvs(self):
261 d = self._dovccmd(['--version']) 262 def check(res): 263 if res == 0: 264 return True 265 return False
266 d.addCallback(check) 267 return d 268
269 - def _getMethod(self):
270 if self.method is not None and self.mode != 'incremental': 271 return self.method 272 elif self.mode == 'incremental': 273 return None 274 elif self.method is None and self.mode == 'full': 275 return 'fresh'
276
277 - def computeSourceRevision(self, changes):
278 if not changes: 279 return None 280 lastChange = max([c.when for c in changes]) 281 lastSubmit = max([br.submittedAt for br in self.build.requests]) 282 when = (lastChange + lastSubmit) / 2 283 return formatdate(when)
284