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

Side by Side Diff: gclient.py

Issue 2857017: Add more glue code necessary for getting the DEPS dependencies as Dependency objects. (Closed)
Patch Set: . Created 10 years, 6 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 | no next file » | 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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 raise gclient_utils.Error( 304 raise gclient_utils.Error(
305 "Solutions have conflicting versions of dependency \"%s\"" % d) 305 "Solutions have conflicting versions of dependency \"%s\"" % d)
306 if d in solution_urls and solution_urls[d] != url: 306 if d in solution_urls and solution_urls[d] != url:
307 raise gclient_utils.Error( 307 raise gclient_utils.Error(
308 "Dependency \"%s\" conflicts with specified solution" % d) 308 "Dependency \"%s\" conflicts with specified solution" % d)
309 # Grab the dependency. 309 # Grab the dependency.
310 deps[d] = url 310 deps[d] = url
311 return deps 311 return deps
312 312
313 def _RunHookAction(self, hook_dict, matching_file_list): 313 def _RunHookAction(self, hook_dict, matching_file_list):
314 """Runs the action from a single hook. 314 """Runs the action from a single hook."""
315 """
316 logging.info(hook_dict) 315 logging.info(hook_dict)
317 logging.info(matching_file_list) 316 logging.info(matching_file_list)
318 command = hook_dict['action'][:] 317 command = hook_dict['action'][:]
319 if command[0] == 'python': 318 if command[0] == 'python':
320 # If the hook specified "python" as the first item, the action is a 319 # If the hook specified "python" as the first item, the action is a
321 # Python script. Run it by starting a new copy of the same 320 # Python script. Run it by starting a new copy of the same
322 # interpreter. 321 # interpreter.
323 command[0] = sys.executable 322 command[0] = sys.executable
324 323
325 if '$matching_files' in command: 324 if '$matching_files' in command:
326 splice_index = command.index('$matching_files') 325 splice_index = command.index('$matching_files')
327 command[splice_index:splice_index + 1] = matching_file_list 326 command[splice_index:splice_index + 1] = matching_file_list
328 327
329 # Use a discrete exit status code of 2 to indicate that a hook action 328 # Use a discrete exit status code of 2 to indicate that a hook action
330 # failed. Users of this script may wish to treat hook action failures 329 # failed. Users of this script may wish to treat hook action failures
331 # differently from VC failures. 330 # differently from VC failures.
332 gclient_utils.SubprocessCall(command, self.root_dir(), fail_status=2) 331 return gclient_utils.SubprocessCall(command, self.root_dir(), fail_status=2)
333 332
334 def _RunHooks(self, command, file_list, is_using_git): 333 def _RunHooks(self, command, file_list, is_using_git):
335 """Evaluates all hooks, running actions as needed. 334 """Evaluates all hooks, running actions as needed.
336 """ 335 """
337 # Hooks only run for these command types. 336 # Hooks only run for these command types.
338 if not command in ('update', 'revert', 'runhooks'): 337 if not command in ('update', 'revert', 'runhooks'):
339 return 338 return
340 339
341 # Hooks only run when --nohooks is not specified 340 # Hooks only run when --nohooks is not specified
342 if self._options.nohooks: 341 if self._options.nohooks:
(...skipping 20 matching lines...) Expand all
363 matching_file_list = [f for f in file_list if pattern.search(f)] 362 matching_file_list = [f for f in file_list if pattern.search(f)]
364 if matching_file_list: 363 if matching_file_list:
365 self._RunHookAction(hook_dict, matching_file_list) 364 self._RunHookAction(hook_dict, matching_file_list)
366 365
367 def root_dir(self): 366 def root_dir(self):
368 return self.parent.root_dir() 367 return self.parent.root_dir()
369 368
370 def enforced_os(self): 369 def enforced_os(self):
371 return self.parent.enforced_os() 370 return self.parent.enforced_os()
372 371
372 def recursion_limit(self):
373 return self.parent.recursion_limit() - 1
374
375 def tree(self, force_all):
376 return self.parent.tree(force_all)
377
378 def get_custom_deps(self, name, url):
379 """Returns a custom deps if applicable."""
380 if self.parent:
381 url = self.parent.get_custom_deps(name, url)
382 # None is a valid return value to disable a dependency.
383 return self.custom_deps.get(name, url)
384
385 def __str__(self):
386 out = []
387 for i in ('name', 'url', 'safesync_url', 'custom_deps', 'custom_vars',
388 'deps_hooks'):
389 # 'deps_file'
390 if self.__dict__[i]:
391 out.append('%s: %s' % (i, self.__dict__[i]))
392
393 for d in self.dependencies:
394 out.extend([' ' + x for x in str(d).splitlines()])
395 out.append('')
396 return '\n'.join(out)
397
398 def __repr__(self):
399 return '%s: %s' % (self.name, self.url)
400
373 401
374 class GClient(Dependency): 402 class GClient(Dependency):
375 """Main gclient checkout root where .gclient resides.""" 403 """Object that represent a gclient checkout. A tree of Dependency(), one per
404 solution or DEPS entry."""
376 SUPPORTED_COMMANDS = [ 405 SUPPORTED_COMMANDS = [
377 'cleanup', 'diff', 'export', 'pack', 'revert', 'status', 'update', 406 'cleanup', 'diff', 'export', 'pack', 'revert', 'status', 'update',
378 'runhooks' 407 'runhooks'
379 ] 408 ]
380 409
381 DEPS_OS_CHOICES = { 410 DEPS_OS_CHOICES = {
382 "win32": "win", 411 "win32": "win",
383 "win": "win", 412 "win": "win",
384 "cygwin": "win", 413 "cygwin": "win",
385 "darwin": "mac", 414 "darwin": "mac",
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 self._options = options 451 self._options = options
423 if options.deps_os: 452 if options.deps_os:
424 enforced_os = options.deps_os.split(',') 453 enforced_os = options.deps_os.split(',')
425 else: 454 else:
426 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] 455 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')]
427 if 'all' in enforced_os: 456 if 'all' in enforced_os:
428 enforced_os = self.DEPS_OS_CHOICES.itervalues() 457 enforced_os = self.DEPS_OS_CHOICES.itervalues()
429 self._enforced_os = list(set(enforced_os)) 458 self._enforced_os = list(set(enforced_os))
430 self._root_dir = root_dir 459 self._root_dir = root_dir
431 self.config_content = None 460 self.config_content = None
461 # Do not change previous behavior. Only solution level and immediate DEPS
462 # are processed.
463 self._recursion_limit = 2
432 464
433 def SetConfig(self, content): 465 def SetConfig(self, content):
434 assert self.dependencies == [] 466 assert self.dependencies == []
435 config_dict = {} 467 config_dict = {}
436 self.config_content = content 468 self.config_content = content
437 try: 469 try:
438 exec(content, config_dict) 470 exec(content, config_dict)
439 except SyntaxError, e: 471 except SyntaxError, e:
440 try: 472 try:
441 # Try to construct a human readable error message 473 # Try to construct a human readable error message
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 modified_files = gclient_scm.scm.SVN.CaptureStatus(e_dir) 695 modified_files = gclient_scm.scm.SVN.CaptureStatus(e_dir)
664 else: 696 else:
665 file_list = [] 697 file_list = []
666 scm = gclient_scm.CreateSCM(prev_entries[entry], self.root_dir(), 698 scm = gclient_scm.CreateSCM(prev_entries[entry], self.root_dir(),
667 entry_fixed) 699 entry_fixed)
668 scm.status(self._options, [], file_list) 700 scm.status(self._options, [], file_list)
669 modified_files = file_list != [] 701 modified_files = file_list != []
670 if not self._options.delete_unversioned_trees or modified_files: 702 if not self._options.delete_unversioned_trees or modified_files:
671 # There are modified files in this entry. Keep warning until 703 # There are modified files in this entry. Keep warning until
672 # removed. 704 # removed.
673 print(("\nWARNING: \"%s\" is no longer part of this client. " 705 print(('\nWARNING: \'%s\' is no longer part of this client. '
674 "It is recommended that you manually remove it.\n") % 706 'It is recommended that you manually remove it.\n') %
675 entry_fixed) 707 entry_fixed)
676 else: 708 else:
677 # Delete the entry 709 # Delete the entry
678 print("\n________ deleting \'%s\' " + 710 print('\n________ deleting \'%s\' ' +
679 "in \'%s\'") % (entry_fixed, self.root_dir()) 711 'in \'%s\'') % (entry_fixed, self.root_dir())
680 gclient_utils.RemoveDirectory(e_dir) 712 gclient_utils.RemoveDirectory(e_dir)
681 # record the current list of entries for next time 713 # record the current list of entries for next time
682 self._SaveEntries(entries) 714 self._SaveEntries(entries)
683 return 0 715 return 0
684 716
685 def PrintRevInfo(self): 717 def PrintRevInfo(self):
686 """Output revision info mapping for the client and its dependencies. 718 """Output revision info mapping for the client and its dependencies.
687 719
688 This allows the capture of an overall "revision" for the source tree that 720 This allows the capture of an overall "revision" for the source tree that
689 can be used to reproduce the same tree in the future. It is only useful for 721 can be used to reproduce the same tree in the future. It is only useful for
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 print(";\n".join(["%s: %s" % (x, entries[x]) 791 print(";\n".join(["%s: %s" % (x, entries[x])
760 for x in sorted(entries.keys())])) 792 for x in sorted(entries.keys())]))
761 793
762 # Print the snapshot configuration file 794 # Print the snapshot configuration file
763 if self._options.snapshot: 795 if self._options.snapshot:
764 config = self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient} 796 config = self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}
765 snapclient = GClient(self.root_dir(), self._options) 797 snapclient = GClient(self.root_dir(), self._options)
766 snapclient.SetConfig(config) 798 snapclient.SetConfig(config)
767 print(snapclient.config_content) 799 print(snapclient.config_content)
768 800
801 def ParseDepsFile(self, direct_reference):
802 """No DEPS to parse for a .gclient file."""
803 self.direct_reference = direct_reference
804 self.deps_parsed = True
805
769 def root_dir(self): 806 def root_dir(self):
807 """Root directory of gclient checkout."""
770 return self._root_dir 808 return self._root_dir
771 809
772 def enforced_os(self): 810 def enforced_os(self):
811 """What deps_os entries that are to be parsed."""
773 return self._enforced_os 812 return self._enforced_os
774 813
814 def recursion_limit(self):
815 """How recursive can each dependencies in DEPS file can load DEPS file."""
816 return self._recursion_limit
817
818 def tree(self, force_all):
819 """Returns a flat list of all the dependencies."""
820 def subtree(dep):
821 if not force_all and not dep.direct_reference:
822 # Was loaded from a From() keyword in a DEPS file, don't load all its
823 # dependencies.
824 return []
825 result = dep.dependencies[:]
826 for d in dep.dependencies:
827 result.extend(subtree(d))
828 return result
829 return subtree(self)
830
775 831
776 #### gclient commands. 832 #### gclient commands.
777 833
778 834
779 def CMDcleanup(parser, args): 835 def CMDcleanup(parser, args):
780 """Cleans up all working copies. 836 """Cleans up all working copies.
781 837
782 Mostly svn-specific. Simply runs 'svn cleanup' for each module. 838 Mostly svn-specific. Simply runs 'svn cleanup' for each module.
783 """ 839 """
784 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', 840 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 return CMDhelp(parser, argv) 1174 return CMDhelp(parser, argv)
1119 except gclient_utils.Error, e: 1175 except gclient_utils.Error, e:
1120 print >> sys.stderr, 'Error: %s' % str(e) 1176 print >> sys.stderr, 'Error: %s' % str(e)
1121 return 1 1177 return 1
1122 1178
1123 1179
1124 if '__main__' == __name__: 1180 if '__main__' == __name__:
1125 sys.exit(Main(sys.argv[1:])) 1181 sys.exit(Main(sys.argv[1:]))
1126 1182
1127 # vim: ts=2:sw=2:tw=80:et: 1183 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698