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) |