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()