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

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: Fix tests 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') | gclient_utils.py » ('J')
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() 1058 actual_url = scm.GetActualRemoteURL()
1055 if actual_url and not scm.DoesRemoteURLMatch(): 1059 if actual_url and not scm.DoesRemoteURLMatch():
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 Expected: %(expected_url)s (%(expected_scm)s) 1064 Expected: %(expected_url)s (%(expected_scm)s)
1061 Actual: %(actual_url)s (%(actual_scm)s) 1065 Actual: %(actual_url)s (%(actual_scm)s)
1062 1066
1063 You should ensure that the URL listed in .gclient is correct and either change 1067 You should ensure that the URL listed in .gclient is correct and either change
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 be invalid for the given |dep|.""" 1228 be invalid for the given |dep|."""
1225 assert len(dep.safesync_url) > 0 1229 assert len(dep.safesync_url) > 0
1226 handle = urllib.urlopen(dep.safesync_url) 1230 handle = urllib.urlopen(dep.safesync_url)
1227 rev = handle.read().strip() 1231 rev = handle.read().strip()
1228 handle.close() 1232 handle.close()
1229 if not rev: 1233 if not rev:
1230 raise gclient_utils.Error( 1234 raise gclient_utils.Error(
1231 'It appears your safesync_url (%s) is not working properly\n' 1235 'It appears your safesync_url (%s) is not working properly\n'
1232 '(as it returned an empty response). Check your config.' % 1236 '(as it returned an empty response). Check your config.' %
1233 dep.safesync_url) 1237 dep.safesync_url)
1234 scm = gclient_scm.CreateSCM(dep.url, dep.root.root_dir, dep.name) 1238 scm = gclient_scm.CreateSCM(
1239 dep.url, dep.root.root_dir, dep.name, self.outbuf)
1235 safe_rev = scm.GetUsableRev(rev, self._options) 1240 safe_rev = scm.GetUsableRev(rev, self._options)
1236 if self._options.verbose: 1241 if self._options.verbose:
1237 print('Using safesync_url revision: %s.\n' % safe_rev) 1242 print('Using safesync_url revision: %s.\n' % safe_rev)
1238 self._options.revisions.append('%s@%s' % (dep.name, safe_rev)) 1243 self._options.revisions.append('%s@%s' % (dep.name, safe_rev))
1239 1244
1240 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True): 1245 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True):
1241 """Runs a command on each dependency in a client and its dependencies. 1246 """Runs a command on each dependency in a client and its dependencies.
1242 1247
1243 Args: 1248 Args:
1244 command: The command to use (e.g., 'status' or 'diff') 1249 command: The command to use (e.g., 'status' or 'diff')
(...skipping 10 matching lines...) Expand all
1255 if command not in ('diff', 'recurse', 'runhooks', 'status'): 1260 if command not in ('diff', 'recurse', 'runhooks', 'status'):
1256 revision_overrides = self._EnforceRevisions() 1261 revision_overrides = self._EnforceRevisions()
1257 pm = None 1262 pm = None
1258 # Disable progress for non-tty stdout. 1263 # Disable progress for non-tty stdout.
1259 if (sys.stdout.isatty() and not self._options.verbose and progress): 1264 if (sys.stdout.isatty() and not self._options.verbose and progress):
1260 if command in ('update', 'revert'): 1265 if command in ('update', 'revert'):
1261 pm = Progress('Syncing projects', 1) 1266 pm = Progress('Syncing projects', 1)
1262 elif command == 'recurse': 1267 elif command == 'recurse':
1263 pm = Progress(' '.join(args), 1) 1268 pm = Progress(' '.join(args), 1)
1264 work_queue = gclient_utils.ExecutionQueue( 1269 work_queue = gclient_utils.ExecutionQueue(
1265 self._options.jobs, pm, ignore_requirements=ignore_requirements) 1270 self._options.jobs, pm, ignore_requirements=ignore_requirements,
1271 verbose=self._options.verbose)
1266 for s in self.dependencies: 1272 for s in self.dependencies:
1267 work_queue.enqueue(s) 1273 work_queue.enqueue(s)
1268 work_queue.flush(revision_overrides, command, args, options=self._options) 1274 work_queue.flush(revision_overrides, command, args, options=self._options)
1269 1275
1270 # Once all the dependencies have been processed, it's now safe to run the 1276 # Once all the dependencies have been processed, it's now safe to run the
1271 # hooks. 1277 # hooks.
1272 if not self._options.nohooks: 1278 if not self._options.nohooks:
1273 self.RunHooksRecursively(self._options) 1279 self.RunHooksRecursively(self._options)
1274 1280
1275 if command == 'update': 1281 if command == 'update':
(...skipping 15 matching lines...) Expand all
1291 def _IsParentOfAny(parent, path_list): 1297 def _IsParentOfAny(parent, path_list):
1292 parent_plus_slash = parent + '/' 1298 parent_plus_slash = parent + '/'
1293 return any( 1299 return any(
1294 path[:len(parent_plus_slash)] == parent_plus_slash 1300 path[:len(parent_plus_slash)] == parent_plus_slash
1295 for path in path_list) 1301 for path in path_list)
1296 1302
1297 # Use entry and not entry_fixed there. 1303 # Use entry and not entry_fixed there.
1298 if (entry not in entries and 1304 if (entry not in entries and
1299 (not any(path.startswith(entry + '/') for path in entries)) and 1305 (not any(path.startswith(entry + '/') for path in entries)) and
1300 os.path.exists(e_dir)): 1306 os.path.exists(e_dir)):
1301 scm = gclient_scm.CreateSCM(prev_url, self.root_dir, entry_fixed) 1307 scm = gclient_scm.CreateSCM(
1308 prev_url, self.root_dir, entry_fixed, self.outbuf)
1302 1309
1303 # Check to see if this directory is now part of a higher-up checkout. 1310 # Check to see if this directory is now part of a higher-up checkout.
1304 if scm.GetCheckoutRoot() in full_entries: 1311 if scm.GetCheckoutRoot() in full_entries:
1305 logging.info('%s is part of a higher level checkout, not ' 1312 logging.info('%s is part of a higher level checkout, not '
1306 'removing.', scm.GetCheckoutRoot()) 1313 'removing.', scm.GetCheckoutRoot())
1307 continue 1314 continue
1308 1315
1309 file_list = [] 1316 file_list = []
1310 scm.status(self._options, [], file_list) 1317 scm.status(self._options, [], file_list)
1311 modified_files = file_list != [] 1318 modified_files = file_list != []
(...skipping 10 matching lines...) Expand all
1322 entry_fixed, self.root_dir)) 1329 entry_fixed, self.root_dir))
1323 gclient_utils.rmtree(e_dir) 1330 gclient_utils.rmtree(e_dir)
1324 # record the current list of entries for next time 1331 # record the current list of entries for next time
1325 self._SaveEntries() 1332 self._SaveEntries()
1326 return 0 1333 return 0
1327 1334
1328 def PrintRevInfo(self): 1335 def PrintRevInfo(self):
1329 if not self.dependencies: 1336 if not self.dependencies:
1330 raise gclient_utils.Error('No solution specified') 1337 raise gclient_utils.Error('No solution specified')
1331 # Load all the settings. 1338 # Load all the settings.
1332 work_queue = gclient_utils.ExecutionQueue(self._options.jobs, None, False) 1339 work_queue = gclient_utils.ExecutionQueue(
1340 self._options.jobs, None, False, verbose=self._options.verbose)
1333 for s in self.dependencies: 1341 for s in self.dependencies:
1334 work_queue.enqueue(s) 1342 work_queue.enqueue(s)
1335 work_queue.flush({}, None, [], options=self._options) 1343 work_queue.flush({}, None, [], options=self._options)
1336 1344
1337 def GetURLAndRev(dep): 1345 def GetURLAndRev(dep):
1338 """Returns the revision-qualified SCM url for a Dependency.""" 1346 """Returns the revision-qualified SCM url for a Dependency."""
1339 if dep.parsed_url is None: 1347 if dep.parsed_url is None:
1340 return None 1348 return None
1341 if isinstance(dep.parsed_url, self.FileImpl): 1349 if isinstance(dep.parsed_url, self.FileImpl):
1342 original_url = dep.parsed_url.file_location 1350 original_url = dep.parsed_url.file_location
1343 else: 1351 else:
1344 original_url = dep.parsed_url 1352 original_url = dep.parsed_url
1345 url, _ = gclient_utils.SplitUrlRevision(original_url) 1353 url, _ = gclient_utils.SplitUrlRevision(original_url)
1346 scm = gclient_scm.CreateSCM(original_url, self.root_dir, dep.name) 1354 scm = gclient_scm.CreateSCM(
1355 original_url, self.root_dir, dep.name, self.outbuf)
1347 if not os.path.isdir(scm.checkout_path): 1356 if not os.path.isdir(scm.checkout_path):
1348 return None 1357 return None
1349 return '%s@%s' % (url, scm.revinfo(self._options, [], None)) 1358 return '%s@%s' % (url, scm.revinfo(self._options, [], None))
1350 1359
1351 if self._options.snapshot: 1360 if self._options.snapshot:
1352 new_gclient = '' 1361 new_gclient = ''
1353 # First level at .gclient 1362 # First level at .gclient
1354 for d in self.dependencies: 1363 for d in self.dependencies:
1355 entries = {} 1364 entries = {}
1356 def GrabDeps(dep): 1365 def GrabDeps(dep):
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 print >> sys.stderr, 'Error: %s' % str(e) 1961 print >> sys.stderr, 'Error: %s' % str(e)
1953 return 1 1962 return 1
1954 finally: 1963 finally:
1955 gclient_utils.PrintWarnings() 1964 gclient_utils.PrintWarnings()
1956 1965
1957 1966
1958 if '__main__' == __name__: 1967 if '__main__' == __name__:
1959 sys.exit(Main(sys.argv[1:])) 1968 sys.exit(Main(sys.argv[1:]))
1960 1969
1961 # vim: ts=2:sw=2:tw=80:et: 1970 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | gclient_scm.py » ('j') | gclient_utils.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698