mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 18:51:29 +00:00
git-cl: Set Code-Review label as a git push argument.
Bug: 877717 Change-Id: I6541a971068aae662b086eba84448bd0769f1a09 Reviewed-on: https://chromium-review.googlesource.com/c/1362405 Reviewed-by: Andrii Shyshkalov <tandrii@chromium.org> Reviewed-by: Edward Lesmes <ehmaldonado@chromium.org> Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
This commit is contained in:
@@ -613,6 +613,18 @@ def GetGerritFetchUrl(host):
|
|||||||
return '%s://%s/' % (GERRIT_PROTOCOL, host)
|
return '%s://%s/' % (GERRIT_PROTOCOL, host)
|
||||||
|
|
||||||
|
|
||||||
|
def GetCodeReviewTbrScore(host, project):
|
||||||
|
"""Given a gerrit host name and project, return the Code-Review score for TBR.
|
||||||
|
"""
|
||||||
|
conn = CreateHttpConn(host, '/projects/%s' % urllib.quote(project, safe=''))
|
||||||
|
project = ReadHttpJsonResponse(conn)
|
||||||
|
if ('labels' not in project
|
||||||
|
or 'Code-Review' not in project['labels']
|
||||||
|
or 'values' not in project['labels']['Code-Review']):
|
||||||
|
return 1
|
||||||
|
return max([int(x) for x in project['labels']['Code-Review']['values']])
|
||||||
|
|
||||||
|
|
||||||
def GetChangePageUrl(host, change_number):
|
def GetChangePageUrl(host, change_number):
|
||||||
"""Given a gerrit host name and change number, return change page url."""
|
"""Given a gerrit host name and change number, return change page url."""
|
||||||
return '%s://%s/#/c/%d/' % (GERRIT_PROTOCOL, host, change_number)
|
return '%s://%s/#/c/%d/' % (GERRIT_PROTOCOL, host, change_number)
|
||||||
@@ -976,7 +988,7 @@ def tempdir():
|
|||||||
|
|
||||||
|
|
||||||
def ChangeIdentifier(project, change_number):
|
def ChangeIdentifier(project, change_number):
|
||||||
"""Returns change identifier "project~number" suitable for |chagne| arg of
|
"""Returns change identifier "project~number" suitable for |change| arg of
|
||||||
this module API.
|
this module API.
|
||||||
|
|
||||||
Such format is allows for more efficient Gerrit routing of HTTP requests,
|
Such format is allows for more efficient Gerrit routing of HTTP requests,
|
||||||
|
|||||||
95
git_cl.py
95
git_cl.py
@@ -1613,41 +1613,6 @@ class Changelist(object):
|
|||||||
ret = upload_branch_deps(self, orig_args)
|
ret = upload_branch_deps(self, orig_args)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def SetLabels(self, enable_auto_submit, use_commit_queue, cq_dry_run):
|
|
||||||
"""Sets labels on the change based on the provided flags.
|
|
||||||
|
|
||||||
Sets labels if issue is already uploaded and known, else returns without
|
|
||||||
doing anything.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
enable_auto_submit: Sets Auto-Submit+1 on the change.
|
|
||||||
use_commit_queue: Sets Commit-Queue+2 on the change.
|
|
||||||
cq_dry_run: Sets Commit-Queue+1 on the change. Overrides Commit-Queue+2 if
|
|
||||||
both use_commit_queue and cq_dry_run are true.
|
|
||||||
"""
|
|
||||||
if not self.GetIssue():
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._codereview_impl.SetLabels(enable_auto_submit, use_commit_queue,
|
|
||||||
cq_dry_run)
|
|
||||||
return 0
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
labels = []
|
|
||||||
if enable_auto_submit:
|
|
||||||
labels.append('Auto-Submit')
|
|
||||||
if use_commit_queue or cq_dry_run:
|
|
||||||
labels.append('Commit-Queue')
|
|
||||||
print('WARNING: Failed to set label(s) on your change: %s\n'
|
|
||||||
'Either:\n'
|
|
||||||
' * Your project does not have the above label(s),\n'
|
|
||||||
' * You don\'t have permission to set the above label(s),\n'
|
|
||||||
' * There\'s a bug in this code (see stack trace below).\n' %
|
|
||||||
(', '.join(labels)))
|
|
||||||
# Still raise exception so that stack trace is printed.
|
|
||||||
raise
|
|
||||||
|
|
||||||
def SetCQState(self, new_state):
|
def SetCQState(self, new_state):
|
||||||
"""Updates the CQ state for the latest patchset.
|
"""Updates the CQ state for the latest patchset.
|
||||||
|
|
||||||
@@ -1841,13 +1806,6 @@ class _ChangelistCodereviewBase(object):
|
|||||||
"""Uploads a change to codereview."""
|
"""Uploads a change to codereview."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def SetLabels(self, enable_auto_submit, use_commit_queue, cq_dry_run):
|
|
||||||
"""Sets labels on the change based on the provided flags.
|
|
||||||
|
|
||||||
Issue must have been already uploaded and known.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def SetCQState(self, new_state):
|
def SetCQState(self, new_state):
|
||||||
"""Updates the CQ state for the latest patchset.
|
"""Updates the CQ state for the latest patchset.
|
||||||
|
|
||||||
@@ -2670,16 +2628,18 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
|
|||||||
# https://gerrit-review.googlesource.com/Documentation/user-upload.html#topic
|
# https://gerrit-review.googlesource.com/Documentation/user-upload.html#topic
|
||||||
refspec_opts.append('topic=%s' % options.topic)
|
refspec_opts.append('topic=%s' % options.topic)
|
||||||
|
|
||||||
if not change_desc.get_reviewers(tbr_only=True):
|
if options.enable_auto_submit:
|
||||||
# Change is not TBR, so we can inline setting other labels, too.
|
refspec_opts.append('l=Auto-Submit+1')
|
||||||
# TODO(crbug.com/877717): make this working for TBR, too, by figuring out
|
if options.use_commit_queue:
|
||||||
# max score for CR label somehow.
|
refspec_opts.append('l=Commit-Queue+2')
|
||||||
if options.enable_auto_submit:
|
elif options.cq_dry_run:
|
||||||
refspec_opts.append('l=Auto-Submit+1')
|
refspec_opts.append('l=Commit-Queue+1')
|
||||||
if options.use_commit_queue:
|
|
||||||
refspec_opts.append('l=Commit-Queue+2')
|
if change_desc.get_reviewers(tbr_only=True):
|
||||||
elif options.cq_dry_run:
|
score = gerrit_util.GetCodeReviewTbrScore(
|
||||||
refspec_opts.append('l=Commit-Queue+1')
|
self._GetGerritHost(),
|
||||||
|
self._GetGerritProject())
|
||||||
|
refspec_opts.append('l=Code-Review+%s' % score)
|
||||||
|
|
||||||
# Gerrit sorts hashtags, so order is not important.
|
# Gerrit sorts hashtags, so order is not important.
|
||||||
hashtags = {change_desc.sanitize_hash_tag(t) for t in options.hashtags}
|
hashtags = {change_desc.sanitize_hash_tag(t) for t in options.hashtags}
|
||||||
@@ -2740,20 +2700,6 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
|
|||||||
reviewers, cc,
|
reviewers, cc,
|
||||||
notify=bool(options.send_mail))
|
notify=bool(options.send_mail))
|
||||||
|
|
||||||
if change_desc.get_reviewers(tbr_only=True):
|
|
||||||
labels = self._GetChangeDetail(['LABELS']).get('labels', {})
|
|
||||||
score = 1
|
|
||||||
if 'Code-Review' in labels and 'values' in labels['Code-Review']:
|
|
||||||
score = max([int(x) for x in labels['Code-Review']['values'].keys()])
|
|
||||||
print('Adding self-LGTM (Code-Review +%d) because of TBRs.' % score)
|
|
||||||
gerrit_util.SetReview(
|
|
||||||
self._GetGerritHost(),
|
|
||||||
self._GerritChangeIdentifier(),
|
|
||||||
msg='Self-approving for TBR',
|
|
||||||
labels={'Code-Review': score})
|
|
||||||
# Labels aren't set through refspec only if tbr is set (see check above).
|
|
||||||
self.SetLabels(options.enable_auto_submit, options.use_commit_queue,
|
|
||||||
options.cq_dry_run)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def _ComputeParent(self, remote, upstream_branch, custom_cl_base, force,
|
def _ComputeParent(self, remote, upstream_branch, custom_cl_base, force,
|
||||||
@@ -2830,23 +2776,6 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
|
|||||||
else:
|
else:
|
||||||
DieWithError('ERROR: Gerrit commit-msg hook not installed.')
|
DieWithError('ERROR: Gerrit commit-msg hook not installed.')
|
||||||
|
|
||||||
def SetLabels(self, enable_auto_submit, use_commit_queue, cq_dry_run):
|
|
||||||
"""Sets labels on the change based on the provided flags."""
|
|
||||||
labels = {}
|
|
||||||
notify = None;
|
|
||||||
if enable_auto_submit:
|
|
||||||
labels['Auto-Submit'] = 1
|
|
||||||
if use_commit_queue:
|
|
||||||
labels['Commit-Queue'] = 2
|
|
||||||
elif cq_dry_run:
|
|
||||||
labels['Commit-Queue'] = 1
|
|
||||||
notify = False
|
|
||||||
if labels:
|
|
||||||
gerrit_util.SetReview(
|
|
||||||
self._GetGerritHost(),
|
|
||||||
self._GerritChangeIdentifier(),
|
|
||||||
labels=labels, notify=notify)
|
|
||||||
|
|
||||||
def SetCQState(self, new_state):
|
def SetCQState(self, new_state):
|
||||||
"""Sets the Commit-Queue label assuming canonical CQ config for Gerrit."""
|
"""Sets the Commit-Queue label assuming canonical CQ config for Gerrit."""
|
||||||
vote_map = {
|
vote_map = {
|
||||||
|
|||||||
@@ -147,6 +147,8 @@ KNOWN_SUBCOMMAND_ARGS = {
|
|||||||
'cc',
|
'cc',
|
||||||
'hashtag',
|
'hashtag',
|
||||||
'l=Auto-Submit+1',
|
'l=Auto-Submit+1',
|
||||||
|
'l=Code-Review+1',
|
||||||
|
'l=Code-Review+2',
|
||||||
'l=Commit-Queue+1',
|
'l=Commit-Queue+1',
|
||||||
'l=Commit-Queue+2',
|
'l=Commit-Queue+2',
|
||||||
'label',
|
'label',
|
||||||
|
|||||||
@@ -1059,10 +1059,17 @@ class TestGitCl(TestCase):
|
|||||||
if c in cc:
|
if c in cc:
|
||||||
cc.remove(c)
|
cc.remove(c)
|
||||||
|
|
||||||
if not tbr:
|
for k, v in sorted((labels or {}).items()):
|
||||||
for k, v in sorted((labels or {}).items()):
|
ref_suffix += ',l=%s+%d' % (k, v)
|
||||||
ref_suffix += ',l=%s+%d' % (k, v)
|
metrics_arguments.append('l=%s+%d' % (k, v))
|
||||||
metrics_arguments.append('l=%s+%d' % (k, v))
|
|
||||||
|
if tbr:
|
||||||
|
calls += [
|
||||||
|
(('GetCodeReviewTbrScore',
|
||||||
|
'%s-review.googlesource.com' % short_hostname,
|
||||||
|
'my/repo'),
|
||||||
|
2,),
|
||||||
|
]
|
||||||
|
|
||||||
calls += [
|
calls += [
|
||||||
(('time.time',), 1000,),
|
(('time.time',), 1000,),
|
||||||
@@ -1115,29 +1122,6 @@ class TestGitCl(TestCase):
|
|||||||
notify),
|
notify),
|
||||||
''),
|
''),
|
||||||
]
|
]
|
||||||
if tbr:
|
|
||||||
calls += [
|
|
||||||
(('GetChangeDetail', 'chromium-review.googlesource.com',
|
|
||||||
'my%2Frepo~123456', ['LABELS']), {
|
|
||||||
'labels': {
|
|
||||||
'Code-Review': {
|
|
||||||
'default_value': 0,
|
|
||||||
'all': [],
|
|
||||||
'values': {
|
|
||||||
'+2': 'lgtm, approved',
|
|
||||||
'+1': 'lgtm, but someone else must approve',
|
|
||||||
' 0': 'No score',
|
|
||||||
'-1': 'Don\'t submit as-is',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
(('SetReview',
|
|
||||||
'chromium-review.googlesource.com',
|
|
||||||
'my%2Frepo~123456',
|
|
||||||
'Self-approving for TBR',
|
|
||||||
{'Code-Review': 2}, None), ''),
|
|
||||||
]
|
|
||||||
calls += cls._git_post_upload_calls()
|
calls += cls._git_post_upload_calls()
|
||||||
return calls
|
return calls
|
||||||
|
|
||||||
@@ -1261,6 +1245,8 @@ class TestGitCl(TestCase):
|
|||||||
notify=True)
|
notify=True)
|
||||||
|
|
||||||
def test_gerrit_reviewer_multiple(self):
|
def test_gerrit_reviewer_multiple(self):
|
||||||
|
self.mock(git_cl.gerrit_util, 'GetCodeReviewTbrScore',
|
||||||
|
lambda *a: self._mocked_call('GetCodeReviewTbrScore', *a))
|
||||||
self._run_gerrit_upload_test(
|
self._run_gerrit_upload_test(
|
||||||
[],
|
[],
|
||||||
'desc\nTBR=reviewer@example.com\nBUG=\nR=another@example.com\n'
|
'desc\nTBR=reviewer@example.com\nBUG=\nR=another@example.com\n'
|
||||||
@@ -1269,7 +1255,8 @@ class TestGitCl(TestCase):
|
|||||||
['reviewer@example.com', 'another@example.com'],
|
['reviewer@example.com', 'another@example.com'],
|
||||||
expected_upstream_ref='origin/master',
|
expected_upstream_ref='origin/master',
|
||||||
cc=['more@example.com', 'people@example.com'],
|
cc=['more@example.com', 'people@example.com'],
|
||||||
tbr='reviewer@example.com')
|
tbr='reviewer@example.com',
|
||||||
|
labels={'Code-Review': 2})
|
||||||
|
|
||||||
def test_gerrit_upload_squash_first_is_default(self):
|
def test_gerrit_upload_squash_first_is_default(self):
|
||||||
self._run_gerrit_upload_test(
|
self._run_gerrit_upload_test(
|
||||||
|
|||||||
Reference in New Issue
Block a user