Package buildslave :: Package commands :: Module bzr
[frames] | no frames]

Source Code for Module buildslave.commands.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 buildslave.commands.base import SourceBaseCommand 
 22  from buildslave import runprocess 
 23   
 24   
25 -class Bzr(SourceBaseCommand):
26 """bzr-specific VC operation. In addition to the arguments 27 handled by SourceBaseCommand, this command reads the following keys: 28 29 ['repourl'] (required): the Bzr repository string 30 ['forceSharedRepo']: force this to a shared repo 31 """ 32 33 header = "bzr operation" 34
35 - def setup(self, args):
36 SourceBaseCommand.setup(self, args) 37 self.repourl = args['repourl'] 38 self.sourcedata = "%s\n" % self.repourl 39 self.revision = self.args.get('revision') 40 self.forceSharedRepo = args.get('forceSharedRepo')
41
42 - def sourcedirIsUpdateable(self):
43 # checking out a specific revision requires a full 'bzr checkout' 44 return (not self.revision and 45 not self.sourcedirIsPatched() and 46 os.path.isdir(os.path.join(self.builder.basedir, 47 self.srcdir, ".bzr")))
48
49 - def start(self):
50 def cont(res): 51 # Continue with start() method in superclass. 52 return SourceBaseCommand.start(self)
53 54 if self.forceSharedRepo: 55 d = self.doForceSharedRepo(); 56 d.addCallback(cont) 57 return d 58 else: 59 return cont(None)
60
61 - def doVCUpdate(self):
62 bzr = self.getCommand('bzr') 63 assert not self.revision 64 # update: possible for mode in ('copy', 'update') 65 srcdir = os.path.join(self.builder.basedir, self.srcdir) 66 command = [bzr, 'update'] 67 c = runprocess.RunProcess(self.builder, command, srcdir, 68 sendRC=False, timeout=self.timeout, 69 maxTime=self.maxTime, usePTY=False) 70 self.command = c 71 return c.start()
72
73 - def doVCFull(self):
74 bzr = self.getCommand('bzr') 75 76 # checkout or export 77 d = self.builder.basedir 78 if self.mode == "export": 79 # exporting in bzr requires a separate directory 80 return self.doVCExport() 81 # originally I added --lightweight here, but then 'bzr revno' is 82 # wrong. The revno reported in 'bzr version-info' is correct, 83 # however. Maybe this is a bzr bug? 84 # 85 # In addition, you cannot perform a 'bzr update' on a repo pulled 86 # from an HTTP repository that used 'bzr checkout --lightweight'. You 87 # get a "ERROR: Cannot lock: transport is read only" when you try. 88 # 89 # So I won't bother using --lightweight for now. 90 91 command = [bzr, 'checkout'] 92 if self.revision: 93 command.append('--revision') 94 command.append(str(self.revision)) 95 command.append(self.repourl) 96 command.append(self.srcdir) 97 98 c = runprocess.RunProcess(self.builder, command, d, 99 sendRC=False, timeout=self.timeout, 100 maxTime=self.maxTime, usePTY=False) 101 self.command = c 102 d = c.start() 103 return d
104
105 - def doVCExport(self):
106 bzr = self.getCommand('bzr') 107 tmpdir = os.path.join(self.builder.basedir, "export-temp") 108 srcdir = os.path.join(self.builder.basedir, self.srcdir) 109 command = [bzr, 'checkout', '--lightweight'] 110 if self.revision: 111 command.append('--revision') 112 command.append(str(self.revision)) 113 command.append(self.repourl) 114 command.append(tmpdir) 115 c = runprocess.RunProcess(self.builder, command, self.builder.basedir, 116 sendRC=False, timeout=self.timeout, 117 maxTime=self.maxTime, usePTY=False) 118 self.command = c 119 d = c.start() 120 def _export(res): 121 command = [bzr, 'export', srcdir] 122 c = runprocess.RunProcess(self.builder, command, tmpdir, 123 sendRC=False, timeout=self.timeout, 124 maxTime=self.maxTime, usePTY=False) 125 self.command = c 126 return c.start()
127 d.addCallback(_export) 128 return d 129
130 - def doForceSharedRepo(self):
131 bzr = self.getCommand('bzr') 132 133 # Don't send stderr. When there is no shared repo, this might confuse 134 # users, as they will see a bzr error message. But having no shared 135 # repo is not an error, just an indication that we need to make one. 136 c = runprocess.RunProcess(self.builder, [bzr, 'info', '.'], 137 self.builder.basedir, 138 sendStderr=False, sendRC=False, usePTY=False) 139 d = c.start() 140 def afterCheckSharedRepo(res): 141 if type(res) is int and res != 0: 142 log.msg("No shared repo found, creating it") 143 # bzr info fails, try to create shared repo. 144 c = runprocess.RunProcess(self.builder, [bzr, 'init-repo', '.'], 145 self.builder.basedir, 146 sendRC=False, usePTY=False) 147 self.command = c 148 return c.start() 149 else: 150 return defer.succeed(res)
151 d.addCallback(afterCheckSharedRepo) 152 return d 153
154 - def get_revision_number(self, out):
155 # it feels like 'bzr revno' sometimes gives different results than 156 # the 'revno:' line from 'bzr version-info', and the one from 157 # version-info is more likely to be correct. 158 for line in out.split("\n"): 159 colon = line.find(":") 160 if colon != -1: 161 key, value = line[:colon], line[colon+2:] 162 if key == "revno": 163 return int(value) 164 raise ValueError("unable to find revno: in bzr output: '%s'" % out)
165
166 - def parseGotRevision(self):
167 bzr = self.getCommand('bzr') 168 command = [bzr, "version-info"] 169 c = runprocess.RunProcess(self.builder, command, 170 os.path.join(self.builder.basedir, self.srcdir), 171 environ=self.env, 172 sendStdout=False, sendStderr=False, sendRC=False, 173 keepStdout=True, usePTY=False) 174 d = c.start() 175 def _parse(res): 176 try: 177 return self.get_revision_number(c.stdout) 178 except ValueError: 179 msg =("Bzr.parseGotRevision unable to parse output " 180 "of bzr version-info: '%s'" % c.stdout.strip()) 181 log.msg(msg) 182 self.sendStatus({'header': msg + "\n"}) 183 return None
184 d.addCallback(_parse) 185 return d 186