Commit 833c94c6 authored by dimu's avatar dimu Committed by Di Mu

Create recipe_modules/gerrit to interact with gerrit REST API

BUG=
R=mmoss,agable

Change-Id: I6410c28280ed05cf384a3da93e6b154c6081e039
Reviewed-on: https://chromium-review.googlesource.com/427375Reviewed-by: 's avatarMichael Moss <mmoss@chromium.org>
parent 54985b6b
#!/usr/bin/python
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Simple client for the Gerrit REST API.
Example usage:
./gerrit_client.py [command] [args]""
"""
from __future__ import print_function
import json
import logging
import optparse
import subcommand
import sys
import urllib
import urlparse
from third_party import colorama
import fix_encoding
import gerrit_util
import setup_color
__version__ = '0.1'
# Shortcut since it quickly becomes redundant.
Fore = colorama.Fore
def write_result(result, opt):
if opt.json_file:
with open(opt.json_file, 'w') as json_file:
json_file.write(json.dumps(result))
@subcommand.usage('[args ...]')
def CMDbranchinfo(parser, args):
parser.add_option('--branch', dest='branch', help='branch name')
(opt, args) = parser.parse_args(args)
host = urlparse.urlparse(opt.host).netloc
project = urllib.quote_plus(opt.project)
branch = urllib.quote_plus(opt.branch)
result = gerrit_util.GetGerritBranch(host, project, branch)
logging.info(result)
write_result(result, opt)
@subcommand.usage('[args ...]')
def CMDbranch(parser, args):
parser.add_option('--branch', dest='branch', help='branch name')
parser.add_option('--commit', dest='commit', help='commit hash')
(opt, args) = parser.parse_args(args)
project = urllib.quote_plus(opt.project)
host = urlparse.urlparse(opt.host).netloc
branch = urllib.quote_plus(opt.branch)
commit = urllib.quote_plus(opt.commit)
result = gerrit_util.CreateGerritBranch(host, project, branch, commit)
logging.info(result)
write_result(result, opt)
class OptionParser(optparse.OptionParser):
"""Creates the option parse and add --verbose support."""
def __init__(self, *args, **kwargs):
optparse.OptionParser.__init__(
self, *args, prog='git cl', version=__version__, **kwargs)
self.add_option(
'--verbose', action='count', default=0,
help='Use 2 times for more debugging info')
self.add_option('--host', dest='host', help='Url of host.')
self.add_option('--project', dest='project', help='project name')
self.add_option(
'--json_file', dest='json_file', help='output json filepath')
def parse_args(self, args=None, values=None):
options, args = optparse.OptionParser.parse_args(self, args, values)
levels = [logging.WARNING, logging.INFO, logging.DEBUG]
logging.basicConfig(level=levels[min(options.verbose, len(levels) - 1)])
return options, args
def main(argv):
if sys.hexversion < 0x02060000:
print('\nYour python version %s is unsupported, please upgrade.\n'
%(sys.version.split(' ', 1)[0],),
file=sys.stderr)
return 2
dispatcher = subcommand.CommandDispatcher(__name__)
return dispatcher.execute(OptionParser(), argv)
if __name__ == '__main__':
# These affect sys.stdout so do it outside of main() to simplify mocks in
# unit testing.
fix_encoding.fix_encoding()
setup_color.init()
try:
sys.exit(main(sys.argv[1:]))
except KeyboardInterrupt:
sys.stderr.write('interrupted\n')
sys.exit(1)
\ No newline at end of file
......@@ -772,6 +772,39 @@ def ResetReviewLabels(host, change, label, value='0', message=None,
'a new patchset was uploaded.' % change)
def CreateGerritBranch(host, project, branch, commit):
"""
Create a new branch from given project and commit
https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#create-branch
Returns:
A JSON with 'ref' key
"""
path = 'projects/%s/branches/%s' % (project, branch)
body = {'revision': commit}
conn = CreateHttpConn(host, path, reqtype='PUT', body=body)
response = ReadHttpJsonResponse(conn)
if response:
return response
raise GerritError(200, 'Unable to create gerrit branch')
def GetGerritBranch(host, project, branch):
"""
Get a branch from given project and commit
https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-branch
Returns:
A JSON object with 'revision' key
"""
path = 'projects/%s/branches/%s' % (project, branch)
conn = CreateHttpConn(host, path, reqtype='GET')
response = ReadHttpJsonResponse(conn)
if response:
return response
raise GerritError(200, 'Unable to get gerrit branch')
@contextlib.contextmanager
def tempdir():
tdir = None
......
DEPS = [
'recipe_engine/json',
'recipe_engine/path',
'recipe_engine/python',
'recipe_engine/raw_io',
]
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from recipe_engine import recipe_api
class GerritApi(recipe_api.RecipeApi):
"""Module for interact with gerrit endpoints"""
def __call__(self, name, cmd, infra_step=True, **kwargs):
"""Wrapper for easy calling of gerrit_utils steps."""
assert isinstance(cmd, (list, tuple))
prefix = 'gerrit '
kwargs.setdefault('env', {})
kwargs['env'].setdefault('PATH', '%(PATH)s')
kwargs['env']['PATH'] = self.m.path.pathsep.join([
kwargs['env']['PATH'], str(self._module.PACKAGE_REPO_ROOT)])
return self.m.python(prefix + name,
self.package_repo_resource('gerrit_client.py'),
cmd,
infra_step=infra_step,
**kwargs)
def create_gerrit_branch(self, host, project, branch, commit, **kwargs):
"""
Create a new branch from given project and commit
Returns:
the ref of the branch created
"""
args = [
'branch',
'--host', host,
'--project', project,
'--branch', branch,
'--commit', commit,
'--json_file', self.m.json.output()
]
step_name = 'create_gerrit_branch'
step_result = self(step_name, args, **kwargs)
ref = step_result.json.output.get('ref')
return ref
def get_gerrit_branch(self, host, project, branch, **kwargs):
"""
Get a branch from given project and commit
Returns:
the revision of the branch
"""
args = [
'branchinfo',
'--host', host,
'--project', project,
'--branch', branch,
'--json_file', self.m.json.output()
]
step_name='get_gerrit_branch'
step_result = self(step_name, args, **kwargs)
revision = step_result.json.output.get('revision')
return revision
[
{
"cmd": [
"python",
"-u",
"RECIPE_PACKAGE_REPO[depot_tools]/gerrit_client.py",
"branch",
"--host",
"https://chromium-review.googlesource.com/a",
"--project",
"v8/v8",
"--branch",
"test",
"--commit",
"67ebf73496383c6777035e374d2d664009e2aa5c",
"--json_file",
"/path/to/tmp/json"
],
"env": {
"PATH": "%(PATH)s:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "gerrit create_gerrit_branch",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"can_delete\": true, @@@",
"@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/heads/test\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"revision\": \"76016386a0d8ecc7b6be212424978bb45959d668\"@@@",
"@@@STEP_LOG_LINE@json.output@}@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{
"cmd": [
"python",
"-u",
"RECIPE_PACKAGE_REPO[depot_tools]/gerrit_client.py",
"branchinfo",
"--host",
"https://chromium-review.googlesource.com/a",
"--project",
"v8/v8",
"--branch",
"master",
"--json_file",
"/path/to/tmp/json"
],
"env": {
"PATH": "%(PATH)s:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "gerrit get_gerrit_branch",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/heads/master\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"revision\": \"67ebf73496383c6777035e374d2d664009e2aa5c\"@@@",
"@@@STEP_LOG_LINE@json.output@}@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{
"name": "$result",
"recipe_result": null,
"status_code": 0
}
]
\ No newline at end of file
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
DEPS = [
'gerrit'
]
def RunSteps(api):
host = 'https://chromium-review.googlesource.com/a'
project = 'v8/v8'
branch = 'test'
commit = '67ebf73496383c6777035e374d2d664009e2aa5c'
data = api.gerrit.create_gerrit_branch(host, project, branch, commit)
assert data == 'refs/heads/test'
data = api.gerrit.get_gerrit_branch(host, project, 'master')
assert data == '67ebf73496383c6777035e374d2d664009e2aa5c'
def GenTests(api):
yield (
api.test('basic')
+ api.step_data(
'gerrit create_gerrit_branch',
api.gerrit.make_gerrit_create_branch_response_data()
)
+ api.step_data(
'gerrit get_gerrit_branch',
api.gerrit.make_gerrit_get_branch_response_data()
)
)
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from recipe_engine import recipe_test_api
class GerritTestApi(recipe_test_api.RecipeTestApi):
def _make_gerrit_response_json(self, data):
return self.m.json.output(data)
def make_gerrit_create_branch_response_data(self):
return self._make_gerrit_response_json({
"ref": "refs/heads/test",
"revision": "76016386a0d8ecc7b6be212424978bb45959d668",
"can_delete": True
})
def make_gerrit_get_branch_response_data(self):
return self._make_gerrit_response_json({
"ref": "refs/heads/master",
"revision": "67ebf73496383c6777035e374d2d664009e2aa5c"
})
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment