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

Unified Diff: git_cl/git_cl.py

Issue 6646009: update git-cl for OWNERS file support via .git/hooks/pre-cl-* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: clean up after running owners-related git-cl tests Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « git-cl-upload-hook ('k') | git_cl/test/git-cl-test-hook » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: git_cl/git_cl.py
diff --git a/git_cl/git_cl.py b/git_cl/git_cl.py
index ec3bd9770f0fba980cc42c68618548075de85467..c729f9b1cf0c6b2005f6522599576e3710e54b28 100644
--- a/git_cl/git_cl.py
+++ b/git_cl/git_cl.py
@@ -54,7 +54,8 @@ def Popen(cmd, **kwargs):
def RunCommand(cmd, error_ok=False, error_message=None,
- redirect_stdout=True, swallow_stderr=False, **kwargs):
+ redirect_stdout=True, swallow_stderr=False,
+ tee_filter=None, **kwargs):
if redirect_stdout:
stdout = subprocess.PIPE
else:
@@ -64,7 +65,18 @@ def RunCommand(cmd, error_ok=False, error_message=None,
else:
stderr = None
proc = Popen(cmd, stdout=stdout, stderr=stderr, **kwargs)
- output = proc.communicate()[0]
+ if tee_filter:
+ output = ''
+ while True:
+ line = proc.stdout.readline()
+ if line == '' and proc.poll() != None:
+ break
+ if not tee_filter(line):
+ print line
+ output += line + '\n'
+ else:
+ output = proc.communicate()[0]
+
if not error_ok and proc.returncode != 0:
DieWithError('Command "%s" failed.\n' % (' '.join(cmd)) +
(error_message or output or ''))
@@ -479,6 +491,76 @@ def GetCodereviewSettingsInteractively():
# svn-based hackery.
+class HookResults(object):
+ """Contains the parsed output of the presubmit hooks."""
+ def __init__(self, output_from_hooks=None):
+ self.reviewers = []
+ self.output = None
+ self._ParseOutputFromHooks(output_from_hooks)
+
+ def _ParseOutputFromHooks(self, output_from_hooks):
+ if not output_from_hooks:
+ return
+ lines = []
+ reviewers = []
+ reviewer_regexp = re.compile('ADD: R=(.+)')
+ for l in output_from_hooks.splitlines():
+ m = reviewer_regexp.match(l)
+ if m:
+ reviewers.extend(m.group(1).split(','))
+ else:
+ lines.append(l)
+ self.output = '\n'.join(lines)
+ self.reviewers = ','.join(reviewers)
+
+
+class ChangeDescription(object):
+ """Contains a parsed form of the change description."""
+ def __init__(self, subject, log_desc, reviewers):
+ self.subject = subject
+ self.log_desc = log_desc
+ self.reviewers = reviewers
+ self.description = self.log_desc
+
+ def Update(self):
+ initial_text = """# Enter a description of the change.
+# This will displayed on the codereview site.
+# The first line will also be used as the subject of the review.
+"""
+ initial_text += self.description
+ if 'R=' not in self.description and self.reviewers:
+ initial_text += '\nR=' + self.reviewers
+ if 'BUG=' not in self.description:
+ initial_text += '\nBUG='
+ if 'TEST=' not in self.description:
+ initial_text += '\nTEST='
+ self._ParseDescription(UserEditedLog(initial_text))
+
+ def _ParseDescription(self, description):
+ if not description:
+ self.description = description
+ return
+
+ parsed_lines = []
+ reviewers_regexp = re.compile('\s*R=(.+)')
+ reviewers = ''
+ subject = ''
+ for l in description.splitlines():
+ if not subject:
+ subject = l
+ matched_reviewers = reviewers_regexp.match(l)
+ if matched_reviewers:
+ reviewers = matched_reviewers.group(1)
+ parsed_lines.append(l)
+
+ self.description = '\n'.join(parsed_lines) + '\n'
+ self.subject = subject
+ self.reviewers = reviewers
+
+ def IsEmpty(self):
+ return not self.description
+
+
def FindCodereviewSettingsFile(filename='codereview.settings'):
"""Finds the given file starting in the cwd and going up.
@@ -669,13 +751,19 @@ def UserEditedLog(starting_text):
return stripcomment_re.sub('', text).strip()
-def RunHook(hook, upstream_branch, error_ok=False):
+def RunHook(hook, upstream_branch, rietveld_server, tbr=False,
+ error_ok=False):
"""Run a given hook if it exists. By default, we fail on errors."""
hook = '%s/%s' % (settings.GetRoot(), hook)
if not os.path.exists(hook):
- return
- return RunCommand([hook, upstream_branch], error_ok=error_ok,
- redirect_stdout=False)
+ return HookResults()
+ cmd = [hook]
+ if tbr:
+ cmd.append('--tbr')
+ cmd.extend(['--host-url=' + rietveld_server, upstream_branch])
+ output = RunCommand(cmd, error_ok=error_ok, redirect_stdout=True,
+ tee_filter=lambda l: l.startswith('ADD:'))
+ return HookResults(output)
def CMDpresubmit(parser, args):
@@ -691,20 +779,23 @@ def CMDpresubmit(parser, args):
print 'Cannot presubmit with a dirty tree. You must commit locally first.'
return 1
+ cl = Changelist()
if args:
base_branch = args[0]
else:
# Default to diffing against the "upstream" branch.
- base_branch = Changelist().GetUpstreamBranch()
+ base_branch = cl.GetUpstreamBranch()
if options.upload:
print '*** Presubmit checks for UPLOAD would report: ***'
return not RunHook(PREUPLOAD_HOOK, upstream_branch=base_branch,
- error_ok=True)
+ rietveld_server=cl.GetRietveldServer(), tbr=False,
+ error_ok=True).output
else:
print '*** Presubmit checks for DCOMMIT would report: ***'
return not RunHook(PREDCOMMIT_HOOK, upstream_branch=base_branch,
- error_ok=True)
+ rietveld_server=cl.GetRietveldServer(), tbr=options.tbr,
+ error_ok=True).output
@usage('[args to "git diff"]')
@@ -743,7 +834,14 @@ def CMDupload(parser, args):
args = [base_branch + "..."]
if not options.bypass_hooks:
- RunHook(PREUPLOAD_HOOK, upstream_branch=base_branch, error_ok=False)
+ hook_results = RunHook(PREUPLOAD_HOOK, upstream_branch=base_branch,
+ rietveld_server=cl.GetRietveldServer(), tbr=False,
+ error_ok=False)
+ else:
+ hook_results = HookResults()
+
+ if not options.reviewers and hook_results.reviewers:
+ options.reviewers = hook_results.reviewers
# --no-ext-diff is broken in some versions of Git, so try to work around
# this by overriding the environment (but there is still a problem if the
@@ -756,8 +854,6 @@ def CMDupload(parser, args):
upload_args = ['--assume_yes'] # Don't ask about untracked files.
upload_args.extend(['--server', cl.GetRietveldServer()])
- if options.reviewers:
- upload_args.extend(['--reviewers', options.reviewers])
if options.emulate_svn_auto_props:
upload_args.append('--emulate_svn_auto_props')
if options.send_mail:
@@ -778,28 +874,19 @@ def CMDupload(parser, args):
"Adding patch to that issue." % cl.GetIssue())
else:
log_desc = CreateDescriptionFromLog(args)
- if options.from_logs:
- # Uses logs as description and message as subject.
- subject = options.message
- change_desc = subject + '\n\n' + log_desc
- else:
- initial_text = """# Enter a description of the change.
-# This will displayed on the codereview site.
-# The first line will also be used as the subject of the review.
-"""
- if 'BUG=' not in log_desc:
- log_desc += '\nBUG='
- if 'TEST=' not in log_desc:
- log_desc += '\nTEST='
- change_desc = UserEditedLog(initial_text + log_desc)
- subject = ''
- if change_desc:
- subject = change_desc.splitlines()[0]
- if not change_desc:
+ change_desc = ChangeDescription(options.message, log_desc,
+ options.reviewers)
+ if not options.from_logs:
+ change_desc.Update()
+
+ if change_desc.IsEmpty():
print "Description is empty; aborting."
return 1
- upload_args.extend(['--message', subject])
- upload_args.extend(['--description', change_desc])
+
+ upload_args.extend(['--message', change_desc.subject])
+ upload_args.extend(['--description', change_desc.description])
+ if change_desc.reviewers:
+ upload_args.extend(['--reviewers', change_desc.reviewers])
cc = ','.join(filter(None, (settings.GetCCList(), options.cc)))
if cc:
upload_args.extend(['--cc', cc])
@@ -831,7 +918,7 @@ def CMDupload(parser, args):
print '\nGot exception while uploading -- saving description to %s\n' \
% backup_path
backup_file = open(backup_path, 'w')
- backup_file.write(change_desc)
+ backup_file.write(change_desc.description)
backup_file.close()
raise
@@ -899,8 +986,10 @@ def SendUpstream(parser, args, cmd):
'before attempting to %s.' % (base_branch, cmd))
return 1
- if not options.force and not options.bypass_hooks:
- RunHook(PREDCOMMIT_HOOK, upstream_branch=base_branch, error_ok=False)
+ if not options.bypass_hooks:
+ RunHook(PREDCOMMIT_HOOK, upstream_branch=base_branch,
+ rietveld_server=cl.GetRietveldServer(), tbr=options.tbr,
+ error_ok=False)
if cmd == 'dcommit':
# Check the tree status if the tree status URL is set.
@@ -940,6 +1029,7 @@ def SendUpstream(parser, args, cmd):
if cl.GetIssue():
description = cl.GetDescription()
+ # TODO(dpranke): Update to use ChangeDescription object.
if not description:
description = """# Enter a description of the change.
# This will be used as the change log for the commit.
@@ -1031,8 +1121,9 @@ def SendUpstream(parser, args, cmd):
if retcode == 0:
hook = POSTUPSTREAM_HOOK_PATTERN % cmd
if os.path.isfile(hook):
- RunHook(hook, upstream_branch=base_branch, error_ok=True)
-
+ RunHook(hook, upstream_branch=base_branch,
+ rietveld_server=cl.GetRietveldServer(), tbr=options.tbr,
+ error_ok=True)
return 0
« no previous file with comments | « git-cl-upload-hook ('k') | git_cl/test/git-cl-test-hook » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698