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

Side by Side Diff: gclient.py

Issue 3135014: Add --jobs support to gclient. --jobs=1 is still the default for now. (Closed)
Patch Set: As long as timeout is specified, it doesn't need to be a low value Created 10 years, 4 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
« no previous file with comments | « no previous file | gclient_utils.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/python 1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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 7
8 Files 8 Files
9 .gclient : Current client configuration, written by 'config' command. 9 .gclient : Current client configuration, written by 'config' command.
10 Format is a Python script defining 'solutions', a list whose 10 Format is a Python script defining 'solutions', a list whose
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 it will be removed from the list and the list will be extended 42 it will be removed from the list and the list will be extended
43 by the list of matching files. 43 by the list of matching files.
44 44
45 Example: 45 Example:
46 hooks = [ 46 hooks = [
47 { "pattern": "\\.(gif|jpe?g|pr0n|png)$", 47 { "pattern": "\\.(gif|jpe?g|pr0n|png)$",
48 "action": ["python", "image_indexer.py", "--all"]}, 48 "action": ["python", "image_indexer.py", "--all"]},
49 ] 49 ]
50 """ 50 """
51 51
52 __version__ = "0.5.2" 52 __version__ = "0.6"
53 53
54 import copy
54 import logging 55 import logging
55 import optparse 56 import optparse
56 import os 57 import os
57 import posixpath 58 import posixpath
58 import pprint 59 import pprint
59 import re 60 import re
60 import subprocess 61 import subprocess
61 import sys 62 import sys
62 import urlparse 63 import urlparse
63 import urllib 64 import urllib
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 # Special support for single-file checkout. 349 # Special support for single-file checkout.
349 if not command in (None, 'cleanup', 'diff', 'pack', 'status'): 350 if not command in (None, 'cleanup', 'diff', 'pack', 'status'):
350 options.revision = self.parsed_url.GetRevision() 351 options.revision = self.parsed_url.GetRevision()
351 scm = gclient_scm.SVNWrapper(self.parsed_url.GetPath(), 352 scm = gclient_scm.SVNWrapper(self.parsed_url.GetPath(),
352 self.root_dir(), 353 self.root_dir(),
353 self.name) 354 self.name)
354 scm.RunCommand('updatesingle', options, 355 scm.RunCommand('updatesingle', options,
355 args + [self.parsed_url.GetFilename()], 356 args + [self.parsed_url.GetFilename()],
356 self._file_list) 357 self._file_list)
357 else: 358 else:
359 # Create a shallow copy to mutate revision.
360 options = copy.copy(options)
358 options.revision = revision_overrides.get(self.name) 361 options.revision = revision_overrides.get(self.name)
359 scm = gclient_scm.CreateSCM(self.parsed_url, self.root_dir(), self.name) 362 scm = gclient_scm.CreateSCM(self.parsed_url, self.root_dir(), self.name)
360 scm.RunCommand(command, options, args, self._file_list) 363 scm.RunCommand(command, options, args, self._file_list)
361 self._file_list = [os.path.join(self.name, f.strip()) 364 self._file_list = [os.path.join(self.name, f.strip())
362 for f in self._file_list] 365 for f in self._file_list]
363 options.revision = None
364 self.processed = True 366 self.processed = True
365 if self.recursion_limit() > 0: 367 if self.recursion_limit() > 0:
366 # Then we can parse the DEPS file. 368 # Then we can parse the DEPS file.
367 self.ParseDepsFile() 369 self.ParseDepsFile()
368 # Adjust the implicit dependency requirement; e.g. if a DEPS file contains 370 # Adjust the implicit dependency requirement; e.g. if a DEPS file contains
369 # both src/foo and src/foo/bar, src/foo/bar is implicitly dependent of 371 # both src/foo and src/foo/bar, src/foo/bar is implicitly dependent of
370 # src/foo. Yes, it's O(n^2)... It's important to do that before 372 # src/foo. Yes, it's O(n^2)... It's important to do that before
371 # enqueueing them. 373 # enqueueing them.
372 for s in self.dependencies: 374 for s in self.dependencies:
373 for s2 in self.dependencies: 375 for s2 in self.dependencies:
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 Args: 705 Args:
704 command: The command to use (e.g., 'status' or 'diff') 706 command: The command to use (e.g., 'status' or 'diff')
705 args: list of str - extra arguments to add to the command line. 707 args: list of str - extra arguments to add to the command line.
706 """ 708 """
707 if not self.dependencies: 709 if not self.dependencies:
708 raise gclient_utils.Error('No solution specified') 710 raise gclient_utils.Error('No solution specified')
709 revision_overrides = self._EnforceRevisions() 711 revision_overrides = self._EnforceRevisions()
710 pm = None 712 pm = None
711 if command == 'update' and not self._options.verbose: 713 if command == 'update' and not self._options.verbose:
712 pm = Progress('Syncing projects', 1) 714 pm = Progress('Syncing projects', 1)
713 work_queue = gclient_utils.ExecutionQueue(pm) 715 work_queue = gclient_utils.ExecutionQueue(self._options.jobs, pm)
714 for s in self.dependencies: 716 for s in self.dependencies:
715 work_queue.enqueue(s) 717 work_queue.enqueue(s)
716 work_queue.flush(self._options, revision_overrides, command, args, 718 work_queue.flush(self._options, revision_overrides, command, args,
717 work_queue) 719 work_queue)
718 720
719 # Once all the dependencies have been processed, it's now safe to run the 721 # Once all the dependencies have been processed, it's now safe to run the
720 # hooks. 722 # hooks.
721 if not self._options.nohooks: 723 if not self._options.nohooks:
722 self.RunHooksRecursively(self._options) 724 self.RunHooksRecursively(self._options)
723 725
(...skipping 24 matching lines...) Expand all
748 entry_fixed, self.root_dir())) 750 entry_fixed, self.root_dir()))
749 gclient_utils.RemoveDirectory(e_dir) 751 gclient_utils.RemoveDirectory(e_dir)
750 # record the current list of entries for next time 752 # record the current list of entries for next time
751 self._SaveEntries() 753 self._SaveEntries()
752 return 0 754 return 0
753 755
754 def PrintRevInfo(self): 756 def PrintRevInfo(self):
755 if not self.dependencies: 757 if not self.dependencies:
756 raise gclient_utils.Error('No solution specified') 758 raise gclient_utils.Error('No solution specified')
757 # Load all the settings. 759 # Load all the settings.
758 work_queue = gclient_utils.ExecutionQueue(None) 760 work_queue = gclient_utils.ExecutionQueue(self._options.jobs, None)
759 for s in self.dependencies: 761 for s in self.dependencies:
760 work_queue.enqueue(s) 762 work_queue.enqueue(s)
761 work_queue.flush(self._options, {}, None, [], work_queue) 763 work_queue.flush(self._options, {}, None, [], work_queue)
762 764
763 def GetURLAndRev(dep): 765 def GetURLAndRev(dep):
764 """Returns the revision-qualified SCM url for a Dependency.""" 766 """Returns the revision-qualified SCM url for a Dependency."""
765 if dep.parsed_url is None: 767 if dep.parsed_url is None:
766 return None 768 return None
767 if isinstance(dep.parsed_url, self.FileImpl): 769 if isinstance(dep.parsed_url, self.FileImpl):
768 original_url = dep.parsed_url.file_location 770 original_url = dep.parsed_url.file_location
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1163
1162 def Main(argv): 1164 def Main(argv):
1163 """Doesn't parse the arguments here, just find the right subcommand to 1165 """Doesn't parse the arguments here, just find the right subcommand to
1164 execute.""" 1166 execute."""
1165 try: 1167 try:
1166 # Do it late so all commands are listed. 1168 # Do it late so all commands are listed.
1167 CMDhelp.usage = ('\n\nCommands are:\n' + '\n'.join([ 1169 CMDhelp.usage = ('\n\nCommands are:\n' + '\n'.join([
1168 ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) 1170 ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip())
1169 for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) 1171 for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')]))
1170 parser = optparse.OptionParser(version='%prog ' + __version__) 1172 parser = optparse.OptionParser(version='%prog ' + __version__)
1173 parser.add_option('-j', '--jobs', default=1, type='int',
1174 help='Specify how many SCM commands can run in parallel')
1171 parser.add_option('-v', '--verbose', action='count', default=0, 1175 parser.add_option('-v', '--verbose', action='count', default=0,
1172 help='Produces additional output for diagnostics. Can be ' 1176 help='Produces additional output for diagnostics. Can be '
1173 'used up to three times for more logging info.') 1177 'used up to three times for more logging info.')
1174 parser.add_option('--gclientfile', dest='config_filename', 1178 parser.add_option('--gclientfile', dest='config_filename',
1175 default=os.environ.get('GCLIENT_FILE', '.gclient'), 1179 default=os.environ.get('GCLIENT_FILE', '.gclient'),
1176 help='Specify an alternate %default file') 1180 help='Specify an alternate %default file')
1177 # Integrate standard options processing. 1181 # Integrate standard options processing.
1178 old_parser = parser.parse_args 1182 old_parser = parser.parse_args
1179 def Parse(args): 1183 def Parse(args):
1180 (options, args) = old_parser(args) 1184 (options, args) = old_parser(args)
1181 level = None 1185 level = None
1182 if options.verbose == 2: 1186 if options.verbose == 2:
1183 level = logging.INFO 1187 level = logging.INFO
1184 elif options.verbose > 2: 1188 elif options.verbose > 2:
1185 level = logging.DEBUG 1189 level = logging.DEBUG
1186 logging.basicConfig(level=level, 1190 logging.basicConfig(level=level,
1187 format='%(module)s(%(lineno)d) %(funcName)s:%(message)s') 1191 format='%(module)s(%(lineno)d) %(funcName)s:%(message)s')
1188 options.entries_filename = options.config_filename + '_entries' 1192 options.entries_filename = options.config_filename + '_entries'
1193 if options.jobs < 1:
1194 parser.error('--jobs must be 1 or higher')
1189 1195
1190 # These hacks need to die. 1196 # These hacks need to die.
1191 if not hasattr(options, 'revisions'): 1197 if not hasattr(options, 'revisions'):
1192 # GClient.RunOnDeps expects it even if not applicable. 1198 # GClient.RunOnDeps expects it even if not applicable.
1193 options.revisions = [] 1199 options.revisions = []
1194 if not hasattr(options, 'head'): 1200 if not hasattr(options, 'head'):
1195 options.head = None 1201 options.head = None
1196 if not hasattr(options, 'nohooks'): 1202 if not hasattr(options, 'nohooks'):
1197 options.nohooks = True 1203 options.nohooks = True
1198 if not hasattr(options, 'deps_os'): 1204 if not hasattr(options, 'deps_os'):
(...skipping 17 matching lines...) Expand all
1216 return CMDhelp(parser, argv) 1222 return CMDhelp(parser, argv)
1217 except gclient_utils.Error, e: 1223 except gclient_utils.Error, e:
1218 print >> sys.stderr, 'Error: %s' % str(e) 1224 print >> sys.stderr, 'Error: %s' % str(e)
1219 return 1 1225 return 1
1220 1226
1221 1227
1222 if '__main__' == __name__: 1228 if '__main__' == __name__:
1223 sys.exit(Main(sys.argv[1:])) 1229 sys.exit(Main(sys.argv[1:]))
1224 1230
1225 # vim: ts=2:sw=2:tw=80:et: 1231 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | gclient_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698