blender/tools/triage/issues_module_listing.py
Campbell Barton d4c7e6f020 Cleanup: suppress type warnings
Also make the script executable & clarify some variable names.
2024-04-03 10:41:03 +11:00

133 lines
3.9 KiB
Python
Executable File

#!/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})")
# Print statistics
print(f"Open {severity} Priority bugs as of {date.today()}:\n")
total = 0
for module in modules.values():
buglist_str = (", ".join(module.buglist))
buglist_len = len(module.buglist)
total += buglist_len
full_url = base_url + severity_labelid[severity] + "%2c" + module.labelid
if not module.buglist or severity != "High":
print(f"- [{module.name}]({full_url}): *{buglist_len}*")
else:
print(f"- [{module.name}]({full_url}): *{buglist_len}* _{buglist_str}_")
print()
print(f"[Total]({total_url}): {total}")
print()
print("Uncategorized:", ", ".join(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()