Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1045)

Side by Side Diff: recipe_engine/package.py

Issue 2669033007: [recipe_engine] Fix a couple path-related bugs. (Closed)
Patch Set: Fix remainder of presubmit tests Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 12 matching lines...) Expand all
23 from . import fetch 23 from . import fetch
24 24
25 25
26 class InconsistentDependencyGraphError(Exception): 26 class InconsistentDependencyGraphError(Exception):
27 def __init__(self, project_id, specs): 27 def __init__(self, project_id, specs):
28 self.project_id = project_id 28 self.project_id = project_id
29 self.specs = specs 29 self.specs = specs
30 30
31 def __str__(self): 31 def __str__(self):
32 return 'Package specs for %s do not match: %s vs %s' % ( 32 return 'Package specs for %s do not match: %s vs %s' % (
33 project_id, self.specs[0], self.specs[1]) 33 self.project_id, self.specs[0], self.specs[1])
34 34
35 35
36 class CyclicDependencyError(Exception): 36 class CyclicDependencyError(Exception):
37 pass 37 pass
38 38
39 39
40 def cleanup_pyc(path): 40 def cleanup_pyc(path):
41 """Removes any .pyc files from |path|'s directory tree. 41 """Removes any .pyc files from |path|'s directory tree.
42 42
43 This ensures we always use the fresh code. 43 This ensures we always use the fresh code.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 """Returns the root of this repository.""" 159 """Returns the root of this repository."""
160 raise NotImplementedError() 160 raise NotImplementedError()
161 161
162 def __eq__(self, other): 162 def __eq__(self, other):
163 raise NotImplementedError() 163 raise NotImplementedError()
164 164
165 def __ne__(self, other): 165 def __ne__(self, other):
166 return not (self == other) 166 return not (self == other)
167 167
168 def proto_file(self, context): 168 def proto_file(self, context):
169 """Returns the ProtoFile of the recipes config file in this repository. 169 """Returns the ProtoFile of the recipes config file in this repository.
170 Requires a good checkout.""" 170 Requires a good checkout."""
171 return ProtoFile(InfraRepoConfig().to_recipes_cfg(self.repo_root(context))) 171 return ProtoFile(InfraRepoConfig().to_recipes_cfg(self.repo_root(context)))
172 172
173 173
174 class GitRepoSpec(RepoSpec): 174 class GitRepoSpec(RepoSpec):
175 def __init__(self, project_id, repo, branch, revision, path, backend): 175 def __init__(self, project_id, repo, branch, revision, path, backend):
176 self.project_id = project_id 176 self.project_id = project_id
177 self.repo = repo 177 self.repo = repo
178 self.branch = branch 178 self.branch = branch
179 self.revision = revision 179 self.revision = revision
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 296
297 def __eq__(self, other): 297 def __eq__(self, other):
298 if not isinstance(other, type(self)): 298 if not isinstance(other, type(self)):
299 return False 299 return False
300 return self._components() == other._components() 300 return self._components() == other._components()
301 301
302 302
303 class PathRepoSpec(RepoSpec): 303 class PathRepoSpec(RepoSpec):
304 """A RepoSpec implementation that uses a local filesystem path.""" 304 """A RepoSpec implementation that uses a local filesystem path."""
305 305
306 def __init__(self, path): 306 def __init__(self, project_id, path):
307 self.project_id = project_id
307 self.path = path 308 self.path = path
308 309
309 def __str__(self): 310 def __str__(self):
310 return 'PathRepoSpec{path="%(path)s"}' % self.__dict__ 311 return (
312 'PathRepoSpec{project_id="%(project_id)s", path="%(path)s"}'
313 % self.__dict__
314 )
311 315
312 def checkout(self, context): 316 def checkout(self, context):
313 pass 317 pass
314 318
315 def repo_root(self, _context): 319 def repo_root(self, _context):
316 return self.path 320 return self.path
317 321
318 def proto_file(self, context): 322 def proto_file(self, context):
319 """Returns the ProtoFile of the recipes config file in this repository. 323 """Returns the ProtoFile of the recipes config file in this repository.
320 Requires a good checkout.""" 324 Requires a good checkout."""
321 return ProtoFile(InfraRepoConfig().to_recipes_cfg(self.path)) 325 return ProtoFile(InfraRepoConfig().to_recipes_cfg(self.path))
322 326
327 def updates(self, _context, _other_revision=None):
328 """Returns (empty) list of potential updates for this spec."""
329 return []
330
331 def dump(self):
332 """Returns the package.proto DepSpec form of this RepoSpec."""
333 return package_pb2.DepSpec(
334 project_id=self.project_id,
335 url="file://"+self.path)
iannucci 2017/02/03 00:00:05 These are used by the autoroller tests.
336
323 def __eq__(self, other): 337 def __eq__(self, other):
324 if not isinstance(other, type(self)): 338 if not isinstance(other, type(self)):
325 return False 339 return False
326 return self.path == other.path 340 return self.path == other.path
327 341
328 342
329 class RootRepoSpec(RepoSpec): 343 class RootRepoSpec(RepoSpec):
330 def __init__(self, proto_file): 344 def __init__(self, proto_file):
331 self._proto_file = proto_file 345 self._proto_file = proto_file
332 346
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 buf = proto_file.read() 516 buf = proto_file.read()
503 assert buf.api_version == cls.API_VERSION 517 assert buf.api_version == cls.API_VERSION
504 518
505 deps = { str(dep.project_id): cls.spec_for_dep(dep) 519 deps = { str(dep.project_id): cls.spec_for_dep(dep)
506 for dep in buf.deps } 520 for dep in buf.deps }
507 return cls(str(buf.project_id), str(buf.recipes_path), deps) 521 return cls(str(buf.project_id), str(buf.recipes_path), deps)
508 522
509 @classmethod 523 @classmethod
510 def spec_for_dep(cls, dep): 524 def spec_for_dep(cls, dep):
511 """Returns a RepoSpec for the given dependency protobuf.""" 525 """Returns a RepoSpec for the given dependency protobuf."""
526 url = str(dep.url)
527 if url.startswith("file://"):
528 return PathRepoSpec(str(dep.project_id), url[len("file://"):])
512 529
513 if dep.repo_type in (package_pb2.DepSpec.GIT, package_pb2.DepSpec.GITILES): 530 if dep.repo_type in (package_pb2.DepSpec.GIT, package_pb2.DepSpec.GITILES):
514 if dep.repo_type == package_pb2.DepSpec.GIT: 531 if dep.repo_type == package_pb2.DepSpec.GIT:
515 backend = fetch.GitBackend() 532 backend = fetch.GitBackend()
516 elif dep.repo_type == package_pb2.DepSpec.GITILES: 533 elif dep.repo_type == package_pb2.DepSpec.GITILES:
517 backend = fetch.GitilesBackend() 534 backend = fetch.GitilesBackend()
518 return GitRepoSpec(str(dep.project_id), 535 return GitRepoSpec(str(dep.project_id),
519 str(dep.url), 536 url,
520 str(dep.branch), 537 str(dep.branch),
521 str(dep.revision), 538 str(dep.revision),
522 str(dep.path_override), 539 str(dep.path_override),
523 backend) 540 backend)
524 541
525 assert False, 'Unexpected repo type: %s' % dep 542 assert False, 'Unexpected repo type: %s' % dep
526 543
527 @property 544 @property
528 def project_id(self): 545 def project_id(self):
529 return self._project_id 546 return self._project_id
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 allow_fetch: whether to fetch dependencies rather than just checking for 622 allow_fetch: whether to fetch dependencies rather than just checking for
606 them. 623 them.
607 overrides: if not None, a dictionary of project overrides. Dictionary keys 624 overrides: if not None, a dictionary of project overrides. Dictionary keys
608 are the `project_id` field to override, and dictionary values 625 are the `project_id` field to override, and dictionary values
609 are the override path. 626 are the override path.
610 """ 627 """
611 context = PackageContext.from_proto_file(repo_root, proto_file, allow_fetch, 628 context = PackageContext.from_proto_file(repo_root, proto_file, allow_fetch,
612 deps_path=deps_path) 629 deps_path=deps_path)
613 630
614 if overrides: 631 if overrides:
615 overrides = {project_id: PathRepoSpec(path) 632 overrides = {project_id: PathRepoSpec(project_id, path)
616 for project_id, path in overrides.iteritems()} 633 for project_id, path in overrides.iteritems()}
617 package_deps = cls(context, overrides=overrides) 634 package_deps = cls(context, overrides=overrides)
618 635
619 package_deps._root_package = package_deps._create_package(RootRepoSpec(proto _file)) 636 package_deps._root_package = package_deps._create_package(RootRepoSpec(proto _file))
620 637
621 return package_deps 638 return package_deps
622 639
623 def _create_package(self, repo_spec): 640 def _create_package(self, repo_spec):
624 repo_spec.checkout(self._context) 641 repo_spec.checkout(self._context)
625 package_spec = PackageSpec.load_proto(repo_spec.proto_file(self._context)) 642 package_spec = PackageSpec.load_proto(repo_spec.proto_file(self._context))
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 >>> d = { 'x': 1, 'y': 2 } 692 >>> d = { 'x': 1, 'y': 2 }
676 >>> sorted(_updated(d, { 'y': 3, 'z': 4 }).items()) 693 >>> sorted(_updated(d, { 'y': 3, 'z': 4 }).items())
677 [('x', 1), ('y', 3), ('z', 4)] 694 [('x', 1), ('y', 3), ('z', 4)]
678 >>> sorted(d.items()) 695 >>> sorted(d.items())
679 [('x', 1), ('y', 2)] 696 [('x', 1), ('y', 2)]
680 """ 697 """
681 698
682 d = copy.copy(d) 699 d = copy.copy(d)
683 d.update(updates) 700 d.update(updates)
684 return d 701 return d
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698