Chromium Code Reviews| Index: gcl.py |
| diff --git a/gcl.py b/gcl.py |
| index 58b6935d7f10ae6246ae9eb0aa660e88ee2075f9..ddf5dad580b13a964228a5e96ae7c0aaaca19707 100755 |
| --- a/gcl.py |
| +++ b/gcl.py |
| @@ -35,11 +35,13 @@ except ImportError: |
| sys.path.append(os.path.join(os.path.dirname(__file__), 'third_party')) |
| import simplejson as json # pylint: disable=F0401 |
| -import breakpad # pylint: disable=W0611 |
| - |
| # gcl now depends on gclient. |
| from scm import SVN |
| + |
| +import breakpad # pylint: disable=W0611 |
|
M-A Ruel
2011/03/15 19:11:57
breakpad _must_ be the first.
|
| import gclient_utils |
| +import owners |
| +import presubmit_support |
| __version__ = '1.2' |
| @@ -70,6 +72,7 @@ FILES_CACHE = {} |
| DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)" |
| DEFAULT_LINT_IGNORE_REGEX = r"$^" |
| +REVIEWERS_REGEX = r'\s*R=(.+)' |
| def CheckHomeForFile(filename): |
| """Checks the users home dir for the existence of the given file. Returns |
| @@ -286,7 +289,10 @@ class ChangeInfo(object): |
| self.name = name |
| self.issue = int(issue) |
| self.patchset = int(patchset) |
| - self.description = description |
| + self._description = None |
| + self._subject = None |
| + self._reviewers = None |
| + self._set_description(description) |
| if files is None: |
| files = [] |
| self._files = files |
| @@ -298,6 +304,48 @@ class ChangeInfo(object): |
| # Set the default value. |
| self.rietveld = GetCodeReviewSetting('CODE_REVIEW_SERVER') |
| + def _get_description(self): |
| + return self._description |
| + |
| + def _set_description(self, description): |
| + # TODO(dpranke): Cloned from git_cl.py. These should be shared. |
| + if not description: |
| + self._description = description |
| + return |
| + |
| + parsed_lines = [] |
| + reviewers_re = re.compile(REVIEWERS_REGEX) |
| + reviewers = '' |
| + subject = '' |
| + for l in description.splitlines(): |
| + if not subject: |
| + subject = l |
| + matched_reviewers = reviewers_re.match(l) |
| + if matched_reviewers: |
| + reviewers = matched_reviewers.group(1) |
| + parsed_lines.append(l) |
| + |
| + if subject.find("\r\n") != -1: |
|
M-A Ruel
2011/03/15 19:11:57
http://docs.python.org/library/stdtypes.html#str.s
chase
2011/03/15 20:48:58
single quotes here and below, please
|
| + subject = subject[:subject.find("\r\n")] |
| + if subject.find("\n") != -1: |
| + subject = subject[:subject.find("\n")] |
| + if len(subject) > 77: |
|
M-A Ruel
2011/03/15 19:11:57
The limit is in fact 100.
if len(subject) > 100
|
| + subject = subject + "..." |
|
M-A Ruel
2011/03/15 19:11:57
subject[:97]
|
| + |
| + self._subject = subject |
| + self._reviewers = reviewers |
| + self._description = '\n'.join(parsed_lines) |
| + |
| + description = property(_get_description, _set_description) |
|
M-A Ruel
2011/03/15 19:11:57
Use python 2.2 format instead:
http://docs.python.
|
| + |
| + @property |
| + def reviewers(self): |
| + return self._reviewers |
| + |
| + @property |
| + def subject(self): |
| + return self._subject |
| + |
| def NeedsUpload(self): |
| return self.needs_upload |
| @@ -714,10 +762,16 @@ def GenerateDiff(files, root=None): |
| def OptionallyDoPresubmitChecks(change_info, committing, args): |
| if FilterFlag(args, "--no_presubmit") or FilterFlag(args, "--force"): |
| - return True |
| + return presubmit_support.PresubmitOutput() |
| return DoPresubmitChecks(change_info, committing, True) |
| +def suggest_reviewers(change_info, affected_files): |
| + owners_db = owners.Database(change_info.LocalRoot(), fopen=file, |
| + os_path=os.path) |
| + return owners_db.reviewers_for(affected_files) |
| + |
| + |
| def defer_attributes(a, b): |
| """Copy attributes from an object (like a function) to another.""" |
| for x in dir(a): |
| @@ -797,7 +851,9 @@ def CMDupload(change_info, args): |
| if not change_info.GetFiles(): |
| print "Nothing to upload, changelist is empty." |
| return 0 |
| - if not OptionallyDoPresubmitChecks(change_info, False, args): |
| + |
| + output = OptionallyDoPresubmitChecks(change_info, False, args) |
| + if not output.should_continue(): |
| return 1 |
| no_watchlists = (FilterFlag(args, "--no_watchlists") or |
| FilterFlag(args, "--no-watchlists")) |
| @@ -808,6 +864,13 @@ def CMDupload(change_info, args): |
| upload_arg = ["upload.py", "-y"] |
| upload_arg.append("--server=%s" % change_info.rietveld) |
| + |
| + reviewers = change_info.reviewers or output.reviewers |
| + if (reviewers and |
| + not any(arg.startswith('-r') or arg.startswith('--reviewer') for |
| + arg in args)): |
| + upload_arg.append('--reviewers=%s' % ','.join(reviewers)) |
| + |
| upload_arg.extend(args) |
| desc_file = "" |
| @@ -841,15 +904,8 @@ def CMDupload(change_info, args): |
| if cc_list: |
| upload_arg.append("--cc=" + cc_list) |
| upload_arg.append("--description_file=" + desc_file + "") |
| - if change_info.description: |
| - subject = change_info.description[:77] |
| - if subject.find("\r\n") != -1: |
| - subject = subject[:subject.find("\r\n")] |
| - if subject.find("\n") != -1: |
| - subject = subject[:subject.find("\n")] |
| - if len(change_info.description) > 77: |
| - subject = subject + "..." |
| - upload_arg.append("--message=" + subject) |
| + if change_info.subject: |
| + upload_arg.append("--message=" + change_info.subject) |
| if GetCodeReviewSetting("PRIVATE") == "True": |
| upload_arg.append("--private") |
| @@ -984,7 +1040,8 @@ def CMDcommit(change_info, args): |
| viewvc_url = GetCodeReviewSetting("VIEW_VC") |
| change_info.description = change_info.description + '\n' |
| if viewvc_url: |
| - change_info.description += "\nCommitted: " + viewvc_url + revision |
| + change_info.description = (change_info.description + |
| + "\nCommitted: " + viewvc_url + revision) |
|
chase
2011/03/15 20:48:58
can this be reverted? seems like there's no diffe
|
| change_info.CloseIssue() |
| os.chdir(previous_cwd) |
| return 0 |
| @@ -1044,6 +1101,13 @@ def CMDchange(args): |
| affected_files = [x for x in other_files if file_re.match(x[0])] |
| unaffected_files = [x for x in other_files if not file_re.match(x[0])] |
| + suggested_reviewers = suggest_reviewers(change_info, affected_files) |
| + if suggested_reviewers: |
| + reviewers_re = re.compile(REVIEWERS_REGEX) |
| + if not any(reviewers_re.match(l) for |
|
M-A Ruel
2011/03/15 19:11:57
if not any(
reviewers_re.match(l) for l in des
|
| + l in description.splitlines()): |
| + description += '\nR=' + ','.join(suggested_reviewers) + '\n' |
| + |
| separator1 = ("\n---All lines above this line become the description.\n" |
| "---Repository Root: " + change_info.GetLocalRoot() + "\n" |
| "---Paths in this changelist (" + change_info.name + "):\n") |
| @@ -1161,8 +1225,6 @@ def CMDlint(change_info, args): |
| def DoPresubmitChecks(change_info, committing, may_prompt): |
| """Imports presubmit, then calls presubmit.DoPresubmitChecks.""" |
| - # Need to import here to avoid circular dependency. |
| - import presubmit_support |
| root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True) |
| change = presubmit_support.SvnChange(change_info.name, |
| change_info.description, |
| @@ -1176,13 +1238,14 @@ def DoPresubmitChecks(change_info, committing, may_prompt): |
| output_stream=sys.stdout, |
| input_stream=sys.stdin, |
| default_presubmit=root_presubmit, |
| - may_prompt=may_prompt) |
| + may_prompt=may_prompt, |
| + tbr=False, |
| + host_url=change_info.rietveld) |
| if not output.should_continue() and may_prompt: |
| # TODO(dpranke): move into DoPresubmitChecks(), unify cmd line args. |
| print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)" |
| - # TODO(dpranke): Return the output object and make use of it. |
| - return output.should_continue() |
| + return output |
| @no_args |