Index: presubmit_support.py |
diff --git a/presubmit_support.py b/presubmit_support.py |
index 91fcd047e7e142d36f9ef98d64808c7780f83510..8936ec5b1c3f8f7bcc59e7c2f13f41082e1749d6 100755 |
--- a/presubmit_support.py |
+++ b/presubmit_support.py |
@@ -173,7 +173,7 @@ class InputApi(object): |
"""Builds an InputApi object. |
Args: |
- change: A presubmit.GclChange object. |
+ change: A presubmit.Change object. |
presubmit_path: The path to the presubmit script being processed. |
is_committing: True if the change is about to be committed. |
""" |
@@ -360,7 +360,7 @@ class AffectedFile(object): |
def __init__(self, path, action, repository_root=''): |
self._path = path |
self._action = action |
- self._repository_root = repository_root |
+ self._local_root = repository_root |
self._is_directory = None |
self._properties = {} |
self.scm = '' |
@@ -380,7 +380,7 @@ class AffectedFile(object): |
def AbsoluteLocalPath(self): |
"""Returns the absolute path of this file on the local disk. |
""" |
- return normpath(os.path.join(self._repository_root, self.LocalPath())) |
+ return normpath(os.path.join(self._local_root, self.LocalPath())) |
def IsDirectory(self): |
"""Returns true if this object is a directory.""" |
@@ -489,7 +489,7 @@ class SvnAffectedFile(AffectedFile): |
return self._is_text_file |
-class GclChange(object): |
+class Change(object): |
"""Describe a change. |
Used directly by the presubmit scripts to query the current change being |
@@ -500,24 +500,27 @@ class GclChange(object): |
self.KEY: equivalent to tags['KEY'] |
""" |
+ _AFFECTED_FILES = AffectedFile |
+ |
# Matches key/value (or "tag") lines in changelist descriptions. |
- _tag_line_re = re.compile( |
+ _TAG_LINE_RE = re.compile( |
'^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$') |
- def __init__(self, change_info): |
- # Do not keep a reference to the original change_info. |
- self._name = change_info.name |
- self._full_description = change_info.description |
- self._repository_root = change_info.GetLocalRoot() |
- self.issue = change_info.issue |
- self.patchset = change_info.patchset |
+ def __init__(self, name, description, local_root, files, issue, patchset): |
+ if files is None: |
+ files = [] |
+ self._name = name |
+ self._full_description = description |
+ self._local_root = local_root |
+ self.issue = issue |
+ self.patchset = patchset |
# From the description text, build up a dictionary of key/value pairs |
# plus the description minus all key/value or "tag" lines. |
self._description_without_tags = [] |
self.tags = {} |
for line in self._full_description.splitlines(): |
- m = self._tag_line_re.match(line) |
+ m = self._TAG_LINE_RE.match(line) |
if m: |
self.tags[m.group('key')] = m.group('value') |
else: |
@@ -528,8 +531,8 @@ class GclChange(object): |
self._description_without_tags = self._description_without_tags.rstrip() |
self._affected_files = [ |
- SvnAffectedFile(info[1], info[0].strip(), self._repository_root) |
- for info in change_info.GetFiles() |
+ self._AFFECTED_FILES(info[1], info[0].strip(), self._local_root) |
+ for info in files |
] |
def Name(self): |
@@ -553,7 +556,7 @@ class GclChange(object): |
"""Returns the repository (checkout) root directory for this change, |
as an absolute path. |
""" |
- return self._repository_root |
+ return self._local_root |
def __getattr__(self, attr): |
"""Return tags directly as attributes on the object.""" |
@@ -622,6 +625,10 @@ class GclChange(object): |
self.AffectedFiles(include_deletes=False))) |
+class SvnChange(Change): |
+ _AFFECTED_FILES = SvnAffectedFile |
+ |
+ |
def ListRelevantPresubmitFiles(files, root): |
"""Finds all presubmit files that apply to a given set of source files. |
@@ -648,14 +655,13 @@ def ListRelevantPresubmitFiles(files, root): |
class PresubmitExecuter(object): |
- def __init__(self, change_info, committing): |
+ def __init__(self, change, committing): |
""" |
Args: |
- change_info: The gcl.ChangeInfo object for the change. |
+ change: The Change object. |
committing: True if 'gcl commit' is running, False if 'gcl upload' is. |
""" |
- # TODO(maruel): Determine the SCM. |
- self.change = GclChange(change_info) |
+ self.change = change |
self.committing = committing |
def ExecPresubmitScript(self, script_text, presubmit_path): |
@@ -697,7 +703,7 @@ class PresubmitExecuter(object): |
return result |
-def DoPresubmitChecks(change_info, |
+def DoPresubmitChecks(change, |
committing, |
verbose, |
output_stream, |
@@ -714,7 +720,7 @@ def DoPresubmitChecks(change_info, |
when needed. |
Args: |
- change_info: The gcl.ChangeInfo object for the change. |
+ change: The Change object. |
committing: True if 'gcl commit' is running, False if 'gcl upload' is. |
verbose: Prints debug info. |
output_stream: A stream to write output from presubmit tests to. |
@@ -725,16 +731,16 @@ def DoPresubmitChecks(change_info, |
Return: |
True if execution can continue, False if not. |
""" |
- presubmit_files = ListRelevantPresubmitFiles(change_info.GetFileNames(), |
- change_info.GetLocalRoot()) |
+ presubmit_files = ListRelevantPresubmitFiles(change.AbsoluteLocalPaths(True), |
+ change.RepositoryRoot()) |
if not presubmit_files and verbose: |
output_stream.write("Warning, no presubmit.py found.\n") |
results = [] |
- executer = PresubmitExecuter(change_info, committing) |
+ executer = PresubmitExecuter(change, committing) |
if default_presubmit: |
if verbose: |
output_stream.write("Running default presubmit script.\n") |
- fake_path = os.path.join(change_info.GetLocalRoot(), 'PRESUBMIT.py') |
+ fake_path = os.path.join(change.RepositoryRoot(), 'PRESUBMIT.py') |
results += executer.ExecPresubmitScript(default_presubmit, fake_path) |
for filename in presubmit_files: |
filename = os.path.abspath(filename) |
@@ -805,18 +811,33 @@ def Main(argv): |
help="Act recursively") |
parser.add_option("-v", "--verbose", action="store_true", |
help="Verbose output") |
+ parser.add_option("--files", default='') |
+ parser.add_option("--name", default='no name') |
+ parser.add_option("--description", default='') |
+ parser.add_option("--issue", type='int', default=0) |
+ parser.add_option("--patchset", type='int', default=0) |
+ parser.add_options("--root", default='') |
+ parser.add_options("--default_presubmit", default='') |
+ parser.add_options("--may_prompt", action='store_true') |
options, args = parser.parse_args(argv[1:]) |
- files = ParseFiles(args, options.recursive) |
+ if not options.files: |
+ options.files = ParseFiles(args, options.recursive) |
+ if not options.root: |
+ options.root = gcl.GetRepositoryRoot() |
if options.verbose: |
print "Found %d files." % len(files) |
- return not DoPresubmitChecks(gcl.ChangeInfo('No name', 0, 0, '', files, |
- gcl.GetRepositoryRoot()), |
+ return not DoPresubmitChecks(SvnChange(options.name, |
+ options.description, |
+ options.root, |
+ options.files, |
+ options.issue, |
+ options.patchset), |
options.commit, |
options.verbose, |
sys.stdout, |
sys.stdin, |
- None, |
- False) |
+ options.default_presubmit, |
+ options.may_prompt) |
if __name__ == '__main__': |