OLD | NEW |
1 # Copyright 2015 The LUCI Authors. All rights reserved. | 1 # Copyright 2015 The LUCI Authors. All rights reserved. |
2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
4 | 4 |
5 import ast | 5 import ast |
6 import collections | 6 import collections |
7 import contextlib | 7 import contextlib |
8 import copy | 8 import copy |
9 import difflib | 9 import difflib |
10 import functools | 10 import functools |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 def __ne__(self, other): | 163 def __ne__(self, other): |
164 return not (self == other) | 164 return not (self == other) |
165 | 165 |
166 def proto_file(self, context): | 166 def proto_file(self, context): |
167 """Returns the ProtoFile of the recipes config file in this repository. | 167 """Returns the ProtoFile of the recipes config file in this repository. |
168 Requires a good checkout.""" | 168 Requires a good checkout.""" |
169 return ProtoFile(InfraRepoConfig().to_recipes_cfg(self.repo_root(context))) | 169 return ProtoFile(InfraRepoConfig().to_recipes_cfg(self.repo_root(context))) |
170 | 170 |
171 | 171 |
172 class GitRepoSpec(RepoSpec): | 172 class GitRepoSpec(RepoSpec): |
173 def __init__(self, project_id, repo, branch, revision, path): | 173 def __init__(self, project_id, repo, branch, revision, path, backend): |
174 self.project_id = project_id | 174 self.project_id = project_id |
175 self.repo = repo | 175 self.repo = repo |
176 self.branch = branch | 176 self.branch = branch |
177 self.revision = revision | 177 self.revision = revision |
178 self.path = path | 178 self.path = path |
| 179 self.backend = backend |
179 | 180 |
180 def __str__(self): | 181 def __str__(self): |
181 return ('GitRepoSpec{project_id="%(project_id)s", repo="%(repo)s", ' | 182 return ('GitRepoSpec{project_id="%(project_id)s", repo="%(repo)s", ' |
182 'branch="%(branch)s", revision="%(revision)s", ' | 183 'branch="%(branch)s", revision="%(revision)s", ' |
183 'path="%(path)s"}' % self.__dict__) | 184 'path="%(path)s"}' % self.__dict__) |
184 | 185 |
185 def run_git(self, context, *args): | 186 def run_git(self, context, *args): |
186 cmd = [self._git] | 187 cmd = [self._git] |
187 if context is not None: | 188 if context is not None: |
188 cmd += ['-C', self._dep_dir(context)] | 189 cmd += ['-C', self._dep_dir(context)] |
189 cmd += list(args) | 190 cmd += list(args) |
190 | 191 |
191 logging.info('Running: %s', cmd) | 192 logging.info('Running: %s', cmd) |
192 return subprocess.check_output(cmd) | 193 return subprocess.check_output(cmd) |
193 | 194 |
194 def checkout(self, context): | 195 def checkout(self, context): |
195 checkout_dir = self._dep_dir(context) | 196 checkout_dir = self._dep_dir(context) |
196 fetch.ensure_git_checkout( | 197 self.backend.checkout( |
197 self.repo, self.revision, checkout_dir, context.allow_fetch) | 198 self.repo, self.revision, checkout_dir, context.allow_fetch) |
198 cleanup_pyc(checkout_dir) | 199 cleanup_pyc(checkout_dir) |
199 | 200 |
200 def repo_root(self, context): | 201 def repo_root(self, context): |
201 return os.path.join(self._dep_dir(context), self.path) | 202 return os.path.join(self._dep_dir(context), self.path) |
202 | 203 |
203 def dump(self): | 204 def dump(self): |
204 buf = package_pb2.DepSpec( | 205 buf = package_pb2.DepSpec( |
205 project_id=self.project_id, | 206 project_id=self.project_id, |
206 url=self.repo, | 207 url=self.repo, |
207 branch=self.branch, | 208 branch=self.branch, |
208 revision=self.revision) | 209 revision=self.revision) |
209 if self.path: | 210 if self.path: |
210 buf.path_override = self.path | 211 buf.path_override = self.path |
211 return buf | 212 return buf |
212 | 213 |
213 def updates(self, context, other_revision=None): | 214 def updates(self, context, other_revision=None): |
214 """Returns a list of all updates to the branch since the revision this | 215 """Returns a list of all updates to the branch since the revision this |
215 repo spec refers to. | 216 repo spec refers to. |
216 """ | 217 """ |
217 raw_updates = self.raw_updates( | 218 raw_updates = self.raw_updates( |
218 context, (other_revision or 'origin/%s' % self.branch)) | 219 context, (other_revision or 'origin/%s' % self.branch)) |
219 updates = [] | 220 updates = [] |
220 for rev in raw_updates: | 221 for rev in raw_updates: |
221 info = self._get_commit_info(rev, context) | 222 info = self._get_commit_info(rev, context) |
222 updates.append(GitRepoSpec( | 223 updates.append(GitRepoSpec( |
223 self.project_id, self.repo, self.branch, rev, self.path)) | 224 self.project_id, |
| 225 self.repo, |
| 226 self.branch, |
| 227 rev, |
| 228 self.path, |
| 229 self.backend)) |
224 return updates | 230 return updates |
225 | 231 |
226 def commit_infos(self, context, other_revision): | 232 def commit_infos(self, context, other_revision): |
227 """Returns a list of commit infos on the branch between the pinned revision | 233 """Returns a list of commit infos on the branch between the pinned revision |
228 and |other_revision|. | 234 and |other_revision|. |
229 """ | 235 """ |
230 raw_updates = self.raw_updates(context, other_revision) | 236 raw_updates = self.raw_updates(context, other_revision) |
231 return [self._get_commit_info(rev, context) for rev in raw_updates] | 237 return [self._get_commit_info(rev, context) for rev in raw_updates] |
232 | 238 |
233 def raw_updates(self, context, other_revision): | 239 def raw_updates(self, context, other_revision): |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 def load_proto(cls, proto_file): | 486 def load_proto(cls, proto_file): |
481 buf = proto_file.read() | 487 buf = proto_file.read() |
482 assert buf.api_version == cls.API_VERSION | 488 assert buf.api_version == cls.API_VERSION |
483 | 489 |
484 deps = { str(dep.project_id): cls.spec_for_dep(dep) | 490 deps = { str(dep.project_id): cls.spec_for_dep(dep) |
485 for dep in buf.deps } | 491 for dep in buf.deps } |
486 return cls(str(buf.project_id), str(buf.recipes_path), deps) | 492 return cls(str(buf.project_id), str(buf.recipes_path), deps) |
487 | 493 |
488 @classmethod | 494 @classmethod |
489 def spec_for_dep(cls, dep): | 495 def spec_for_dep(cls, dep): |
490 """Returns a RepoSpec for the given dependency protobuf. | 496 """Returns a RepoSpec for the given dependency protobuf.""" |
491 | 497 |
492 This assumes all dependencies are Git dependencies. | 498 if dep.repo_type in (package_pb2.DepSpec.GIT, package_pb2.DepSpec.GITILES): |
493 """ | 499 if dep.repo_type == package_pb2.DepSpec.GIT: |
494 return GitRepoSpec(str(dep.project_id), | 500 backend = fetch.LocalGitBackend() |
495 str(dep.url), | 501 elif dep.repo_type == package_pb2.DepSpec.GITILES: |
496 str(dep.branch), | 502 backend = fetch.GitilesGitBackend() |
497 str(dep.revision), | 503 return GitRepoSpec(str(dep.project_id), |
498 str(dep.path_override)) | 504 str(dep.url), |
| 505 str(dep.branch), |
| 506 str(dep.revision), |
| 507 str(dep.path_override), |
| 508 backend) |
| 509 |
| 510 assert False, 'Unexpected repo type: %s' % dep |
499 | 511 |
500 @property | 512 @property |
501 def project_id(self): | 513 def project_id(self): |
502 return self._project_id | 514 return self._project_id |
503 | 515 |
504 @property | 516 @property |
505 def recipes_path(self): | 517 def recipes_path(self): |
506 return self._recipes_path | 518 return self._recipes_path |
507 | 519 |
508 @property | 520 @property |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 >>> d = { 'x': 1, 'y': 2 } | 661 >>> d = { 'x': 1, 'y': 2 } |
650 >>> sorted(_updated(d, { 'y': 3, 'z': 4 }).items()) | 662 >>> sorted(_updated(d, { 'y': 3, 'z': 4 }).items()) |
651 [('x', 1), ('y', 3), ('z', 4)] | 663 [('x', 1), ('y', 3), ('z', 4)] |
652 >>> sorted(d.items()) | 664 >>> sorted(d.items()) |
653 [('x', 1), ('y', 2)] | 665 [('x', 1), ('y', 2)] |
654 """ | 666 """ |
655 | 667 |
656 d = copy.copy(d) | 668 d = copy.copy(d) |
657 d.update(updates) | 669 d.update(updates) |
658 return d | 670 return d |
OLD | NEW |