ruff/scripts/update_schemastore.py
konstin 04d273bcc7
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
2023-05-23 10:41:56 +00:00

97 lines
3.1 KiB
Python

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