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

Side by Side Diff: gclient.py

Issue 9232068: Added `gclient hookinfo`. This will be used to convert hooks into (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 8 years, 9 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 | tests/gclient_test.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 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 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 for s in self.dependencies: 597 for s in self.dependencies:
598 work_queue.enqueue(s) 598 work_queue.enqueue(s)
599 599
600 @gclient_utils.lockedmethod 600 @gclient_utils.lockedmethod
601 def _run_is_done(self, file_list, parsed_url): 601 def _run_is_done(self, file_list, parsed_url):
602 # Both these are kept for hooks that are run as a separate tree traversal. 602 # Both these are kept for hooks that are run as a separate tree traversal.
603 self._file_list = file_list 603 self._file_list = file_list
604 self._parsed_url = parsed_url 604 self._parsed_url = parsed_url
605 self._processed = True 605 self._processed = True
606 606
607 def RunHooksRecursively(self, options): 607 @staticmethod
608 """Evaluates all hooks, running actions as needed. run() 608 def GetHookAction(hook_dict, matching_file_list):
609 must have been called before to load the DEPS.""" 609 """Turns a parsed 'hook' dict into an executable command."""
610 assert self.hooks_ran == False 610 logging.debug(hook_dict)
611 logging.debug(matching_file_list)
612 command = hook_dict['action'][:]
613 if command[0] == 'python':
614 # If the hook specified "python" as the first item, the action is a
615 # Python script. Run it by starting a new copy of the same
616 # interpreter.
617 command[0] = sys.executable
618 if '$matching_files' in command:
619 splice_index = command.index('$matching_files')
620 command[splice_index:splice_index + 1] = matching_file_list
621 return command
622
623 def GetHooks(self, options):
624 """Evaluates all hooks, and return them in a flat list.
625
626 RunOnDeps() must have been called before to load the DEPS.
627 """
628 result = []
611 if not self.should_process or not self.recursion_limit: 629 if not self.should_process or not self.recursion_limit:
612 # Don't run the hook when it is above recursion_limit. 630 # Don't run the hook when it is above recursion_limit.
613 return 631 return result
614 # If "--force" was specified, run all hooks regardless of what files have 632 # If "--force" was specified, run all hooks regardless of what files have
615 # changed. 633 # changed.
616 if self.deps_hooks: 634 if self.deps_hooks:
617 # TODO(maruel): If the user is using git or git-svn, then we don't know 635 # TODO(maruel): If the user is using git or git-svn, then we don't know
618 # what files have changed so we always run all hooks. It'd be nice to fix 636 # what files have changed so we always run all hooks. It'd be nice to fix
619 # that. 637 # that.
620 if (options.force or 638 if (options.force or
621 isinstance(self.parsed_url, self.FileImpl) or 639 isinstance(self.parsed_url, self.FileImpl) or
622 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or 640 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or
623 os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))): 641 os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))):
624 for hook_dict in self.deps_hooks: 642 for hook_dict in self.deps_hooks:
625 self._RunHookAction(hook_dict, []) 643 result.append(self.GetHookAction(hook_dict, []))
626 else: 644 else:
627 # Run hooks on the basis of whether the files from the gclient operation 645 # Run hooks on the basis of whether the files from the gclient operation
628 # match each hook's pattern. 646 # match each hook's pattern.
629 for hook_dict in self.deps_hooks: 647 for hook_dict in self.deps_hooks:
630 pattern = re.compile(hook_dict['pattern']) 648 pattern = re.compile(hook_dict['pattern'])
631 matching_file_list = [ 649 matching_file_list = [
632 f for f in self.file_list_and_children if pattern.search(f) 650 f for f in self.file_list_and_children if pattern.search(f)
633 ] 651 ]
634 if matching_file_list: 652 if matching_file_list:
635 self._RunHookAction(hook_dict, matching_file_list) 653 result.append(self.GetHookAction(hook_dict, matching_file_list))
636 for s in self.dependencies: 654 for s in self.dependencies:
637 s.RunHooksRecursively(options) 655 result.extend(s.GetHooks(options))
656 return result
638 657
639 def _RunHookAction(self, hook_dict, matching_file_list): 658 def RunHooksRecursively(self, options):
640 """Runs the action from a single hook.""" 659 assert self.hooks_ran == False
641 # A single DEPS file can specify multiple hooks so this function can be
642 # called multiple times on a single Dependency.
643 #assert self.hooks_ran == False
644 self._hooks_ran = True 660 self._hooks_ran = True
645 logging.debug(hook_dict) 661 for hook in self.GetHooks(options):
646 logging.debug(matching_file_list) 662 try:
647 command = hook_dict['action'][:] 663 gclient_utils.CheckCallAndFilterAndHeader(
648 if command[0] == 'python': 664 hook, cwd=self.root.root_dir, always=True)
649 # If the hook specified "python" as the first item, the action is a 665 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
650 # Python script. Run it by starting a new copy of the same 666 # Use a discrete exit status code of 2 to indicate that a hook action
651 # interpreter. 667 # failed. Users of this script may wish to treat hook action failures
652 command[0] = sys.executable 668 # differently from VC failures.
653 669 print >> sys.stderr, 'Error: %s' % str(e)
654 if '$matching_files' in command: 670 sys.exit(2)
655 splice_index = command.index('$matching_files')
656 command[splice_index:splice_index + 1] = matching_file_list
657
658 try:
659 gclient_utils.CheckCallAndFilterAndHeader(
660 command, cwd=self.root.root_dir, always=True)
661 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
662 # Use a discrete exit status code of 2 to indicate that a hook action
663 # failed. Users of this script may wish to treat hook action failures
664 # differently from VC failures.
665 print >> sys.stderr, 'Error: %s' % str(e)
666 sys.exit(2)
667 671
668 def subtree(self, include_all): 672 def subtree(self, include_all):
669 """Breadth first recursion excluding root node.""" 673 """Breadth first recursion excluding root node."""
670 dependencies = self.dependencies 674 dependencies = self.dependencies
671 for d in dependencies: 675 for d in dependencies:
672 if d.should_process or include_all: 676 if d.should_process or include_all:
673 yield d 677 yield d
674 for d in dependencies: 678 for d in dependencies:
675 for i in d.subtree(include_all): 679 for i in d.subtree(include_all):
676 yield i 680 yield i
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 'version of all repositories to reproduce the tree, ' 1451 'version of all repositories to reproduce the tree, '
1448 'implies -a') 1452 'implies -a')
1449 (options, args) = parser.parse_args(args) 1453 (options, args) = parser.parse_args(args)
1450 client = GClient.LoadCurrentConfig(options) 1454 client = GClient.LoadCurrentConfig(options)
1451 if not client: 1455 if not client:
1452 raise gclient_utils.Error('client not configured; see \'gclient config\'') 1456 raise gclient_utils.Error('client not configured; see \'gclient config\'')
1453 client.PrintRevInfo() 1457 client.PrintRevInfo()
1454 return 0 1458 return 0
1455 1459
1456 1460
1461 def CMDhookinfo(parser, args):
1462 """Output the hooks that would be run by `gclient runhooks`"""
1463 (options, args) = parser.parse_args(args)
1464 options.force = True
1465 client = GClient.LoadCurrentConfig(options)
1466 if not client:
1467 raise gclient_utils.Error('client not configured; see \'gclient config\'')
1468 client.RunOnDeps(None, [])
1469 print '; '.join(' '.join(hook) for hook in client.GetHooks(options))
1470 return 0
1471
1472
1457 def Command(name): 1473 def Command(name):
1458 return getattr(sys.modules[__name__], 'CMD' + name, None) 1474 return getattr(sys.modules[__name__], 'CMD' + name, None)
1459 1475
1460 1476
1461 def CMDhelp(parser, args): 1477 def CMDhelp(parser, args):
1462 """Prints list of commands or help for a specific command.""" 1478 """Prints list of commands or help for a specific command."""
1463 (_, args) = parser.parse_args(args) 1479 (_, args) = parser.parse_args(args)
1464 if len(args) == 1: 1480 if len(args) == 1:
1465 return Main(args + ['--help']) 1481 return Main(args + ['--help'])
1466 parser.print_help() 1482 parser.print_help()
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 except (gclient_utils.Error, subprocess2.CalledProcessError), e: 1581 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
1566 print >> sys.stderr, 'Error: %s' % str(e) 1582 print >> sys.stderr, 'Error: %s' % str(e)
1567 return 1 1583 return 1
1568 1584
1569 1585
1570 if '__main__' == __name__: 1586 if '__main__' == __name__:
1571 fix_encoding.fix_encoding() 1587 fix_encoding.fix_encoding()
1572 sys.exit(Main(sys.argv[1:])) 1588 sys.exit(Main(sys.argv[1:]))
1573 1589
1574 # vim: ts=2:sw=2:tw=80:et: 1590 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698