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, logEnviron=self.logEnviron, 70 usePTY=False) 71 self.command = c 72 return c.start()
73
74 - def doVCFull(self):
75 bzr = self.getCommand('bzr') 76 77 # checkout or export 78 d = self.builder.basedir 79 if self.mode == "export": 80 # exporting in bzr requires a separate directory 81 return self.doVCExport() 82 # originally I added --lightweight here, but then 'bzr revno' is 83 # wrong. The revno reported in 'bzr version-info' is correct, 84 # however. Maybe this is a bzr bug? 85 # 86 # In addition, you cannot perform a 'bzr update' on a repo pulled 87 # from an HTTP repository that used 'bzr checkout --lightweight'. You 88 # get a "ERROR: Cannot lock: transport is read only" when you try. 89 # 90 # So I won't bother using --lightweight for now. 91 92 command = [bzr, 'checkout'] 93 if self.revision: 94 command.append('--revision') 95 command.append(str(self.revision)) 96 command.append(self.repourl) 97 command.append(self.srcdir) 98 99 c = runprocess.RunProcess(self.builder, command, d, 100 sendRC=False, timeout=self.timeout, 101 maxTime=self.maxTime, logEnviron=self.logEnviron, 102 usePTY=False) 103 self.command = c 104 d = c.start() 105 return d
106
107 - def doVCExport(self):
108 bzr = self.getCommand('bzr') 109 tmpdir = os.path.join(self.builder.basedir, "export-temp") 110 srcdir = os.path.join(self.builder.basedir, self.srcdir) 111 command = [bzr, 'checkout', '--lightweight'] 112 if self.revision: 113 command.append('--revision') 114 command.append(str(self.revision)) 115 command.append(self.repourl) 116 command.append(tmpdir) 117 c = runprocess.RunProcess(self.builder, command, self.builder.basedir, 118 sendRC=False, timeout=self.timeout, 119 maxTime=self.maxTime, logEnviron=self.logEnviron, 120 usePTY=False) 121 self.command = c 122 d = c.start() 123 def _export(res): 124 command = [bzr, 'export', srcdir] 125 c = runprocess.RunProcess(self.builder, command, tmpdir, 126 sendRC=False, timeout=self.timeout, 127 maxTime=self.maxTime, logEnviron=self.logEnviron, 128 usePTY=False) 129 self.command = c 130 return c.start()
131 d.addCallback(_export) 132 return d 133
134 - def doForceSharedRepo(self):
135 bzr = self.getCommand('bzr') 136 137 # Don't send stderr. When there is no shared repo, this might confuse 138 # users, as they will see a bzr error message. But having no shared 139 # repo is not an error, just an indication that we need to make one. 140 c = runprocess.RunProcess(self.builder, [bzr, 'info', '.'], 141 self.builder.basedir, 142 sendStderr=False, sendRC=False, 143 logEnviron=self.logEnviron,usePTY=False) 144 d = c.start() 145 def afterCheckSharedRepo(res): 146 if type(res) is int and res != 0: 147 log.msg("No shared repo found, creating it") 148 # bzr info fails, try to create shared repo. 149 c = runprocess.RunProcess(self.builder, [bzr, 'init-repo', '.'], 150 self.builder.basedir, 151 sendRC=False, logEnviron=self.logEnviron, 152 usePTY=False) 153 self.command = c 154 return c.start() 155 else: 156 return defer.succeed(res)
157 d.addCallback(afterCheckSharedRepo) 158 return d 159
160 - def get_revision_number(self, out):
161 # it feels like 'bzr revno' sometimes gives different results than 162 # the 'revno:' line from 'bzr version-info', and the one from 163 # version-info is more likely to be correct. 164 for line in out.split("\n"): 165 colon = line.find(":") 166 if colon != -1: 167 key, value = line[:colon], line[colon+2:] 168 if key == "revno": 169 return int(value) 170 raise ValueError("unable to find revno: in bzr output: '%s'" % out)
171
172 - def parseGotRevision(self):
173 bzr = self.getCommand('bzr') 174 command = [bzr, "version-info"] 175 c = runprocess.RunProcess(self.builder, command, 176 os.path.join(self.builder.basedir, self.srcdir), 177 environ=self.env, 178 sendStdout=False, sendStderr=False, sendRC=False, 179 keepStdout=True, logEnviron=self.logEnviron, 180 usePTY=False) 181 d = c.start() 182 def _parse(res): 183 try: 184 return self.get_revision_number(c.stdout) 185 except ValueError: 186 msg =("Bzr.parseGotRevision unable to parse output " 187 "of bzr version-info: '%s'" % c.stdout.strip()) 188 log.msg(msg) 189 self.sendStatus({'header': msg + "\n"}) 190 return None
191 d.addCallback(_parse) 192 return d 193