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

Side by Side Diff: gclient.py

Issue 227163002: Revamped terminal output for update. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: rebase Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | gclient_scm.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Meta checkout manager supporting both Subversion and GIT.""" 6 """Meta checkout manager supporting both Subversion and GIT."""
7 # Files 7 # Files
8 # .gclient : Current client configuration, written by 'config' command. 8 # .gclient : Current client configuration, written by 'config' command.
9 # Format is a Python script defining 'solutions', a list whose 9 # Format is a Python script defining 'solutions', a list whose
10 # entries each are maps binding the strings "name" and "url" 10 # entries each are maps binding the strings "name" and "url"
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 if not parsed_url[0]: 437 if not parsed_url[0]:
438 # A relative url. Fetch the real base. 438 # A relative url. Fetch the real base.
439 path = parsed_url[2] 439 path = parsed_url[2]
440 if not path.startswith('/'): 440 if not path.startswith('/'):
441 raise gclient_utils.Error( 441 raise gclient_utils.Error(
442 'relative DEPS entry \'%s\' must begin with a slash' % url) 442 'relative DEPS entry \'%s\' must begin with a slash' % url)
443 # Create a scm just to query the full url. 443 # Create a scm just to query the full url.
444 parent_url = self.parent.parsed_url 444 parent_url = self.parent.parsed_url
445 if isinstance(parent_url, self.FileImpl): 445 if isinstance(parent_url, self.FileImpl):
446 parent_url = parent_url.file_location 446 parent_url = parent_url.file_location
447 scm = gclient_scm.CreateSCM(parent_url, self.root.root_dir, None) 447 scm = gclient_scm.CreateSCM(
448 parent_url, self.root.root_dir, None, self.outbuf)
448 parsed_url = scm.FullUrlForRelativeUrl(url) 449 parsed_url = scm.FullUrlForRelativeUrl(url)
449 else: 450 else:
450 parsed_url = url 451 parsed_url = url
451 logging.info( 452 logging.info(
452 'Dependency(%s).LateOverride(%s) -> %s' % 453 'Dependency(%s).LateOverride(%s) -> %s' %
453 (self.name, url, parsed_url)) 454 (self.name, url, parsed_url))
454 return parsed_url 455 return parsed_url
455 456
456 if isinstance(url, self.FileImpl): 457 if isinstance(url, self.FileImpl):
457 logging.info( 458 logging.info(
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 parsed_url = self.LateOverride(self.url) 651 parsed_url = self.LateOverride(self.url)
651 file_list = [] if not options.nohooks else None 652 file_list = [] if not options.nohooks else None
652 if run_scm and parsed_url: 653 if run_scm and parsed_url:
653 if isinstance(parsed_url, self.FileImpl): 654 if isinstance(parsed_url, self.FileImpl):
654 # Special support for single-file checkout. 655 # Special support for single-file checkout.
655 if not command in (None, 'cleanup', 'diff', 'pack', 'status'): 656 if not command in (None, 'cleanup', 'diff', 'pack', 'status'):
656 # Sadly, pylint doesn't realize that parsed_url is of FileImpl. 657 # Sadly, pylint doesn't realize that parsed_url is of FileImpl.
657 # pylint: disable=E1103 658 # pylint: disable=E1103
658 options.revision = parsed_url.GetRevision() 659 options.revision = parsed_url.GetRevision()
659 self._used_scm = gclient_scm.SVNWrapper( 660 self._used_scm = gclient_scm.SVNWrapper(
660 parsed_url.GetPath(), self.root.root_dir, self.name) 661 parsed_url.GetPath(), self.root.root_dir, self.name,
662 out_cb=work_queue.out_cb)
661 self._used_scm.RunCommand('updatesingle', 663 self._used_scm.RunCommand('updatesingle',
662 options, args + [parsed_url.GetFilename()], file_list) 664 options, args + [parsed_url.GetFilename()], file_list)
663 else: 665 else:
664 # Create a shallow copy to mutate revision. 666 # Create a shallow copy to mutate revision.
665 options = copy.copy(options) 667 options = copy.copy(options)
666 options.revision = revision_overrides.get(self.name) 668 options.revision = revision_overrides.get(self.name)
667 self.maybeGetParentRevision( 669 self.maybeGetParentRevision(
668 command, options, parsed_url, self.parent.name, revision_overrides) 670 command, options, parsed_url, self.parent.name, revision_overrides)
669 self._used_scm = gclient_scm.CreateSCM( 671 self._used_scm = gclient_scm.CreateSCM(
670 parsed_url, self.root.root_dir, self.name) 672 parsed_url, self.root.root_dir, self.name, self.outbuf,
673 out_cb=work_queue.out_cb)
671 self._got_revision = self._used_scm.RunCommand(command, options, args, 674 self._got_revision = self._used_scm.RunCommand(command, options, args,
672 file_list) 675 file_list)
673 if file_list: 676 if file_list:
674 file_list = [os.path.join(self.name, f.strip()) for f in file_list] 677 file_list = [os.path.join(self.name, f.strip()) for f in file_list]
675 678
676 # TODO(phajdan.jr): We should know exactly when the paths are absolute. 679 # TODO(phajdan.jr): We should know exactly when the paths are absolute.
677 # Convert all absolute paths to relative. 680 # Convert all absolute paths to relative.
678 for i in range(len(file_list or [])): 681 for i in range(len(file_list or [])):
679 # It depends on the command being executed (like runhooks vs sync). 682 # It depends on the command being executed (like runhooks vs sync).
680 if not os.path.isabs(file_list[i]): 683 if not os.path.isabs(file_list[i]):
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 """Git-specific path marshaling. It is optimized for git-grep.""" 720 """Git-specific path marshaling. It is optimized for git-grep."""
718 721
719 def mod_path(git_pathspec): 722 def mod_path(git_pathspec):
720 match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec) 723 match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec)
721 modified_path = os.path.join(self.name, match.group(2)) 724 modified_path = os.path.join(self.name, match.group(2))
722 branch = match.group(1) or '' 725 branch = match.group(1) or ''
723 return '%s%s' % (branch, modified_path) 726 return '%s%s' % (branch, modified_path)
724 727
725 match = re.match('^Binary file ([^\0]+) matches$', line) 728 match = re.match('^Binary file ([^\0]+) matches$', line)
726 if match: 729 if match:
727 print 'Binary file %s matches' % mod_path(match.group(1)) 730 print 'Binary file %s matches\n' % mod_path(match.group(1))
728 return 731 return
729 732
730 items = line.split('\0') 733 items = line.split('\0')
731 if len(items) == 2 and items[1]: 734 if len(items) == 2 and items[1]:
732 print '%s : %s' % (mod_path(items[0]), items[1]) 735 print '%s : %s' % (mod_path(items[0]), items[1])
733 elif len(items) >= 2: 736 elif len(items) >= 2:
734 # Multiple null bytes or a single trailing null byte indicate 737 # Multiple null bytes or a single trailing null byte indicate
735 # git is likely displaying filenames only (such as with -l) 738 # git is likely displaying filenames only (such as with -l)
736 print '\n'.join(mod_path(path) for path in items if path) 739 print '\n'.join(mod_path(path) for path in items if path)
737 else: 740 else:
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 enforced_os = self.DEPS_OS_CHOICES.itervalues() 1046 enforced_os = self.DEPS_OS_CHOICES.itervalues()
1044 self._enforced_os = tuple(set(enforced_os)) 1047 self._enforced_os = tuple(set(enforced_os))
1045 self._root_dir = root_dir 1048 self._root_dir = root_dir
1046 self.config_content = None 1049 self.config_content = None
1047 1050
1048 def _CheckConfig(self): 1051 def _CheckConfig(self):
1049 """Verify that the config matches the state of the existing checked-out 1052 """Verify that the config matches the state of the existing checked-out
1050 solutions.""" 1053 solutions."""
1051 for dep in self.dependencies: 1054 for dep in self.dependencies:
1052 if dep.managed and dep.url: 1055 if dep.managed and dep.url:
1053 scm = gclient_scm.CreateSCM(dep.url, self.root_dir, dep.name) 1056 scm = gclient_scm.CreateSCM(
1057 dep.url, self.root_dir, dep.name, self.outbuf)
1054 actual_url = scm.GetActualRemoteURL(self._options) 1058 actual_url = scm.GetActualRemoteURL(self._options)
1055 if actual_url and not scm.DoesRemoteURLMatch(self._options): 1059 if actual_url and not scm.DoesRemoteURLMatch(self._options):
1056 raise gclient_utils.Error(''' 1060 raise gclient_utils.Error('''
1057 Your .gclient file seems to be broken. The requested URL is different from what 1061 Your .gclient file seems to be broken. The requested URL is different from what
1058 is actually checked out in %(checkout_path)s. 1062 is actually checked out in %(checkout_path)s.
1059 1063
1060 The .gclient file contains: 1064 The .gclient file contains:
1061 %(expected_url)s (%(expected_scm)s) 1065 %(expected_url)s (%(expected_scm)s)
1062 1066
1063 The local checkout in %(checkout_path)s reports: 1067 The local checkout in %(checkout_path)s reports:
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 be invalid for the given |dep|.""" 1231 be invalid for the given |dep|."""
1228 assert len(dep.safesync_url) > 0 1232 assert len(dep.safesync_url) > 0
1229 handle = urllib.urlopen(dep.safesync_url) 1233 handle = urllib.urlopen(dep.safesync_url)
1230 rev = handle.read().strip() 1234 rev = handle.read().strip()
1231 handle.close() 1235 handle.close()
1232 if not rev: 1236 if not rev:
1233 raise gclient_utils.Error( 1237 raise gclient_utils.Error(
1234 'It appears your safesync_url (%s) is not working properly\n' 1238 'It appears your safesync_url (%s) is not working properly\n'
1235 '(as it returned an empty response). Check your config.' % 1239 '(as it returned an empty response). Check your config.' %
1236 dep.safesync_url) 1240 dep.safesync_url)
1237 scm = gclient_scm.CreateSCM(dep.url, dep.root.root_dir, dep.name) 1241 scm = gclient_scm.CreateSCM(
1242 dep.url, dep.root.root_dir, dep.name, self.outbuf)
1238 safe_rev = scm.GetUsableRev(rev, self._options) 1243 safe_rev = scm.GetUsableRev(rev, self._options)
1239 if self._options.verbose: 1244 if self._options.verbose:
1240 print('Using safesync_url revision: %s.\n' % safe_rev) 1245 print('Using safesync_url revision: %s.\n' % safe_rev)
1241 self._options.revisions.append('%s@%s' % (dep.name, safe_rev)) 1246 self._options.revisions.append('%s@%s' % (dep.name, safe_rev))
1242 1247
1243 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True): 1248 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True):
1244 """Runs a command on each dependency in a client and its dependencies. 1249 """Runs a command on each dependency in a client and its dependencies.
1245 1250
1246 Args: 1251 Args:
1247 command: The command to use (e.g., 'status' or 'diff') 1252 command: The command to use (e.g., 'status' or 'diff')
(...skipping 10 matching lines...) Expand all
1258 if command not in ('diff', 'recurse', 'runhooks', 'status'): 1263 if command not in ('diff', 'recurse', 'runhooks', 'status'):
1259 revision_overrides = self._EnforceRevisions() 1264 revision_overrides = self._EnforceRevisions()
1260 pm = None 1265 pm = None
1261 # Disable progress for non-tty stdout. 1266 # Disable progress for non-tty stdout.
1262 if (sys.stdout.isatty() and not self._options.verbose and progress): 1267 if (sys.stdout.isatty() and not self._options.verbose and progress):
1263 if command in ('update', 'revert'): 1268 if command in ('update', 'revert'):
1264 pm = Progress('Syncing projects', 1) 1269 pm = Progress('Syncing projects', 1)
1265 elif command == 'recurse': 1270 elif command == 'recurse':
1266 pm = Progress(' '.join(args), 1) 1271 pm = Progress(' '.join(args), 1)
1267 work_queue = gclient_utils.ExecutionQueue( 1272 work_queue = gclient_utils.ExecutionQueue(
1268 self._options.jobs, pm, ignore_requirements=ignore_requirements) 1273 self._options.jobs, pm, ignore_requirements=ignore_requirements,
1274 verbose=self._options.verbose)
1269 for s in self.dependencies: 1275 for s in self.dependencies:
1270 work_queue.enqueue(s) 1276 work_queue.enqueue(s)
1271 work_queue.flush(revision_overrides, command, args, options=self._options) 1277 work_queue.flush(revision_overrides, command, args, options=self._options)
1272 1278
1273 # Once all the dependencies have been processed, it's now safe to run the 1279 # Once all the dependencies have been processed, it's now safe to run the
1274 # hooks. 1280 # hooks.
1275 if not self._options.nohooks: 1281 if not self._options.nohooks:
1276 self.RunHooksRecursively(self._options) 1282 self.RunHooksRecursively(self._options)
1277 1283
1278 if command == 'update': 1284 if command == 'update':
(...skipping 15 matching lines...) Expand all
1294 def _IsParentOfAny(parent, path_list): 1300 def _IsParentOfAny(parent, path_list):
1295 parent_plus_slash = parent + '/' 1301 parent_plus_slash = parent + '/'
1296 return any( 1302 return any(
1297 path[:len(parent_plus_slash)] == parent_plus_slash 1303 path[:len(parent_plus_slash)] == parent_plus_slash
1298 for path in path_list) 1304 for path in path_list)
1299 1305
1300 # Use entry and not entry_fixed there. 1306 # Use entry and not entry_fixed there.
1301 if (entry not in entries and 1307 if (entry not in entries and
1302 (not any(path.startswith(entry + '/') for path in entries)) and 1308 (not any(path.startswith(entry + '/') for path in entries)) and
1303 os.path.exists(e_dir)): 1309 os.path.exists(e_dir)):
1304 scm = gclient_scm.CreateSCM(prev_url, self.root_dir, entry_fixed) 1310 scm = gclient_scm.CreateSCM(
1311 prev_url, self.root_dir, entry_fixed, self.outbuf)
1305 1312
1306 # Check to see if this directory is now part of a higher-up checkout. 1313 # Check to see if this directory is now part of a higher-up checkout.
1307 if scm.GetCheckoutRoot() in full_entries: 1314 if scm.GetCheckoutRoot() in full_entries:
1308 logging.info('%s is part of a higher level checkout, not ' 1315 logging.info('%s is part of a higher level checkout, not '
1309 'removing.', scm.GetCheckoutRoot()) 1316 'removing.', scm.GetCheckoutRoot())
1310 continue 1317 continue
1311 1318
1312 file_list = [] 1319 file_list = []
1313 scm.status(self._options, [], file_list) 1320 scm.status(self._options, [], file_list)
1314 modified_files = file_list != [] 1321 modified_files = file_list != []
(...skipping 10 matching lines...) Expand all
1325 entry_fixed, self.root_dir)) 1332 entry_fixed, self.root_dir))
1326 gclient_utils.rmtree(e_dir) 1333 gclient_utils.rmtree(e_dir)
1327 # record the current list of entries for next time 1334 # record the current list of entries for next time
1328 self._SaveEntries() 1335 self._SaveEntries()
1329 return 0 1336 return 0
1330 1337
1331 def PrintRevInfo(self): 1338 def PrintRevInfo(self):
1332 if not self.dependencies: 1339 if not self.dependencies:
1333 raise gclient_utils.Error('No solution specified') 1340 raise gclient_utils.Error('No solution specified')
1334 # Load all the settings. 1341 # Load all the settings.
1335 work_queue = gclient_utils.ExecutionQueue(self._options.jobs, None, False) 1342 work_queue = gclient_utils.ExecutionQueue(
1343 self._options.jobs, None, False, verbose=self._options.verbose)
1336 for s in self.dependencies: 1344 for s in self.dependencies:
1337 work_queue.enqueue(s) 1345 work_queue.enqueue(s)
1338 work_queue.flush({}, None, [], options=self._options) 1346 work_queue.flush({}, None, [], options=self._options)
1339 1347
1340 def GetURLAndRev(dep): 1348 def GetURLAndRev(dep):
1341 """Returns the revision-qualified SCM url for a Dependency.""" 1349 """Returns the revision-qualified SCM url for a Dependency."""
1342 if dep.parsed_url is None: 1350 if dep.parsed_url is None:
1343 return None 1351 return None
1344 if isinstance(dep.parsed_url, self.FileImpl): 1352 if isinstance(dep.parsed_url, self.FileImpl):
1345 original_url = dep.parsed_url.file_location 1353 original_url = dep.parsed_url.file_location
1346 else: 1354 else:
1347 original_url = dep.parsed_url 1355 original_url = dep.parsed_url
1348 url, _ = gclient_utils.SplitUrlRevision(original_url) 1356 url, _ = gclient_utils.SplitUrlRevision(original_url)
1349 scm = gclient_scm.CreateSCM(original_url, self.root_dir, dep.name) 1357 scm = gclient_scm.CreateSCM(
1358 original_url, self.root_dir, dep.name, self.outbuf)
1350 if not os.path.isdir(scm.checkout_path): 1359 if not os.path.isdir(scm.checkout_path):
1351 return None 1360 return None
1352 return '%s@%s' % (url, scm.revinfo(self._options, [], None)) 1361 return '%s@%s' % (url, scm.revinfo(self._options, [], None))
1353 1362
1354 if self._options.snapshot: 1363 if self._options.snapshot:
1355 new_gclient = '' 1364 new_gclient = ''
1356 # First level at .gclient 1365 # First level at .gclient
1357 for d in self.dependencies: 1366 for d in self.dependencies:
1358 entries = {} 1367 entries = {}
1359 def GrabDeps(dep): 1368 def GrabDeps(dep):
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 print >> sys.stderr, 'Error: %s' % str(e) 1964 print >> sys.stderr, 'Error: %s' % str(e)
1956 return 1 1965 return 1
1957 finally: 1966 finally:
1958 gclient_utils.PrintWarnings() 1967 gclient_utils.PrintWarnings()
1959 1968
1960 1969
1961 if '__main__' == __name__: 1970 if '__main__' == __name__:
1962 sys.exit(Main(sys.argv[1:])) 1971 sys.exit(Main(sys.argv[1:]))
1963 1972
1964 # vim: ts=2:sw=2:tw=80:et: 1973 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | gclient_scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698