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

Side by Side Diff: presubmit_support.py

Issue 242140: Git support in presubmit tests.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: '' Created 11 years, 2 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 | « gclient_scm.py ('k') | tests/presubmit_unittest.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) 2006-2009 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2006-2009 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 """Enables directory-specific presubmit checks to run at upload and/or commit. 6 """Enables directory-specific presubmit checks to run at upload and/or commit.
7 """ 7 """
8 8
9 __version__ = '1.3.2' 9 __version__ = '1.3.2'
10 10
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 return "" 382 return ""
383 383
384 def LocalPath(self): 384 def LocalPath(self):
385 """Returns the path of this file on the local disk relative to client root. 385 """Returns the path of this file on the local disk relative to client root.
386 """ 386 """
387 return normpath(self._path) 387 return normpath(self._path)
388 388
389 def AbsoluteLocalPath(self): 389 def AbsoluteLocalPath(self):
390 """Returns the absolute path of this file on the local disk. 390 """Returns the absolute path of this file on the local disk.
391 """ 391 """
392 return normpath(os.path.join(self._local_root, self.LocalPath())) 392 return os.path.abspath(os.path.join(self._local_root, self.LocalPath()))
393 393
394 def IsDirectory(self): 394 def IsDirectory(self):
395 """Returns true if this object is a directory.""" 395 """Returns true if this object is a directory."""
396 if self._is_directory is None: 396 if self._is_directory is None:
397 path = self.AbsoluteLocalPath() 397 path = self.AbsoluteLocalPath()
398 self._is_directory = (os.path.exists(path) and 398 self._is_directory = (os.path.exists(path) and
399 os.path.isdir(path)) 399 os.path.isdir(path))
400 return self._is_directory 400 return self._is_directory
401 401
402 def Action(self): 402 def Action(self):
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 555
556 # Matches key/value (or "tag") lines in changelist descriptions. 556 # Matches key/value (or "tag") lines in changelist descriptions.
557 _TAG_LINE_RE = re.compile( 557 _TAG_LINE_RE = re.compile(
558 '^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$') 558 '^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$')
559 559
560 def __init__(self, name, description, local_root, files, issue, patchset): 560 def __init__(self, name, description, local_root, files, issue, patchset):
561 if files is None: 561 if files is None:
562 files = [] 562 files = []
563 self._name = name 563 self._name = name
564 self._full_description = description 564 self._full_description = description
565 self._local_root = local_root 565 # Convert root into an absolute path.
566 self._local_root = os.path.abspath(local_root)
566 self.issue = issue 567 self.issue = issue
567 self.patchset = patchset 568 self.patchset = patchset
568 self.scm = '' 569 self.scm = ''
569 570
570 # From the description text, build up a dictionary of key/value pairs 571 # From the description text, build up a dictionary of key/value pairs
571 # plus the description minus all key/value or "tag" lines. 572 # plus the description minus all key/value or "tag" lines.
572 self._description_without_tags = [] 573 self._description_without_tags = []
573 self.tags = {} 574 self.tags = {}
574 for line in self._full_description.splitlines(): 575 for line in self._full_description.splitlines():
575 m = self._TAG_LINE_RE.match(line) 576 m = self._TAG_LINE_RE.match(line)
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 """Executes a single presubmit script. 758 """Executes a single presubmit script.
758 759
759 Args: 760 Args:
760 script_text: The text of the presubmit script. 761 script_text: The text of the presubmit script.
761 presubmit_path: The path to the presubmit file (this will be reported via 762 presubmit_path: The path to the presubmit file (this will be reported via
762 input_api.PresubmitLocalPath()). 763 input_api.PresubmitLocalPath()).
763 764
764 Return: 765 Return:
765 A list of result objects, empty if no problems. 766 A list of result objects, empty if no problems.
766 """ 767 """
768
769 # Change to the presubmit file's directory to support local imports.
770 main_path = os.getcwd()
771 os.chdir(os.path.dirname(presubmit_path))
772
773 # Load the presubmit script into context.
767 input_api = InputApi(self.change, presubmit_path, self.committing) 774 input_api = InputApi(self.change, presubmit_path, self.committing)
768 context = {} 775 context = {}
769 exec script_text in context 776 exec script_text in context
770 777
771 # These function names must change if we make substantial changes to 778 # These function names must change if we make substantial changes to
772 # the presubmit API that are not backwards compatible. 779 # the presubmit API that are not backwards compatible.
773 if self.committing: 780 if self.committing:
774 function_name = 'CheckChangeOnCommit' 781 function_name = 'CheckChangeOnCommit'
775 else: 782 else:
776 function_name = 'CheckChangeOnUpload' 783 function_name = 'CheckChangeOnUpload'
777 if function_name in context: 784 if function_name in context:
778 context['__args'] = (input_api, OutputApi()) 785 context['__args'] = (input_api, OutputApi())
779 result = eval(function_name + '(*__args)', context) 786 result = eval(function_name + '(*__args)', context)
780 if not (isinstance(result, types.TupleType) or 787 if not (isinstance(result, types.TupleType) or
781 isinstance(result, types.ListType)): 788 isinstance(result, types.ListType)):
782 raise exceptions.RuntimeError( 789 raise exceptions.RuntimeError(
783 'Presubmit functions must return a tuple or list') 790 'Presubmit functions must return a tuple or list')
784 for item in result: 791 for item in result:
785 if not isinstance(item, OutputApi.PresubmitResult): 792 if not isinstance(item, OutputApi.PresubmitResult):
786 raise exceptions.RuntimeError( 793 raise exceptions.RuntimeError(
787 'All presubmit results must be of types derived from ' 794 'All presubmit results must be of types derived from '
788 'output_api.PresubmitResult') 795 'output_api.PresubmitResult')
789 else: 796 else:
790 result = () # no error since the script doesn't care about current event. 797 result = () # no error since the script doesn't care about current event.
791 798
799 # Return the process to the original working directory.
800 os.chdir(main_path)
792 return result 801 return result
793 802
794 803
795 def DoPresubmitChecks(change, 804 def DoPresubmitChecks(change,
796 committing, 805 committing,
797 verbose, 806 verbose,
798 output_stream, 807 output_stream,
799 input_stream, 808 input_stream,
800 default_presubmit, 809 default_presubmit,
801 may_prompt): 810 may_prompt):
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 options, args = parser.parse_args(argv[1:]) 941 options, args = parser.parse_args(argv[1:])
933 if not options.root: 942 if not options.root:
934 options.root = os.getcwd() 943 options.root = os.getcwd()
935 if os.path.isdir(os.path.join(options.root, '.git')): 944 if os.path.isdir(os.path.join(options.root, '.git')):
936 change_class = GitChange 945 change_class = GitChange
937 if not options.files: 946 if not options.files:
938 if args: 947 if args:
939 options.files = ParseFiles(args, options.recursive) 948 options.files = ParseFiles(args, options.recursive)
940 else: 949 else:
941 # Grab modified files. 950 # Grab modified files.
942 raise NotImplementedException() # TODO(maruel) Implement. 951 options.files = gclient_scm.CaptureGitStatus([options.root])
943 elif os.path.isdir(os.path.join(options.root, '.svn')): 952 elif os.path.isdir(os.path.join(options.root, '.svn')):
944 change_class = SvnChange 953 change_class = SvnChange
945 if not options.files: 954 if not options.files:
946 if args: 955 if args:
947 options.files = ParseFiles(args, options.recursive) 956 options.files = ParseFiles(args, options.recursive)
948 else: 957 else:
949 # Grab modified files. 958 # Grab modified files.
950 files = gclient_scm.CaptureSVNStatus([options.root]) 959 options.files = gclient_scm.CaptureSVNStatus([options.root])
951 else: 960 else:
952 # Doesn't seem under source control. 961 # Doesn't seem under source control.
953 change_class = Change 962 change_class = Change
954 if options.verbose: 963 if options.verbose:
955 print "Found %d files." % len(options.files) 964 if len(options.files) != 1:
965 print "Found %d files." % len(options.files)
966 else:
967 print "Found 1 file."
956 return not DoPresubmitChecks(change_class(options.name, 968 return not DoPresubmitChecks(change_class(options.name,
957 options.description, 969 options.description,
958 options.root, 970 options.root,
959 options.files, 971 options.files,
960 options.issue, 972 options.issue,
961 options.patchset), 973 options.patchset),
962 options.commit, 974 options.commit,
963 options.verbose, 975 options.verbose,
964 sys.stdout, 976 sys.stdout,
965 sys.stdin, 977 sys.stdin,
966 options.default_presubmit, 978 options.default_presubmit,
967 options.may_prompt) 979 options.may_prompt)
968 980
969 981
970 if __name__ == '__main__': 982 if __name__ == '__main__':
971 sys.exit(Main(sys.argv)) 983 sys.exit(Main(sys.argv))
OLDNEW
« no previous file with comments | « gclient_scm.py ('k') | tests/presubmit_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698