#!/usr/bin/env python2 # SPDX-License-Identifier: Apache-2.0 ############################################################################## # Copyright (c) 2018 The Linux Foundation and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## """ Create Gerrit Branchs """ import argparse try: import ConfigParser except ImportError: import configparser as ConfigParser import logging import os import yaml from requests.compat import quote from requests.exceptions import RequestException from pygerrit2.rest import GerritRestAPI from pygerrit2.rest.auth import HTTPDigestAuthFromNetrc, HTTPBasicAuthFromNetrc logging.basicConfig(level=logging.INFO) def quote_branch(arguments): """ Quote is used here to escape the '/' in branch name. By default '/' is listed in 'safe' characters which aren't escaped. quote is not used in the data of the PUT request, as quoting for arguments is handled by the request library """ new_args = arguments.copy() new_args['branch'] = quote(new_args['branch'], '') return new_args def create_branch(api, arguments): """ Create a branch using the Gerrit REST API """ logger = logging.getLogger(__file__) branch_data = """ { "ref": "%(branch)s" "revision": "%(commit)s" }""" % arguments # First verify the commit exists, otherwise the branch will be # created at HEAD try: request = api.get("/projects/%(project)s/commits/%(commit)s" % arguments) logger.debug(request) logger.debug("Commit exists: %(commit)s", arguments) except RequestException as err: if hasattr(err, 'response') and err.response.status_code in [404]: logger.warn("Commit %(commit)s for %(project)s does" " not exist. Not creating branch.", arguments) logger.warn(err) else: logger.error("Error: %s", str(err)) # Skip trying to create the branch return # Try to create the branch and let us know if it already exist. try: request = api.put("/projects/%(project)s/branches/%(branch)s" % quote_branch(arguments), branch_data) logger.info("Branch %(branch)s for %(project)s successfully created", arguments) except RequestException as err: if hasattr(err, 'response') and err.response.status_code in [412, 409]: logger.info("Branch %(branch)s already created for %(project)s", arguments) logger.info(err) else: logger.error("Error: %s", str(err)) def main(): """Given a yamlfile that follows the release syntax, create branches in Gerrit listed under branches""" config = ConfigParser.ConfigParser() config.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'defaults.cfg')) config.read([os.path.expanduser('~/releases.cfg'), 'releases.cfg']) gerrit_url = config.get('gerrit', 'url') parser = argparse.ArgumentParser() parser.add_argument('--file', '-f', type=argparse.FileType('r'), required=True) parser.add_argument('--basicauth', '-b', action='store_true') args = parser.parse_args() GerritAuth = HTTPDigestAuthFromNetrc if args.basicauth: GerritAuth = HTTPBasicAuthFromNetrc try: auth = GerritAuth(url=gerrit_url) except ValueError as err: logging.error("%s for %s", err, gerrit_url) quit(1) restapi = GerritRestAPI(url=gerrit_url, auth=auth) project = yaml.safe_load(args.file) create_branches(restapi, project) def create_branches(restapi, project): """Create branches for a specific project defined in the release file""" branches = [] for branch in project['branches']: repo, ref = next(iter(branch['location'].items())) branches.append({ 'project': repo, 'branch': branch['name'], 'commit': ref }) for branch in branches: create_branch(restapi, branch) if __name__ == "__main__": main()