1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17 import re
18
19 from twisted.internet import defer
20
21 from buildslave.commands.base import SourceBaseCommand
22 from buildslave import runprocess
23 from buildslave.commands.base import AbandonChain
24
25
26 -class Repo(SourceBaseCommand):
27 """Repo specific VC operation. In addition to the arguments
28 handled by SourceBaseCommand, this command reads the following keys:
29
30 ['manifest_url'] (required): The manifests repo repository.
31 ['manifest_branch'] (optional): Which manifest repo version (i.e. branch or tag)
32 to retrieve. Default: "master".
33 ['manifest_file'] (optional): Which manifest file to use. Default: "default.xml".
34 ['tarball'] (optional): The tarball base to accelerate the fetch.
35 ['repo_downloads'] (optional): Repo downloads to do. Computer from GerritChangeSource
36 and forced build properties.
37 """
38
39 header = "repo operation"
40
42 SourceBaseCommand.setup(self, args)
43 self.manifest_url = args.get('manifest_url')
44 self.manifest_branch = args.get('manifest_branch')
45 self.manifest_file = args.get('manifest_file')
46 self.tarball = args.get('tarball')
47 self.repo_downloads = args.get('repo_downloads')
48
49
50 self.repo_downloaded = ""
51
52 self.sourcedata = "%s %s %s" % (self.manifest_url, self.manifest_branch, self.manifest_file)
53 self.re_change = re.compile(".* refs/changes/\d\d/(\d+)/(\d+) -> FETCH_HEAD$")
54 self.re_head = re.compile("^HEAD is now at ([0-9a-f]+)...")
55
58
60 print os.path.join(self._fullSrcdir(), ".repo")
61 print os.path.isdir(os.path.join(self._fullSrcdir(), ".repo"))
62 return os.path.isdir(os.path.join(self._fullSrcdir(), ".repo"))
63
64 - def _repoCmd(self, command, cb=None, abandonOnFailure=True, **kwargs):
76
86
87 - def _gitCmd(self, subdir, cmds, callback):
96
103
105 os.makedirs(self._fullSrcdir())
106 if self.tarball and os.path.exists(self.tarball):
107 return self._tarCmd(['-xvzf', self.tarball], self._doInit)
108 else:
109 return self._doInit(None)
110
112
113 if os.path.exists(os.path.join(self._fullSrcdir(), ".repo/project.list")):
114 os.unlink(os.path.join(self._fullSrcdir(), ".repo/project.list"))
115 return self._repoCmd(['init', '-u', self.manifest_url, '-b', self.manifest_branch, '-m', self.manifest_file], self._didInit)
116
119
121 command = ['forall', '-c', 'git', 'clean', '-f', '-d', '-x']
122 return self._repoCmd(command, self._doClean2, abandonOnFailure=False)
123
125 command = ['clean', '-f', '-d', '-x']
126 return self._gitCmd(".repo/manifests",command, self._doSync)
127
129 command = ['sync']
130 self.sendStatus({"header": "synching manifest %s from branch %s from %s\n"
131 % (self.manifest_file, self.manifest_branch, self.manifest_url)})
132 return self._repoCmd(command, self._didSync)
133
135 if self.tarball and not os.path.exists(self.tarball):
136 return self._tarCmd(['-cvzf', self.tarball, ".repo"], self._doDownload)
137 else:
138 return self._doDownload(None)
139
141 if hasattr(self.command, 'stderr') and self.command.stderr:
142 lines = self.command.stderr.split('\n')
143 if len(lines) > 2:
144 match1 = self.re_change.match(lines[1])
145 match2 = self.re_head.match(lines[-2])
146 if match1 and match2:
147 self.repo_downloaded += "%s/%s %s " % (match1.group(1), match1.group(2), match2.group(1))
148
149 if self.repo_downloads:
150
151 download = self.repo_downloads.pop(0)
152 command = ['download'] + download.split(' ')
153 self.sendStatus({"header": "downloading changeset %s\n"
154 % (download)})
155 return self._repoCmd(command, self._doDownload, keepStderr=True)
156
157 if self.repo_downloaded:
158 self.sendStatus({"repo_downloaded": self.repo_downloaded[:-1]})
159 return defer.succeed(0)
160
162
163
164 if hasattr(self.command, 'stderr'):
165 if "Couldn't find remote ref" in self.command.stderr:
166 raise AbandonChain(-1)
167