mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-22 16:22:52 +00:00

Same as https://github.com/astral-sh/ty/pull/1391: > Last time I ran this script, due to what I assume was a `npm` version mismatch, the `package-lock.json` file was updated while running `npm install` in the `schemastore`. Due to the use of `git commit -a`, it was accidentally included in the commit for the semi-automated schemastore PR. The solution here is to only add the actual file that we want to commit.
168 lines
5.1 KiB
Python
168 lines
5.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.
|
|
|
|
Usage:
|
|
|
|
uv run --only-dev scripts/update_schemastore.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import enum
|
|
import json
|
|
from pathlib import Path
|
|
from subprocess import check_call, check_output
|
|
from tempfile import TemporaryDirectory
|
|
from typing import NamedTuple, assert_never
|
|
|
|
# The remote URL for the `ruff` repository.
|
|
RUFF_REPO = "https://github.com/astral-sh/ruff"
|
|
|
|
# The path to the root of the `ruff` repository.
|
|
RUFF_ROOT = Path(__file__).parent.parent
|
|
|
|
# The path to the JSON schema in the `ruff` repository.
|
|
RUFF_SCHEMA = RUFF_ROOT / "ruff.schema.json"
|
|
|
|
# The path to the JSON schema in the `schemastore` repository.
|
|
RUFF_JSON = Path("schemas/json/ruff.json")
|
|
|
|
|
|
class SchemastoreRepos(NamedTuple):
|
|
fork: str
|
|
upstream: str
|
|
|
|
|
|
class GitProtocol(enum.Enum):
|
|
SSH = "ssh"
|
|
HTTPS = "https"
|
|
|
|
def schemastore_repos(self) -> SchemastoreRepos:
|
|
match self:
|
|
case GitProtocol.SSH:
|
|
return SchemastoreRepos(
|
|
fork="git@github.com:astral-sh/schemastore.git",
|
|
upstream="git@github.com:SchemaStore/schemastore.git",
|
|
)
|
|
case GitProtocol.HTTPS:
|
|
return SchemastoreRepos(
|
|
fork="https://github.com/astral-sh/schemastore.git",
|
|
upstream="https://github.com/SchemaStore/schemastore.git",
|
|
)
|
|
case _:
|
|
assert_never(self)
|
|
|
|
|
|
def update_schemastore(
|
|
schemastore_path: Path, schemastore_repos: SchemastoreRepos
|
|
) -> None:
|
|
if not (schemastore_path / ".git").is_dir():
|
|
check_call(
|
|
["git", "clone", schemastore_repos.fork, schemastore_path, "--depth=1"]
|
|
)
|
|
check_call(
|
|
[
|
|
"git",
|
|
"remote",
|
|
"add",
|
|
"upstream",
|
|
schemastore_repos.upstream,
|
|
],
|
|
cwd=schemastore_path,
|
|
)
|
|
# 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_path)
|
|
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_path,
|
|
)
|
|
check_call(
|
|
["git", "reset", "--hard", "upstream/master"],
|
|
cwd=schemastore_path,
|
|
)
|
|
|
|
# Run npm install
|
|
src = schemastore_path / "src"
|
|
check_call(["npm", "install"], cwd=schemastore_path)
|
|
|
|
# Update the schema and format appropriately
|
|
schema = json.loads(RUFF_SCHEMA.read_text())
|
|
schema["$id"] = "https://json.schemastore.org/ruff.json"
|
|
(src / RUFF_JSON).write_text(
|
|
json.dumps(dict(schema.items()), indent=2, ensure_ascii=False),
|
|
)
|
|
check_call(
|
|
[
|
|
"../node_modules/prettier/bin/prettier.cjs",
|
|
"--plugin",
|
|
"prettier-plugin-sort-json",
|
|
"--write",
|
|
RUFF_JSON,
|
|
],
|
|
cwd=src,
|
|
)
|
|
|
|
# Check if the schema has changed
|
|
# https://stackoverflow.com/a/9393642/3549270
|
|
if check_output(["git", "status", "-s"], cwd=schemastore_path).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", "add", (src / RUFF_JSON).as_posix()], cwd=schemastore_path)
|
|
check_call(
|
|
[
|
|
"git",
|
|
"commit",
|
|
"-m",
|
|
"Update ruff's JSON schema",
|
|
"-m",
|
|
commit_body,
|
|
],
|
|
cwd=schemastore_path,
|
|
)
|
|
# This should show the link to create a PR
|
|
check_call(
|
|
["git", "push", "--set-upstream", "origin", branch, "--force"],
|
|
cwd=schemastore_path,
|
|
)
|
|
else:
|
|
print("No changes")
|
|
|
|
|
|
def determine_git_protocol(argv: list[str] | None = None) -> GitProtocol:
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
|
|
)
|
|
parser.add_argument(
|
|
"--proto",
|
|
choices=[proto.value for proto in GitProtocol],
|
|
default="https",
|
|
help="Protocol to use for git authentication",
|
|
)
|
|
args = parser.parse_args(argv)
|
|
return GitProtocol(args.proto)
|
|
|
|
|
|
def main() -> None:
|
|
schemastore_repos = determine_git_protocol().schemastore_repos()
|
|
schemastore_existing = RUFF_ROOT / "schemastore"
|
|
if schemastore_existing.is_dir():
|
|
update_schemastore(schemastore_existing, schemastore_repos)
|
|
else:
|
|
with TemporaryDirectory(prefix="ruff-schemastore-") as temp_dir:
|
|
update_schemastore(Path(temp_dir), schemastore_repos)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|