| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # 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 functools | 9 import functools |
| 10 import itertools | 10 import itertools |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 self.repo = repo | 189 self.repo = repo |
| 190 self.branch = branch | 190 self.branch = branch |
| 191 self.revision = revision | 191 self.revision = revision |
| 192 self.path = path | 192 self.path = path |
| 193 | 193 |
| 194 def __str__(self): | 194 def __str__(self): |
| 195 return ('GitRepoSpec{project_id="%(project_id)s", repo="%(repo)s", ' | 195 return ('GitRepoSpec{project_id="%(project_id)s", repo="%(repo)s", ' |
| 196 'branch="%(branch)s", revision="%(revision)s", ' | 196 'branch="%(branch)s", revision="%(revision)s", ' |
| 197 'path="%(path)s"}' % self.__dict__) | 197 'path="%(path)s"}' % self.__dict__) |
| 198 | 198 |
| 199 def run_git(self, context, *args): |
| 200 cmd = [self._git] |
| 201 if context is not None: |
| 202 cmd += ['--git-dir', os.path.join(self._dep_dir(context), '.git')] |
| 203 cmd += list(args) |
| 204 |
| 205 logging.info('Running: %s', cmd) |
| 206 return subprocess.check_output(cmd) |
| 207 |
| 199 def checkout(self, context): | 208 def checkout(self, context): |
| 200 dep_dir = self._dep_dir(context) | 209 dep_dir = self._dep_dir(context) |
| 201 logging.info('Freshening repository %s' % dep_dir) | 210 logging.info('Freshening repository %s', dep_dir) |
| 202 | 211 |
| 203 if not os.path.isdir(dep_dir): | 212 if not os.path.isdir(dep_dir): |
| 204 _run_cmd([self._git, 'clone', self.repo, dep_dir]) | 213 self.run_git(None, 'clone', self.repo, dep_dir) |
| 205 elif not os.path.isdir(os.path.join(dep_dir, '.git')): | 214 elif not os.path.isdir(os.path.join(dep_dir, '.git')): |
| 206 raise UncleanFilesystemError('%s exists but is not a git repo' % dep_dir) | 215 raise UncleanFilesystemError('%s exists but is not a git repo' % dep_dir) |
| 207 | 216 |
| 208 try: | 217 try: |
| 209 subprocess.check_output([self._git, 'rev-parse', '-q', '--verify', | 218 self.run_git(context, 'rev-parse', '-q', '--verify', |
| 210 '%s^{commit}' % self.revision], cwd=dep_dir) | 219 '%s^{commit}' % self.revision) |
| 211 except subprocess.CalledProcessError: | 220 except subprocess.CalledProcessError: |
| 212 _run_cmd([self._git, 'fetch'], cwd=dep_dir) | 221 self.run_git(context, 'fetch') |
| 213 _run_cmd([self._git, 'reset', '-q', '--hard', self.revision], cwd=dep_dir) | 222 self.run_git(context, 'reset', '-q', '--hard', self.revision) |
| 214 | 223 |
| 215 def check_checkout(self, context): | 224 def check_checkout(self, context): |
| 216 dep_dir = self._dep_dir(context) | 225 dep_dir = self._dep_dir(context) |
| 217 if not os.path.isdir(dep_dir): | 226 if not os.path.isdir(dep_dir): |
| 218 raise UncleanFilesystemError('Dependency %s does not exist' % | 227 raise UncleanFilesystemError('Dependency %s does not exist' % |
| 219 dep_dir) | 228 dep_dir) |
| 220 elif not os.path.isdir(os.path.join(dep_dir, '.git')): | 229 elif not os.path.isdir(os.path.join(dep_dir, '.git')): |
| 221 raise UncleanFilesystemError('Dependency %s is not a git repo' % | 230 raise UncleanFilesystemError('Dependency %s is not a git repo' % |
| 222 dep_dir) | 231 dep_dir) |
| 223 | 232 |
| 224 git_status_command = [self._git, 'status', '--porcelain'] | 233 output = self.run_git(context, 'status', '--porcelain') |
| 225 logging.info('%s', git_status_command) | |
| 226 output = subprocess.check_output(git_status_command, cwd=dep_dir) | |
| 227 if output: | 234 if output: |
| 228 raise UncleanFilesystemError('Dependency %s is unclean:\n%s' % | 235 raise UncleanFilesystemError('Dependency %s is unclean:\n%s' % |
| 229 (dep_dir, output)) | 236 (dep_dir, output)) |
| 230 | 237 |
| 231 def repo_root(self, context): | 238 def repo_root(self, context): |
| 232 return os.path.join(self._dep_dir(context), self.path) | 239 return os.path.join(self._dep_dir(context), self.path) |
| 233 | 240 |
| 234 def dump(self): | 241 def dump(self): |
| 235 buf = package_pb2.DepSpec( | 242 buf = package_pb2.DepSpec( |
| 236 project_id=self.project_id, | 243 project_id=self.project_id, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 252 for rev in lines: | 259 for rev in lines: |
| 253 info = self._get_commit_info(rev, context) | 260 info = self._get_commit_info(rev, context) |
| 254 updates.append(RepoUpdate( | 261 updates.append(RepoUpdate( |
| 255 GitRepoSpec(self.project_id, self.repo, self.branch, rev, | 262 GitRepoSpec(self.project_id, self.repo, self.branch, rev, |
| 256 self.path), | 263 self.path), |
| 257 commit_infos=(info,))) | 264 commit_infos=(info,))) |
| 258 return updates | 265 return updates |
| 259 | 266 |
| 260 def _raw_updates(self, context, subdir): | 267 def _raw_updates(self, context, subdir): |
| 261 self.checkout(context) | 268 self.checkout(context) |
| 262 _run_cmd([self._git, 'fetch'], cwd=self._dep_dir(context)) | 269 self.run_git(context, 'fetch') |
| 263 args = [self._git, 'rev-list', '--reverse', | 270 args = ['rev-list', '--reverse', |
| 264 '%s..origin/%s' % (self.revision, self.branch)] | 271 '%s..origin/%s' % (self.revision, self.branch)] |
| 265 if subdir: | 272 if subdir: |
| 266 # We add proto_file to the list of paths to check because it might contain | 273 # We add proto_file to the list of paths to check because it might contain |
| 267 # other upstream rolls, which we want. | 274 # other upstream rolls, which we want. |
| 268 args.extend(['--', subdir + os.path.sep, self.proto_file(context).path]) | 275 args.extend(['--', subdir + os.path.sep, self.proto_file(context).path]) |
| 269 git = subprocess.Popen( | 276 return self.run_git(context, *args) |
| 270 args, stdout=subprocess.PIPE, cwd=self._dep_dir(context)) | |
| 271 (stdout, _) = git.communicate() | |
| 272 return stdout | |
| 273 | 277 |
| 274 def _get_commit_info(self, rev, context): | 278 def _get_commit_info(self, rev, context): |
| 275 author = subprocess.check_output( | 279 author = self.run_git(context, 'show', '-s', '--pretty=%aE', rev).strip() |
| 276 [self._git, 'show', '-s', '--pretty=%aE', rev], | 280 message = self.run_git(context, 'show', '-s', '--pretty=%B', rev).strip() |
| 277 cwd=self._dep_dir(context)).strip() | |
| 278 message = subprocess.check_output( | |
| 279 [self._git, 'show', '-s', '--pretty=%B', rev], | |
| 280 cwd=self._dep_dir(context)).strip() | |
| 281 return CommitInfo(author, message, self.project_id, rev) | 281 return CommitInfo(author, message, self.project_id, rev) |
| 282 | 282 |
| 283 def _dep_dir(self, context): | 283 def _dep_dir(self, context): |
| 284 return os.path.join(context.package_dir, self.project_id) | 284 return os.path.join(context.package_dir, self.project_id) |
| 285 | 285 |
| 286 @property | 286 @property |
| 287 def _git(self): | 287 def _git(self): |
| 288 if sys.platform.startswith(('win', 'cygwin')): | 288 if sys.platform.startswith(('win', 'cygwin')): |
| 289 return 'git.bat' | 289 return 'git.bat' |
| 290 else: | 290 else: |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 @property | 650 @property |
| 651 def packages(self): | 651 def packages(self): |
| 652 for p in self._packages.values(): | 652 for p in self._packages.values(): |
| 653 yield p | 653 yield p |
| 654 | 654 |
| 655 @property | 655 @property |
| 656 def engine_recipes_py(self): | 656 def engine_recipes_py(self): |
| 657 return os.path.join(self._context.repo_root, 'recipes.py') | 657 return os.path.join(self._context.repo_root, 'recipes.py') |
| 658 | 658 |
| 659 | 659 |
| 660 def _run_cmd(cmd, cwd=None): | |
| 661 cwd_str = ' (in %s)' % cwd if cwd else '' | |
| 662 logging.info('%s%s', cmd, cwd_str) | |
| 663 subprocess.check_call(cmd, cwd=cwd) | |
| 664 | |
| 665 | |
| 666 def _merge2(xs, ys, compare=lambda x, y: x <= y): | 660 def _merge2(xs, ys, compare=lambda x, y: x <= y): |
| 667 """Merges two sorted iterables, preserving sort order. | 661 """Merges two sorted iterables, preserving sort order. |
| 668 | 662 |
| 669 >>> list(_merge2([1, 3, 6], [2, 4, 5])) | 663 >>> list(_merge2([1, 3, 6], [2, 4, 5])) |
| 670 [1, 2, 3, 4, 5, 6] | 664 [1, 2, 3, 4, 5, 6] |
| 671 >>> list(_merge2([1, 2, 3], [])) | 665 >>> list(_merge2([1, 2, 3], [])) |
| 672 [1, 2, 3] | 666 [1, 2, 3] |
| 673 >>> list(_merge2([], [4, 5, 6])) | 667 >>> list(_merge2([], [4, 5, 6])) |
| 674 [4, 5, 6] | 668 [4, 5, 6] |
| 675 >>> list(_merge2([], [])) | 669 >>> list(_merge2([], [])) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 >>> d = { 'x': 1, 'y': 2 } | 725 >>> d = { 'x': 1, 'y': 2 } |
| 732 >>> sorted(_updated(d, { 'y': 3, 'z': 4 }).items()) | 726 >>> sorted(_updated(d, { 'y': 3, 'z': 4 }).items()) |
| 733 [('x', 1), ('y', 3), ('z', 4)] | 727 [('x', 1), ('y', 3), ('z', 4)] |
| 734 >>> sorted(d.items()) | 728 >>> sorted(d.items()) |
| 735 [('x', 1), ('y', 2)] | 729 [('x', 1), ('y', 2)] |
| 736 """ | 730 """ |
| 737 | 731 |
| 738 d = copy.copy(d) | 732 d = copy.copy(d) |
| 739 d.update(updates) | 733 d.update(updates) |
| 740 return d | 734 return d |
| OLD | NEW |