Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 1 | #!/usr/bin/python3 |
| 2 | |
| 3 | import argparse |
| 4 | import json |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 5 | import os |
| 6 | import re |
| 7 | from collections import defaultdict |
nitroglycerine | 56acf68 | 2022-12-15 03:55:38 -0800 | [diff] [blame] | 8 | from typing import Dict |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 9 | |
Patrick Williams | a3db66b | 2022-12-04 16:27:08 -0600 | [diff] [blame] | 10 | import libvoters.acceptable as acceptable |
Andrew Jeffery | ed5643f | 2023-05-22 12:38:59 +0930 | [diff] [blame^] | 11 | from libvoters import UserChanges, changes_factory |
Patrick Williams | a3db66b | 2022-12-04 16:27:08 -0600 | [diff] [blame] | 12 | from libvoters.time import TimeOfDay, timestamp |
| 13 | |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 14 | |
| 15 | class subcmd: |
| 16 | def __init__(self, parser: argparse._SubParsersAction) -> None: |
| 17 | p = parser.add_parser( |
| 18 | "analyze-commits", help="Determine points for commits" |
| 19 | ) |
| 20 | |
| 21 | p.add_argument( |
| 22 | "--before", |
| 23 | "-b", |
| 24 | help="Before timestamp (YYYY-MM-DD)", |
| 25 | required=True, |
| 26 | ) |
| 27 | p.add_argument( |
| 28 | "--after", |
| 29 | "-a", |
| 30 | help="After timestamp (YYYY-MM-DD)", |
| 31 | required=True, |
| 32 | ) |
| 33 | |
| 34 | p.set_defaults(cmd=self) |
| 35 | |
| 36 | def run(self, args: argparse.Namespace) -> int: |
| 37 | before = timestamp(args.before, TimeOfDay.AM) |
| 38 | after = timestamp(args.after, TimeOfDay.PM) |
| 39 | |
Andrew Jeffery | ed5643f | 2023-05-22 12:38:59 +0930 | [diff] [blame^] | 40 | changes_per_user: Dict[str, UserChanges] = defaultdict(changes_factory) |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 41 | |
| 42 | for f in sorted(os.listdir(args.dir)): |
| 43 | path = os.path.join(args.dir, f) |
| 44 | if not os.path.isfile(path): |
| 45 | continue |
| 46 | |
Patrick Williams | a3db66b | 2022-12-04 16:27:08 -0600 | [diff] [blame] | 47 | if not re.match(r"[0-9]*\.json", f): |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 48 | continue |
| 49 | |
| 50 | with open(path, "r") as file: |
| 51 | data = json.load(file) |
| 52 | |
| 53 | if data["status"] != "MERGED": |
| 54 | continue |
| 55 | |
| 56 | merged_at = 0 |
| 57 | for c in data["comments"]: |
| 58 | if "timestamp" not in c: |
| 59 | continue |
| 60 | if "message" in c and re.match( |
| 61 | "Change has been successfully .*", c["message"] |
| 62 | ): |
| 63 | merged_at = c["timestamp"] |
| 64 | |
| 65 | if merged_at == 0: |
| 66 | raise RuntimeError(f"Missing merge timestamp on {f}") |
| 67 | |
| 68 | if merged_at > before or merged_at < after: |
| 69 | continue |
| 70 | |
| 71 | project = data["project"] |
| 72 | id_number = data["number"] |
Andrew Jeffery | ed5643f | 2023-05-22 12:38:59 +0930 | [diff] [blame^] | 73 | username = data["owner"]["username"] |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 74 | |
| 75 | if not acceptable.project(project): |
| 76 | print("Rejected project:", project, id_number) |
| 77 | continue |
| 78 | |
| 79 | changes = 0 |
| 80 | touched_files = [] |
| 81 | for file_data in sorted( |
| 82 | data["patchSets"], key=lambda x: x["number"] |
| 83 | )[-1][ |
| 84 | "files" |
| 85 | ]: # type: Dict[str, Any] |
| 86 | if not acceptable.file(project, file_data["file"]): |
| 87 | continue |
| 88 | changes += int(file_data["insertions"]) + abs( |
| 89 | int(file_data["deletions"]) |
| 90 | ) |
| 91 | touched_files.append(file_data["file"]) |
| 92 | |
| 93 | if changes < 10: |
| 94 | print("Rejected for limited changes:", project, id_number) |
| 95 | continue |
| 96 | |
Andrew Jeffery | ed5643f | 2023-05-22 12:38:59 +0930 | [diff] [blame^] | 97 | print(project, id_number, username) |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 98 | for f in touched_files: |
| 99 | print(f" {f}") |
| 100 | |
Andrew Jeffery | ed5643f | 2023-05-22 12:38:59 +0930 | [diff] [blame^] | 101 | user = changes_per_user[username] |
| 102 | user["name"] = data["owner"]["name"] |
| 103 | user["email"] = data["owner"]["email"] |
| 104 | user["changes"].append(id_number) |
Patrick Williams | 215c1c3 | 2022-01-06 20:26:26 -0600 | [diff] [blame] | 105 | |
| 106 | with open(os.path.join(args.dir, "commits.json"), "w") as outfile: |
| 107 | outfile.write(json.dumps(changes_per_user, indent=4)) |
| 108 | |
| 109 | return 0 |