Patrick Williams | 45c7017 | 2021-03-04 20:25:26 -0600 | [diff] [blame] | 1 | #!/usr/bin/env -S python3 -B |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 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 |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 11 | from typing import cast, Callable, List, Optional, Tuple |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 12 | import argparse |
| 13 | import os |
Patrick Williams | 2deb2e3 | 2021-06-21 15:15:20 -0500 | [diff] [blame] | 14 | import sh # type: ignore |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 15 | import sys |
| 16 | |
Patrick Williams | 2deb2e3 | 2021-06-21 15:15:20 -0500 | [diff] [blame] | 17 | git: Callable[..., str] = sh.git.bake() |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 18 | |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 19 | |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 20 | def get_reviewers( |
| 21 | root: Optional[str] = None, mname: str = "MAINTAINERS" |
| 22 | ) -> Tuple[List[str], List[str]]: |
| 23 | maints: List[str] = list() |
Patrick Williams | 2deb2e3 | 2021-06-21 15:15:20 -0500 | [diff] [blame] | 24 | reviewers: List[str] = list() |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 25 | if not root: |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 26 | root = git("rev-parse", "--show-toplevel").strip() |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 27 | mfile = os.path.join(root, mname) |
Andrew Jeffery | 39654b1 | 2018-05-22 12:38:53 +0930 | [diff] [blame] | 28 | if not os.path.exists(mfile): |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 29 | return (maints, reviewers) |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 30 | with open(mfile, "r") as mstream: |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 31 | maintainers.trash_preamble(mstream) |
| 32 | block = maintainers.parse_block(mstream) |
| 33 | if not block: |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 34 | return (maints, reviewers) |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 35 | mlist = cast( |
| 36 | List[maintainers.Identity], block[maintainers.LineType.MAINTAINER] |
| 37 | ) |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 38 | maints.extend(i.email.address for i in mlist) |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 39 | if maintainers.LineType.REVIEWER in block: |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 40 | rlist = cast( |
| 41 | List[maintainers.Identity], block[maintainers.LineType.REVIEWER] |
| 42 | ) |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 43 | reviewers.extend(i.email.address for i in rlist) |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 44 | return (maints, reviewers) |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 45 | |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 46 | |
| 47 | def gerrit_refspec_args( |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 48 | maintainers: Optional[List[str]] = None, |
| 49 | reviewers: Optional[List[str]] = None, |
| 50 | topic: str = None, |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 51 | ) -> str: |
Patrick Williams | 2deb2e3 | 2021-06-21 15:15:20 -0500 | [diff] [blame] | 52 | argl: List[str] = [] |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 53 | if maintainers: |
| 54 | argl.extend("r={}".format(addr) for addr in maintainers) |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 55 | if reviewers: |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 56 | argl.extend("cc={}".format(addr) for addr in reviewers) |
Andrew Jeffery | 3512b93 | 2020-06-15 13:09:16 +0930 | [diff] [blame] | 57 | if topic: |
Lei YU | 8e56c31 | 2020-07-30 10:14:47 +0000 | [diff] [blame] | 58 | argl.append("topic={}".format(topic)) |
Andrew Jeffery | 3512b93 | 2020-06-15 13:09:16 +0930 | [diff] [blame] | 59 | return ",".join(argl) |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 60 | |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 61 | |
Andrew Jeffery | 3512b93 | 2020-06-15 13:09:16 +0930 | [diff] [blame] | 62 | def decorate_refspec(refspec: str, topic: str) -> str: |
Patrick Williams | 404d301 | 2021-06-21 15:33:11 -0500 | [diff] [blame] | 63 | (maintainers, reviewers) = get_reviewers() |
| 64 | gargs = gerrit_refspec_args(maintainers, reviewers, topic) |
Andrew Jeffery | 39654b1 | 2018-05-22 12:38:53 +0930 | [diff] [blame] | 65 | if not gargs: |
| 66 | return refspec |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 67 | if "%" in refspec: |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 68 | return "{},{}".format(refspec, gargs) |
| 69 | return "{}%{}".format(refspec, gargs) |
| 70 | |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 71 | |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 72 | def do_push(args: argparse.Namespace) -> None: |
Patrick Williams | 2deb2e3 | 2021-06-21 15:15:20 -0500 | [diff] [blame] | 73 | git( |
| 74 | "push", |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 75 | args.remote, |
| 76 | decorate_refspec(args.refspec, args.topic), |
| 77 | _in=sys.stdin, |
| 78 | _out=sys.stdout, |
| 79 | _err=sys.stderr, |
| 80 | ) |
| 81 | |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 82 | |
Patrick Williams | 2d19834 | 2021-06-21 15:35:50 -0500 | [diff] [blame^] | 83 | def do_reviewers(args: argparse.Namespace) -> None: |
| 84 | (maintainers, reviewers) = get_reviewers() |
| 85 | print(gerrit_refspec_args(maintainers, reviewers)) |
| 86 | |
| 87 | |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 88 | parser = argparse.ArgumentParser() |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 89 | subbies = parser.add_subparsers(dest="subcommand") |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 90 | subbies.required = True |
Patrick Williams | 2d19834 | 2021-06-21 15:35:50 -0500 | [diff] [blame^] | 91 | |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 92 | push = subbies.add_parser("push", help="Push changes to Gerrit with reviewers") |
| 93 | push.add_argument("remote") |
| 94 | push.add_argument("refspec") |
Patrick Williams | 9a01439 | 2021-06-21 14:57:29 -0500 | [diff] [blame] | 95 | push.add_argument("topic", nargs="?", default=None) |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 96 | push.set_defaults(func=do_push) |
| 97 | |
Patrick Williams | 2d19834 | 2021-06-21 15:35:50 -0500 | [diff] [blame^] | 98 | reviewers = subbies.add_parser("reviewers", help="Get the reviewer list.") |
| 99 | reviewers.set_defaults(func=do_reviewers) |
| 100 | |
Andrew Jeffery | f4019fe | 2018-05-18 16:42:18 +0930 | [diff] [blame] | 101 | args = parser.parse_args() |
| 102 | args.func(args) |