From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=N0WM7CFx; spf=pass (domain: linaro.org, ip: 209.85.128.65, mailfrom: leif.lindholm@linaro.org) Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by groups.io with SMTP; Wed, 12 Jun 2019 04:19:55 -0700 Received: by mail-wm1-f65.google.com with SMTP id a15so6133716wmj.5 for ; Wed, 12 Jun 2019 04:19:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=CmXKj9+pMUrLMUgWS0nalITpEJPQJAl/STPnkCkpSKA=; b=N0WM7CFx6DFn95uI59HBa+3YlMyRqNJR/GoLhvIb0jJBa+UW7rkQptOtDT4C3YDQqQ Lx6fQNwM7rpXxwXUYQfi77nMrA9oSuuYab2KfWgHEkWpJUlr8yvKIbQQfEDS7TCvlSwH LDEOp+/NGpAAM8rfRttMBraI9rspPrSFVmvIZXYKuyK4K4VoWwi8BuCsQP5Y/oD8Pret Jmn2ajkoQqytSh2sMTx9KbIksoB/AhuhFsY25ZS6jmOXKgnaOncsTev8PosulV0hIZXH kkMNzmRrzn+X8PJI9I4E728iN0EltNnHRaI9XMCI5FjJtQJ/4gQ8/mk5udND7sdtZupV bZ/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=CmXKj9+pMUrLMUgWS0nalITpEJPQJAl/STPnkCkpSKA=; b=gZPmwfRTzqvzfo2kKbVzCB2a3qENxRtaSkTGZaIXr26cnZu/+4L/P4dM6sLqP+v+3l sIzXDg3nVAQcBSLMBKsrXKchvC00dEiByWw7aWlPLjjmTosPd1tLKWP7OohwqhukmphL 9cN+t8I4k6tUqIqgwiRewR7ODBxQ3vTDMLs3rrDcgNOUtfzQp1b+yOBdZpyjTXu2AaYb AZEZmETLCdsjcgzPs0n+ZXi0e/r4EK7FKTaiKpNwtEX4pTb/rPnVT/S1ii4DCV2guOJW edaYMIEBY5VZnY8fwfmYn0Vfdi4xiKxOtnaxdn6VurW3ksxFw3jYBc8zppQasefktu+8 apFw== X-Gm-Message-State: APjAAAVlWPQgxOAtVop17CAOx1Gr6EblEl90PdTC3HDiCMrWs+PKajvP vaX8oTAq8xa/2DAVHSNeUxK0aBYCZxPCtw== X-Google-Smtp-Source: APXvYqzyK3Q5shZWkwMhLoYiQmfVMbXWahDdXjQfQfG9FSjBBheHq2Xcy5K6uMXvRyLjvykI9Kncyw== X-Received: by 2002:a1c:3b02:: with SMTP id i2mr20331734wma.23.1560338393421; Wed, 12 Jun 2019 04:19:53 -0700 (PDT) Return-Path: Received: from vanye.hemma.eciton.net (cpc92302-cmbg19-2-0-cust304.5-4.cable.virginm.net. [82.1.209.49]) by smtp.gmail.com with ESMTPSA id o14sm15348133wrp.77.2019.06.12.04.19.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 12 Jun 2019 04:19:52 -0700 (PDT) From: "Leif Lindholm" To: devel@edk2.groups.io Cc: "Feng, Bob C" , Liming Gao , Andrew Fish , Laszlo Ersek , Michael D Kinney Subject: [BIKESHEDDING-TARGET] BaseTools: add GetMaintainer.py helper script Date: Wed, 12 Jun 2019 12:19:51 +0100 Message-Id: <20190612111951.2429-1-leif.lindholm@linaro.org> X-Mailer: git-send-email 2.11.0 This is work-in-progress, but I figured it would be a good time to start having a conversation about how we want it to work. The script currently does nothing clever whatsoever with regards to looking at historical contributors to the modified code - it only performs a lookup in Maintainers.txt. Known shortcomings: - Does not provide any metainformation about why certain people or mailing lists were picked. - Does not reason about precedence of sections - all maintainers for all sections that match a wildcard are returned. - Does not substantially update Maintainers.txt. - Does not implement the X: tag, to explicitly exclude subpaths. (But scans for it.) - The splitting of Maintainers.txt into sections is based on directly adjacent lines starting with a valid tag (so I expect Star is left out from MdeModulePkg hits, and OvmfPkg loses most of its Reviewers. (My feeling is this is valid, and Maintainers.txt should change - certainly all the problematic lines would become redundant with this format change.) Supported wildcards are '*' and '?' - there is no special treatment of trailing '/' at this point. Oh, and like 'SetupGit.py', it requires the gitpython module. Laszlo: if you could provide some english language description of how the path (F:) format is supposed to work, and how you think section precedence should happen, I can implement that. The qemu MAINTAINERS file does not contain this information, and my perl knowledge is rustier than my python knowledge is incomplete. Signed-off-by: Leif Lindholm --- BaseTools/Scripts/GetMaintainer.py | 131 +++++++++++++++++++++++++++++++++++++ Maintainers.txt | 38 +++++++++++ 2 files changed, 169 insertions(+) create mode 100644 BaseTools/Scripts/GetMaintainer.py diff --git a/BaseTools/Scripts/GetMaintainer.py b/BaseTools/Scripts/GetMaintainer.py new file mode 100644 index 0000000000..939930b052 --- /dev/null +++ b/BaseTools/Scripts/GetMaintainer.py @@ -0,0 +1,131 @@ +## @file +# Retrieves the people to request review from on submission of a commit. +# +# Copyright (c) 2019, Linaro Ltd. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +from __future__ import print_function +from collections import defaultdict +from collections import OrderedDict +import argparse +import os +import re +import SetupGit + +EXPRESSIONS = { + 'exclude': re.compile(r'^X:\s*(?P.*?)\r*$'), + 'file': re.compile(r'^F:\s*(?P.*?)\r*$'), + 'list': re.compile(r'^L:\s*(?P.*?)\r*$'), + 'maintainer': re.compile(r'^M:\s*(?P.*<.*?>)\r*$'), + 'reviewer': re.compile(r'^R:\s*(?P.*?)\r*$'), + 'status': re.compile(r'^S:\s*(?P.*?)\r*$'), + 'tree': re.compile(r'^T:\s*(?P.*?)\r*$'), + 'webpage': re.compile(r'^W:\s*(?P.*?)\r*$') +} + +def printsection(section): + """Prints out the dictionary describing a Maintainers.txt section.""" + print('===') + for key in section.keys(): + print("Key: %s" % key) + for item in section[key]: + print(' %s' % item) + +def pattern_to_regex(pattern): + """Takes a string containing regular UNIX path wildcards + and returns a string suitable for matching with regex.""" + pattern = pattern.replace('.', r'\.') + pattern = pattern.replace('*', r'.*') + pattern = pattern.replace('?', r'.') + + return pattern + +def get_section_maintainers(path, section): + """Returns a list with email addresses to any M: and R: entries + matching the provided path in the provided section.""" + maintainers = [] + + for pattern in section['file']: + regex = pattern_to_regex(pattern) + match = re.match(regex, path) + if match: +# print('path: "%s" pattern: "%s" regex: "%s"' % (path, pattern, regex)) + for address in section['maintainer'], section['reviewer']: + maintainers += address + + return maintainers + +def get_maintainers(path, sections): + """For 'path', iterates over all sections, returning maintainers + for matching ones.""" + maintainers = [] + for section in sections: + addresses = get_section_maintainers(path, section) + if addresses: + maintainers += addresses + + # Remove any duplicates + return list(OrderedDict.fromkeys(maintainers)) + +def parse_maintainers_line(line): + """Parse one line of Maintainers.txt, returning any match group and its key.""" + for key, expression in EXPRESSIONS.items(): + match = expression.match(line) + if match: + return key, match.group(key) + return None, None + +def parse_maintainers_file(filename): + """Parse the Maintainers.txt from top-level of repo and + return a list containing dictionaries of all sections.""" + with open(filename, 'r') as text: + line = text.readline() + sectionlist = [] + section = defaultdict(list) + while line: + key, value = parse_maintainers_line(line) + if key and value: + section[key].append(value) + + line = text.readline() + # If end of section (end of file, or non-tag line encountered)... + if not key or not value or not line: + # ...if non-empty, append area to list. + if section: + sectionlist.append(section.copy()) + section.clear() + + return sectionlist + +def get_modified_files(repo, args): + """Returns a list of the files modified by the commit specified in 'args'.""" + commit = repo.commit(args.commit) + return commit.stats.files + +if __name__ == '__main__': + PARSER = argparse.ArgumentParser( + description='Retrieves information on who to cc for review on a given commit') + PARSER.add_argument('commit', + action="store", + help='git revision to examine (default: HEAD)', + nargs='?', + default='HEAD') + ARGS = PARSER.parse_args() + + REPO = SetupGit.locate_repo() + + FILES = get_modified_files(REPO, ARGS) + CONFIG_FILE = os.path.join(REPO.working_dir, 'Maintainers.txt') + + SECTIONS = parse_maintainers_file(CONFIG_FILE) + + ADDRESSES = [] + + for file in FILES: + print(file) + ADDRESSES += get_maintainers(file, SECTIONS) + + for address in list(OrderedDict.fromkeys(ADDRESSES)): + print(' %s' % address) diff --git a/Maintainers.txt b/Maintainers.txt index 762a684659..f4c851536e 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -47,6 +47,7 @@ T: svn (read-only, deprecated) - https://svn.code.sf.net/p/edk2/code/trunk/edk2 Tianocore Stewards ------------------ +F: * M: Andrew Fish M: Laszlo Ersek M: Leif Lindholm @@ -61,19 +62,30 @@ EDK II Releases: W: https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Release-Planning M: Liming Gao +EDK II Architectures: +--------------------- +ARM, AARCH64 +F: */AARCH64/* +F: */ARM/* +M: Leif Lindholm +M: Ard Biesheuvel + EDK II Packages: ---------------- ArmPkg +F: ArmPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/ArmPkg M: Leif Lindholm M: Ard Biesheuvel ArmPlatformPkg +F: ArmPlatformPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/ArmPlatformPkg M: Leif Lindholm M: Ard Biesheuvel ArmVirtPkg +F: ArmVirtPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/ArmVirtPkg M: Laszlo Ersek M: Ard Biesheuvel @@ -81,26 +93,31 @@ R: Julien Grall (Xen modules) BaseTools +F: BaseTools/* W: https://github.com/tianocore/tianocore.github.io/wiki/BaseTools M: Bob Feng M: Liming Gao CryptoPkg +F: CryptoPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/CryptoPkg M: Jian Wang R: Ting Ye DynamicTablesPkg +F: DynamicTablesPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/DynamicTablesPkg M: Sami Mujawar M: Alexei Fedorov EmbeddedPkg +F: EmbeddedPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/EmbeddedPkg M: Leif Lindholm M: Ard Biesheuvel EmulatorPkg +F: EmulatorPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/EmulatorPkg M: Jordan Justen M: Andrew Fish @@ -108,55 +125,65 @@ M: Ray Ni S: Maintained FatPkg +F: FatPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/Edk2-fat-driver M: Ray Ni T: svn - https://svn.code.sf.net/p/edk2-fatdriver2/code/trunk/EnhancedFat T: git - https://github.com/tianocore/edk2-FatPkg.git FmpDevicePkg +F: FmpDevicePkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/FmpDevicePkg M: Liming Gao M: Michael D Kinney IntelFrameworkModulePkg +F: IntelFrameworkModulePkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelFrameworkModulePkg M: Liming Gao IntelFrameworkPkg +F: IntelFrameworkPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelFrameworkPkg M: Michael D Kinney M: Liming Gao IntelFsp2Pkg +F: IntelFsp2Pkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelFsp2Pkg M: Chasel Chiu R: Nate DeSimone R: Star Zeng IntelFsp2WrapperPkg +F: IntelFsp2WrapperPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelFsp2WrapperPkg M: Chasel Chiu R: Nate DeSimone R: Star Zeng IntelFspPkg +F: IntelFspPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelFspPkg M: Chasel Chiu R: Nate DeSimone R: Star Zeng IntelFspWrapperPkg +F: IntelFspWrapperPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelFspWrapperPkg M: Chasel Chiu R: Nate DeSimone R: Star Zeng IntelSiliconPkg +F: IntelSiliconPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/IntelSiliconPkg M: Ray Ni M: Rangasai V Chaganty MdeModulePkg +F: MdeModulePkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/MdeModulePkg M: Jian J Wang M: Hao A Wu @@ -166,16 +193,19 @@ R: Ray Ni R: Star Zeng MdePkg +F: MdePkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/MdePkg M: Michael D Kinney M: Liming Gao NetworkPkg +F: NetworkPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/NetworkPkg M: Siyuan Fu M: Jiaxin Wu OvmfPkg +F: OvmfPkg/* W: http://www.tianocore.org/ovmf/ M: Jordan Justen M: Laszlo Ersek @@ -191,16 +221,19 @@ R: Stefan Berger S: Maintained PcAtChipsetPkg +F: PcAtChipsetPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg M: Ray Ni SecurityPkg +F: SecurityPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/SecurityPkg M: Chao Zhang M: Jiewen Yao M: Jian Wang ShellPkg +F: ShellPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/ShellPkg M: Jaben Carsey M: Ray Ni @@ -214,21 +247,25 @@ M: Leif Lindholm (ARM/AArch64) M: Ard Biesheuvel (ARM/AArch64) SignedCapsulePkg +F: SignedCapsulePkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/SignedCapsulePkg M: Jiewen Yao M: Chao Zhang SourceLevelDebugPkg +F: SourceLevelDebugPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/SourceLevelDebugPkg M: Hao A Wu UefiCpuPkg +F: UefiCpuPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/UefiCpuPkg M: Eric Dong M: Ray Ni R: Laszlo Ersek UefiPayloadPkg +F: UefiPayloadPkg/* W: https://github.com/tianocore/tianocore.github.io/wiki/UefiPayloadPkg M: Maurice Ma M: Guo Dong @@ -236,6 +273,7 @@ M: Benjamin You S: Maintained StandaloneMmPkg +F: StandaloneMmPkg/* M: Achin Gupta M: Jiewen Yao R: Supreeth Venkatesh -- 2.11.0