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

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, 10 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 | 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/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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 for s in self.dependencies: 578 for s in self.dependencies:
579 work_queue.enqueue(s) 579 work_queue.enqueue(s)
580 580
581 @gclient_utils.lockedmethod 581 @gclient_utils.lockedmethod
582 def _run_is_done(self, file_list, parsed_url): 582 def _run_is_done(self, file_list, parsed_url):
583 # Both these are kept for hooks that are run as a separate tree traversal. 583 # Both these are kept for hooks that are run as a separate tree traversal.
584 self._file_list = file_list 584 self._file_list = file_list
585 self._parsed_url = parsed_url 585 self._parsed_url = parsed_url
586 self._processed = True 586 self._processed = True
587 587
588 def RunHooksRecursively(self, options): 588 @staticmethod
589 """Evaluates all hooks, running actions as needed. run() 589 def GetHookAction(hook_dict, matching_file_list):
590 must have been called before to load the DEPS.""" 590 """Turn a parsed 'hook' dict into an executable command."""
591 assert self.hooks_ran == False 591 logging.debug(hook_dict)
M-A Ruel 2012/01/31 01:15:25 FTR, you'll have to remove these before committing
szager 2012/01/31 06:47:39 I don't mind removing them (done), but why? These
M-A Ruel 2012/01/31 15:18:33 I'm stupid. You can add these back.
592 logging.debug(matching_file_list)
593 command = hook_dict['action'][:]
594 if command[0] == 'python':
595 # If the hook specified "python" as the first item, the action is a
596 # Python script. Run it by starting a new copy of the same
597 # interpreter.
598 command[0] = sys.executable
599 if '$matching_files' in command:
600 splice_index = command.index('$matching_files')
601 command[splice_index:splice_index + 1] = matching_file_list
602 return command
603
604 def GetHooks(self, options, result=None):
M-A Ruel 2012/01/31 01:15:25 I think it'd be simpler if you simply returned the
szager 2012/01/31 06:47:39 Done.
605 """Evaluate all hooks, and return them in a flat list.
606
607 run() must have been called before to load the DEPS.
608 """
609 result = [] if result is None else result
M-A Ruel 2012/01/31 01:15:25 result = result or [] ?
szager 2012/01/31 06:47:39 Obsolete now.
592 if not self.should_process or not self.recursion_limit: 610 if not self.should_process or not self.recursion_limit:
593 # Don't run the hook when it is above recursion_limit. 611 # Don't run the hook when it is above recursion_limit.
594 return 612 return
595 # If "--force" was specified, run all hooks regardless of what files have 613 # If "--force" was specified, run all hooks regardless of what files have
596 # changed. 614 # changed.
597 if self.deps_hooks: 615 if self.deps_hooks:
598 # TODO(maruel): If the user is using git or git-svn, then we don't know 616 # TODO(maruel): If the user is using git or git-svn, then we don't know
599 # what files have changed so we always run all hooks. It'd be nice to fix 617 # what files have changed so we always run all hooks. It'd be nice to fix
600 # that. 618 # that.
601 if (options.force or 619 if (options.force or
602 isinstance(self.parsed_url, self.FileImpl) or 620 isinstance(self.parsed_url, self.FileImpl) or
603 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or 621 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or
604 os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))): 622 os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))):
605 for hook_dict in self.deps_hooks: 623 for hook_dict in self.deps_hooks:
606 self._RunHookAction(hook_dict, []) 624 result.append(self.GetHookAction(hook_dict, []))
607 else: 625 else:
608 # Run hooks on the basis of whether the files from the gclient operation 626 # Run hooks on the basis of whether the files from the gclient operation
609 # match each hook's pattern. 627 # match each hook's pattern.
610 for hook_dict in self.deps_hooks: 628 for hook_dict in self.deps_hooks:
611 pattern = re.compile(hook_dict['pattern']) 629 pattern = re.compile(hook_dict['pattern'])
612 matching_file_list = [ 630 matching_file_list = [
613 f for f in self.file_list_and_children if pattern.search(f) 631 f for f in self.file_list_and_children if pattern.search(f)
614 ] 632 ]
615 if matching_file_list: 633 if matching_file_list:
616 self._RunHookAction(hook_dict, matching_file_list) 634 result.append(self.GetHookAction(hook_dict, matching_file_list))
617 for s in self.dependencies: 635 for s in self.dependencies:
618 s.RunHooksRecursively(options) 636 s.GetHooks(options, result)
637 return result
619 638
620 def _RunHookAction(self, hook_dict, matching_file_list): 639 def RunHooksRecursively(self, options):
621 """Runs the action from a single hook.""" 640 assert self.hooks_ran == False
622 # A single DEPS file can specify multiple hooks so this function can be
623 # called multiple times on a single Dependency.
624 #assert self.hooks_ran == False
625 self._hooks_ran = True 641 self._hooks_ran = True
626 logging.debug(hook_dict) 642 for hook in self.GetHooks(options):
627 logging.debug(matching_file_list) 643 try:
628 command = hook_dict['action'][:] 644 gclient_utils.CheckCallAndFilterAndHeader(
629 if command[0] == 'python': 645 hook, cwd=self.root.root_dir, always=True)
630 # If the hook specified "python" as the first item, the action is a 646 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
631 # Python script. Run it by starting a new copy of the same 647 # Use a discrete exit status code of 2 to indicate that a hook action
632 # interpreter. 648 # failed. Users of this script may wish to treat hook action failures
633 command[0] = sys.executable 649 # differently from VC failures.
634 650 print >> sys.stderr, 'Error: %s' % str(e)
635 if '$matching_files' in command: 651 sys.exit(2)
636 splice_index = command.index('$matching_files')
637 command[splice_index:splice_index + 1] = matching_file_list
638
639 try:
640 gclient_utils.CheckCallAndFilterAndHeader(
641 command, cwd=self.root.root_dir, always=True)
642 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
643 # Use a discrete exit status code of 2 to indicate that a hook action
644 # failed. Users of this script may wish to treat hook action failures
645 # differently from VC failures.
646 print >> sys.stderr, 'Error: %s' % str(e)
647 sys.exit(2)
648 652
649 def subtree(self, include_all): 653 def subtree(self, include_all):
650 """Breadth first recursion excluding root node.""" 654 """Breadth first recursion excluding root node."""
651 dependencies = self.dependencies 655 dependencies = self.dependencies
652 for d in dependencies: 656 for d in dependencies:
653 if d.should_process or include_all: 657 if d.should_process or include_all:
654 yield d 658 yield d
655 for d in dependencies: 659 for d in dependencies:
656 for i in d.subtree(include_all): 660 for i in d.subtree(include_all):
657 yield i 661 yield i
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 'version of all repositories to reproduce the tree, ' 1420 'version of all repositories to reproduce the tree, '
1417 'implies -a') 1421 'implies -a')
1418 (options, args) = parser.parse_args(args) 1422 (options, args) = parser.parse_args(args)
1419 client = GClient.LoadCurrentConfig(options) 1423 client = GClient.LoadCurrentConfig(options)
1420 if not client: 1424 if not client:
1421 raise gclient_utils.Error('client not configured; see \'gclient config\'') 1425 raise gclient_utils.Error('client not configured; see \'gclient config\'')
1422 client.PrintRevInfo() 1426 client.PrintRevInfo()
1423 return 0 1427 return 0
1424 1428
1425 1429
1430 def CMDhookinfo(parser, args):
1431 """Output the hooks that would be run by `gclient runhooks`"""
1432 (options, args) = parser.parse_args(args)
1433 client = GClient.LoadCurrentConfig(options)
1434 if not client:
1435 raise gclient_utils.Error('client not configured; see \'gclient config\'')
1436 work_queue = gclient_utils.ExecutionQueue(options.jobs, None)
1437 for s in client.dependencies:
1438 work_queue.enqueue(s)
1439 work_queue.flush({}, None, [], options=options)
1440 print client.GetHooks(options)
M-A Ruel 2012/01/31 01:15:25 for hook in client.GetHooks(options): print ' '.
szager 2012/01/31 06:47:39 I'd like the output to be parse-able by python, so
1441 return 0
1442
1443
1426 def Command(name): 1444 def Command(name):
1427 return getattr(sys.modules[__name__], 'CMD' + name, None) 1445 return getattr(sys.modules[__name__], 'CMD' + name, None)
1428 1446
1429 1447
1430 def CMDhelp(parser, args): 1448 def CMDhelp(parser, args):
1431 """Prints list of commands or help for a specific command.""" 1449 """Prints list of commands or help for a specific command."""
1432 (_, args) = parser.parse_args(args) 1450 (_, args) = parser.parse_args(args)
1433 if len(args) == 1: 1451 if len(args) == 1:
1434 return Main(args + ['--help']) 1452 return Main(args + ['--help'])
1435 parser.print_help() 1453 parser.print_help()
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 except (gclient_utils.Error, subprocess2.CalledProcessError), e: 1550 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
1533 print >> sys.stderr, 'Error: %s' % str(e) 1551 print >> sys.stderr, 'Error: %s' % str(e)
1534 return 1 1552 return 1
1535 1553
1536 1554
1537 if '__main__' == __name__: 1555 if '__main__' == __name__:
1538 fix_encoding.fix_encoding() 1556 fix_encoding.fix_encoding()
1539 sys.exit(Main(sys.argv[1:])) 1557 sys.exit(Main(sys.argv[1:]))
1540 1558
1541 # vim: ts=2:sw=2:tw=80:et: 1559 # 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