From 04293e2494c9cbbfa4975ca88272dadb3c87d61a Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 2 Apr 2024 15:54:14 +0200 Subject: [PATCH] Tools: Add script to report (high) priority issues per module The python script checks on reports based on the provided severity (default High) and sorts them per module. Thanks to Sybren for suggestions on how to improve it! Pull Request: https://projects.blender.org/blender/blender/pulls/120022 --- tools/triage/issues_module_listing.py | 126 ++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tools/triage/issues_module_listing.py diff --git a/tools/triage/issues_module_listing.py b/tools/triage/issues_module_listing.py new file mode 100644 index 00000000000..7c2845c5acd --- /dev/null +++ b/tools/triage/issues_module_listing.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2024 Blender Authors +# +# SPDX-License-Identifier: GPL-2.0-or-later + +""" +# This script prints the numbers of open issues per module. + +Example usage: + + python ./issues_module_listing.py --severity High +""" + +import argparse +import dataclasses +from datetime import date +from gitea_utils import gitea_json_issues_search + +@dataclasses.dataclass +class ModuleInfo: + name: str + labelid: str + buglist: list[str] = dataclasses.field(default_factory=list) + +# Label names and IDs are taken from https://projects.blender.org/blender/blender/labels. +modules = { + "Module/Animation & Rigging" : ModuleInfo(name="Animation & Rigging", labelid="268"), + "Module/Core" : ModuleInfo(name="Core", labelid="269"), + "Module/EEVEE & Viewport" : ModuleInfo(name="EEVEE & Viewport", labelid="272"), + "Module/Grease Pencil" : ModuleInfo(name="Grease Pencil", labelid="273"), + "Module/Modeling" : ModuleInfo(name="Modeling", labelid="274"), + "Module/Nodes & Physics" : ModuleInfo(name="Nodes & Physics", labelid="275"), + "Module/Pipeline, Assets & IO" : ModuleInfo(name="Pipeline, Assets & I/O", labelid="276"), + "Module/Platforms, Builds, Test & Devices" : ModuleInfo(name="Platforms, Builds, Test & Devices", labelid="278"), + "Module/Python API" : ModuleInfo(name="Python API", labelid="279"), + "Module/Render & Cycles" : ModuleInfo(name="Render & Cycles", labelid="280"), + "Module/Sculpt, Paint & Texture" : ModuleInfo(name="Sculpt, Paint & Texture", labelid="281"), + "Module/User Interface" : ModuleInfo(name="User Interface", labelid="283"), + "Module/VFX & Video" : ModuleInfo(name="VFX & Video", labelid="284"), +} + +base_url = "https://projects.blender.org/blender/blender/issues?q=&type=all&sort=&state=open&labels=" +total_url = "https://projects.blender.org/blender/blender/issues?q=&type=all&sort=&state=open&labels=285%2c-297%2c-298%2c-299%2c-301" + +severity_labelid = { + "Low": "286", + "Normal": "287", + "High": "285", + "Unbreak Now!": "288" +} + + +def compile_list(severity: str) -> None: + + label = f"Priority/{severity}" + issues_json = gitea_json_issues_search( + type="issues", + state="open", + labels=label, + verbose=True, + ) + + uncategorized_reports = [] + + for issue in issues_json: + html_url = issue["html_url"] + number = issue["number"] + + # Check reports module assignment and fill in data. + for label_iter in issue["labels"]: + label = label_iter["name"] + if label not in modules: + continue + + modules[label].buglist.append(f"[#{number}]({html_url})") + break + else: + uncategorized_reports.append(f"[#{number}]({html_url})") + + uncategorized_reports = (', '.join(uncategorized_reports)) + + # Print statistics + print(f"Open {severity} Priority bugs as of {date.today()}:\n") + + total = 0 + for module in modules.values(): + total += len(module.buglist) + str_list = (', '.join(module.buglist)) + full_url = base_url + severity_labelid[severity] + "%2c" + module.labelid + buglist_len = len(module.buglist) + if not module.buglist or severity != 'High': + print(f"- [{module.name}]({full_url}): *{buglist_len}*") + else: + print(f"- [{module.name}]({full_url}): *{buglist_len}* _{str_list}_") + + print() + print(f"[Total]({total_url}): {total}") + + print() + print(f"Uncategorized: {uncategorized_reports}") + + +def main() -> None: + + parser = argparse.ArgumentParser( + description="Print statistics on open bug reports per module", + epilog="This script is used to help module teams", + ) + + parser.add_argument( + "--severity", + dest="severity", + default="High", + type=str, + required=False, + choices=severity_labelid.keys(), + help="Severity level of reports", + ) + + args = parser.parse_args() + + compile_list(args.severity) + + +if __name__ == "__main__": + main()