Create recipe_modules/gerrit to interact with gerrit REST API
BUG= R=mmoss,agable Change-Id: I6410c28280ed05cf384a3da93e6b154c6081e039 Reviewed-on: https://chromium-review.googlesource.com/427375 Reviewed-by: Michael Moss <mmoss@chromium.org>changes/75/427375/6
parent
54985b6b96
commit
833c94c6fb
@ -0,0 +1,105 @@
|
||||
#!/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)
|
@ -0,0 +1,6 @@
|
||||
DEPS = [
|
||||
'recipe_engine/json',
|
||||
'recipe_engine/path',
|
||||
'recipe_engine/python',
|
||||
'recipe_engine/raw_io',
|
||||
]
|
@ -0,0 +1,63 @@
|
||||
# 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
|
@ -0,0 +1,64 @@
|
||||
[
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
@ -0,0 +1,35 @@
|
||||
# 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()
|
||||
)
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
# 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"
|
||||
})
|
Loading…
Reference in New Issue