|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# Copyright (c) 2024 Yaël Dillies, Javier Lopez-Contreras. All rights reserved. |
| 3 | +# Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | + |
| 5 | +""" |
| 6 | +This script parse the aggregate json file and filters all PRs which touch some given files. |
| 7 | +""" |
| 8 | + |
| 9 | +import json |
| 10 | +import os |
| 11 | +import pathlib |
| 12 | +import subprocess |
| 13 | +from typing import Any |
| 14 | + |
| 15 | +# To customize |
| 16 | +MODULE = "Carleson" |
| 17 | +REPOSITORY = "fpvandoorn/carleson" |
| 18 | +BRANCH = "master" |
| 19 | +FOLDER_PATH = "./docs/_includes" |
| 20 | + |
| 21 | +QUEUEBOARD = ( |
| 22 | + "https://raw.githubusercontent.com/leanprover-community/queueboard/refs/" |
| 23 | + "heads/master/processed_data/open_pr_data.json") |
| 24 | +PR_SYMBOL = '<svg class="octicon octicon-git-pull-request open color-fg-open mr-1" title="Open" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path></svg>' |
| 25 | + |
| 26 | +def main(): |
| 27 | + pr_file = subprocess.run(["curl", QUEUEBOARD], capture_output=True, text=True) |
| 28 | + pr_json = json.loads(pr_file.stdout)["pr_statusses"] |
| 29 | + pr_dict = {pr["number"]: pr for pr in pr_json} |
| 30 | + |
| 31 | + file_touched_pr: dict[str, list[Any]] = {} |
| 32 | + for pr in pr_dict: |
| 33 | + for file in pr_dict[pr]["files"]: |
| 34 | + pr_data = { |
| 35 | + "number" : pr, |
| 36 | + "title" : pr_dict[pr]["title"], |
| 37 | + "num_files": len(pr_dict[pr]["files"]), |
| 38 | + "is_draft": pr_dict[pr]["is_draft"] |
| 39 | + } |
| 40 | + if file not in file_touched_pr: file_touched_pr[file] = [pr_data] |
| 41 | + else: file_touched_pr[file].append(pr_data) |
| 42 | + |
| 43 | + project_files: dict[str, Any] = {} |
| 44 | + for entry in pathlib.Path(MODULE).rglob("*.lean"): |
| 45 | + code = None |
| 46 | + with open(entry, 'r') as reader: |
| 47 | + code = reader.read() |
| 48 | + entry = str(entry) |
| 49 | + file = "/".join(entry.split("/")[1:]) |
| 50 | + project_files[entry] = { |
| 51 | + "prs" : [] if file not in file_touched_pr else file_touched_pr[file], |
| 52 | + "num_sorries" : code.count("sorry"), |
| 53 | + "depends" : f"import {MODULE}" in code |
| 54 | + } |
| 55 | + |
| 56 | + if not os.path.exists(FOLDER_PATH): |
| 57 | + os.makedirs(FOLDER_PATH) |
| 58 | + |
| 59 | + with open(f"{FOLDER_PATH}/ready_to_upstream.md", 'w+') as writer: |
| 60 | + for file_path in project_files: |
| 61 | + if project_files[file_path]["num_sorries"] > 0: |
| 62 | + continue |
| 63 | + if project_files[file_path]["depends"]: |
| 64 | + continue |
| 65 | + module_name = file_path.replace('/','.')[:-5] |
| 66 | + writer.write(f"* [`{module_name}`](https://github.com/{REPOSITORY}/blob/{BRANCH}/{file_path})\n") |
| 67 | + for pr in project_files[file_path]["prs"]: |
| 68 | + if pr["title"][:4] == "perf": |
| 69 | + continue |
| 70 | + if pr["is_draft"]: |
| 71 | + continue |
| 72 | + |
| 73 | + writer.write(f" * [{PR_SYMBOL} {pr['title']} #{pr['number']}]") |
| 74 | + writer.write(f"(https://github.com/leanprover-community/mathlib4/pull/{pr['number']})\n") |
| 75 | + |
| 76 | + with open(f"{FOLDER_PATH}/easy_to_unlock.md", 'w+') as writer: |
| 77 | + for file_path in project_files: |
| 78 | + if project_files[file_path]["num_sorries"] == 0: |
| 79 | + continue |
| 80 | + if project_files[file_path]["depends"]: |
| 81 | + continue |
| 82 | + num_sorries = project_files[file_path]["num_sorries"] |
| 83 | + module_name = file_path.replace('/','.')[:-5] |
| 84 | + if num_sorries == 1: |
| 85 | + sorries = f"{num_sorries} sorry" |
| 86 | + else: |
| 87 | + sorries = f"{num_sorries} sorries" |
| 88 | + writer.write(f"* [`{module_name}`](https://github.com/{REPOSITORY}/blob/{BRANCH}/{file_path}) {sorries}\n") |
| 89 | + |
| 90 | +main() |
0 commit comments