blob: b5bbbb9f82e914f417913a62cbcd494eabb3a0a8 [file] [log] [blame]
Patrick Williams45c70172021-03-04 20:25:26 -06001#!/usr/bin/env -S python3 -B
Andrew Jefferyf4019fe2018-05-18 16:42:18 +09302#
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
10from obmc import maintainers
11from typing import cast, List, Optional
12import argparse
13import os
14import sh
15import sys
16
17git = sh.git.bake()
18
Patrick Williams9a014392021-06-21 14:57:29 -050019
20def get_reviewers(root: Optional[str] = None, mname: str = "MAINTAINERS") -> List[str]:
Andrew Jeffery382f2862018-05-23 17:05:50 +093021 reviewers = cast(List[str], list())
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093022 if not root:
Patrick Williams9a014392021-06-21 14:57:29 -050023 root = git("rev-parse", "--show-toplevel").strip()
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093024 mfile = os.path.join(root, mname)
Andrew Jeffery39654b12018-05-22 12:38:53 +093025 if not os.path.exists(mfile):
26 return reviewers
Patrick Williams9a014392021-06-21 14:57:29 -050027 with open(mfile, "r") as mstream:
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093028 maintainers.trash_preamble(mstream)
29 block = maintainers.parse_block(mstream)
30 if not block:
31 return reviewers
Patrick Williams9a014392021-06-21 14:57:29 -050032 mlist = cast(
33 List[maintainers.Identity], block[maintainers.LineType.MAINTAINER]
34 )
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093035 reviewers.extend(i.email.address for i in mlist)
36 if maintainers.LineType.REVIEWER in block:
Patrick Williams9a014392021-06-21 14:57:29 -050037 rlist = cast(
38 List[maintainers.Identity], block[maintainers.LineType.REVIEWER]
39 )
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093040 reviewers.extend(i.email.address for i in rlist)
41 return reviewers
42
Patrick Williams9a014392021-06-21 14:57:29 -050043
44def gerrit_refspec_args(
45 reviewers: Optional[List[str]] = None, topic: str = None
46) -> str:
Andrew Jeffery3512b932020-06-15 13:09:16 +093047 argl = []
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093048 if reviewers:
Andrew Jeffery3512b932020-06-15 13:09:16 +093049 argl.extend("r={}".format(addr) for addr in reviewers)
50 if topic:
Lei YU8e56c312020-07-30 10:14:47 +000051 argl.append("topic={}".format(topic))
Andrew Jeffery3512b932020-06-15 13:09:16 +093052 return ",".join(argl)
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093053
Patrick Williams9a014392021-06-21 14:57:29 -050054
Andrew Jeffery3512b932020-06-15 13:09:16 +093055def decorate_refspec(refspec: str, topic: str) -> str:
56 gargs = gerrit_refspec_args(get_reviewers(), topic)
Andrew Jeffery39654b12018-05-22 12:38:53 +093057 if not gargs:
58 return refspec
Patrick Williams9a014392021-06-21 14:57:29 -050059 if "%" in refspec:
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093060 return "{},{}".format(refspec, gargs)
61 return "{}%{}".format(refspec, gargs)
62
Patrick Williams9a014392021-06-21 14:57:29 -050063
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093064def do_push(args: argparse.Namespace) -> None:
Patrick Williams9a014392021-06-21 14:57:29 -050065 git.push(
66 args.remote,
67 decorate_refspec(args.refspec, args.topic),
68 _in=sys.stdin,
69 _out=sys.stdout,
70 _err=sys.stderr,
71 )
72
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093073
74parser = argparse.ArgumentParser()
Patrick Williams9a014392021-06-21 14:57:29 -050075subbies = parser.add_subparsers(dest="subcommand")
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093076subbies.required = True
77push = subbies.add_parser("push", help="Push changes to Gerrit with reviewers")
78push.add_argument("remote")
79push.add_argument("refspec")
Patrick Williams9a014392021-06-21 14:57:29 -050080push.add_argument("topic", nargs="?", default=None)
Andrew Jefferyf4019fe2018-05-18 16:42:18 +093081push.set_defaults(func=do_push)
82
83args = parser.parse_args()
84args.func(args)