| Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 1 | #!/usr/bin/env python3 | 
 | 2 | # | 
 | 3 | # SPDX-License-Identifier: Apache-2.0 | 
 | 4 | # Copyright (C) 2018 IBM Corp. | 
 | 5 | # | 
 | 6 | # Push changes to Gerrit, automatically adding reviewers to the patches by | 
 | 7 | # parsing the OpenBMC-style MAINTAINERS file in the root of the repository (if | 
 | 8 | # it exists). | 
 | 9 |  | 
 | 10 | from obmc import maintainers | 
 | 11 | from typing import cast, List, Optional | 
 | 12 | import argparse | 
 | 13 | import os | 
 | 14 | import sh | 
 | 15 | import sys | 
 | 16 |  | 
 | 17 | git = sh.git.bake() | 
 | 18 |  | 
 | 19 | def get_reviewers(root: Optional[str]=None, mname: str='MAINTAINERS') -> List[str]: | 
| Andrew Jeffery | 382f286 | 2018-05-23 17:05:50 +0930 | [diff] [blame] | 20 |     reviewers = cast(List[str], list()) | 
| Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 21 |     if not root: | 
 | 22 |         root = git('rev-parse', '--show-toplevel').strip() | 
 | 23 |     mfile = os.path.join(root, mname) | 
| Andrew Jeffery | 39654b1 | 2018-05-22 12:38:53 +0930 | [diff] [blame] | 24 |     if not os.path.exists(mfile): | 
 | 25 |         return reviewers | 
| Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 26 |     with open(mfile, 'r') as mstream: | 
 | 27 |         maintainers.trash_preamble(mstream) | 
 | 28 |         block = maintainers.parse_block(mstream) | 
 | 29 |         if not block: | 
 | 30 |             return reviewers | 
 | 31 |         mlist = cast(List[maintainers.Identity], | 
 | 32 |                      block[maintainers.LineType.MAINTAINER]) | 
 | 33 |         reviewers.extend(i.email.address for i in mlist) | 
 | 34 |         if maintainers.LineType.REVIEWER in block: | 
 | 35 |             rlist = cast(List[maintainers.Identity], | 
 | 36 |                          block[maintainers.LineType.REVIEWER]) | 
 | 37 |             reviewers.extend(i.email.address for i in rlist) | 
 | 38 |     return reviewers | 
 | 39 |  | 
 | 40 | def gerrit_refspec_args(reviewers: Optional[List[str]]=None) -> str: | 
 | 41 |     args = "" | 
 | 42 |     if reviewers: | 
 | 43 |         args += ",".join("r={}".format(addr) for addr in reviewers) | 
 | 44 |     return args | 
 | 45 |  | 
 | 46 | def decorate_refspec(refspec: str) -> str: | 
 | 47 |     gargs = gerrit_refspec_args(get_reviewers()) | 
| Andrew Jeffery | 39654b1 | 2018-05-22 12:38:53 +0930 | [diff] [blame] | 48 |     if not gargs: | 
 | 49 |         return refspec | 
| Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 50 |     if '%' in refspec: | 
 | 51 |         return "{},{}".format(refspec, gargs) | 
 | 52 |     return "{}%{}".format(refspec, gargs) | 
 | 53 |  | 
 | 54 | def do_push(args: argparse.Namespace) -> None: | 
 | 55 |     git.push(args.remote, decorate_refspec(args.refspec), | 
 | 56 |              _in=sys.stdin, _out=sys.stdout, _err=sys.stderr) | 
 | 57 |  | 
 | 58 | parser = argparse.ArgumentParser() | 
 | 59 | subbies = parser.add_subparsers(dest='subcommand') | 
 | 60 | subbies.required = True | 
 | 61 | push = subbies.add_parser("push", help="Push changes to Gerrit with reviewers") | 
 | 62 | push.add_argument("remote") | 
 | 63 | push.add_argument("refspec") | 
 | 64 | push.set_defaults(func=do_push) | 
 | 65 |  | 
 | 66 | args = parser.parse_args() | 
 | 67 | args.func(args) |