From 04d273bcc7265720f25a5cf3874ba04752d84bea Mon Sep 17 00:00:00 2001 From: konstin Date: Tue, 23 May 2023 12:41:56 +0200 Subject: [PATCH] Add a script to update the schemastore (#4574) * Add a script to update the schemastore Hacked this together, it clones astral-sh/schemastore, updated the schema and pushes the changes to a new branch tagged with the ruff git hash. You can see the URL to create the PR to schemastore in the CLI. The script is separated into three blocks so you can rerun the schema generation in the middle before committing. * Use tempdir for schemastore * Add comments --- .gitignore | 3 +- scripts/update_schemastore.py | 97 +++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 scripts/update_schemastore.py diff --git a/.gitignore b/.gitignore index b394c6a518..de3c456e67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ -# Local cache -.ruff_cache crates/ruff/resources/test/cpython mkdocs.yml .overrides ruff-old github_search*.jsonl +schemastore .venv* ### diff --git a/scripts/update_schemastore.py b/scripts/update_schemastore.py new file mode 100644 index 0000000000..ace0f715c6 --- /dev/null +++ b/scripts/update_schemastore.py @@ -0,0 +1,97 @@ +"""Update ruff.json in schemastore. + +This script will clone astral-sh/schemastore, update the schema and push the changes +to a new branch tagged with the ruff git hash. You should see a URL to create the PR +to schemastore in the CLI. +""" + +import json +from pathlib import Path +from subprocess import check_call, check_output +from tempfile import TemporaryDirectory + +schemastore_fork = "https://github.com/astral-sh/schemastore" +schemastore_upstream = "https://github.com/SchemaStore/schemastore" +ruff_repo = "https://github.com/charliermarsh/ruff" +root = Path( + check_output(["git", "rev-parse", "--show-toplevel"], text=True).strip(), +) +ruff_json = Path("src/schemas/json/ruff.json") + + +def update_schemastore(schemastore: Path) -> None: + if not schemastore.is_dir(): + check_call(["git", "clone", schemastore_fork, schemastore]) + check_call( + [ + "git", + "remote", + "add", + "upstream", + schemastore_upstream, + ], + cwd=schemastore, + ) + # Create a new branch tagged with the current ruff commit up to date with the latest + # upstream schemastore + check_call(["git", "fetch", "upstream"], cwd=schemastore) + current_sha = check_output(["git", "rev-parse", "HEAD"], text=True).strip() + branch = f"update-ruff-{current_sha}" + check_call( + ["git", "switch", "-c", branch], + cwd=schemastore, + ) + check_call( + ["git", "reset", "--hard", "upstream/master"], + cwd=schemastore, + ) + + # Update the schema and format appropriately + schema = json.loads(root.joinpath("ruff.schema.json").read_text()) + schema["$id"] = "https://json.schemastore.org/ruff.json" + schemastore.joinpath(ruff_json).write_text( + json.dumps(dict(sorted(schema.items())), indent=2, ensure_ascii=False), + ) + check_call(["prettier", "--write", ruff_json], cwd=schemastore) + + # Check if the schema has changed + # https://stackoverflow.com/a/9393642/3549270 + if check_output(["git", "status", "-s"], cwd=schemastore).strip(): + # Schema has changed, commit and push + commit_url = f"{ruff_repo}/commit/{current_sha}" + commit_body = ( + f"This updates ruff's JSON schema to [{current_sha}]({commit_url})" + ) + # https://stackoverflow.com/a/22909204/3549270 + check_call( + [ + "git", + "commit", + "-a", + "-m", + "Update ruff's JSON schema", + "-m", + commit_body, + ], + cwd=schemastore, + ) + # This should show the link to create a PR + check_call( + ["git", "push", "--set-upstream", "origin", branch], + cwd=schemastore, + ) + else: + print("No changes") + + +def main() -> None: + schemastore_existing = root.joinpath("schemastore") + if schemastore_existing.is_dir(): + update_schemastore(schemastore_existing) + else: + with TemporaryDirectory() as temp_dir: + update_schemastore(Path(temp_dir).joinpath("schemastore")) + + +if __name__ == "__main__": + main()