mirror of
https://github.com/aphrody-labs/ruff.git
synced 2026-10-14 14:19:13 +00:00
126 lines
3.7 KiB
Python
Executable File
126 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env -S uv run --script
|
|
#
|
|
# /// script
|
|
# requires-python = ">=3.12"
|
|
# dependencies = [
|
|
# "pathspec>=1.1.1",
|
|
# ]
|
|
#
|
|
# [tool.ty.rules]
|
|
# truthiness-test-of-none-union = "warn"
|
|
# blanket-ignore-comment = "warn"
|
|
# missing-type-argument = "warn"
|
|
# possibly-unresolved-reference = "warn"
|
|
# unsound-return-statement = "warn"
|
|
# unsound-yield = "warn"
|
|
# unsupported-dynamic-base = "warn"
|
|
# division-by-zero = "warn"
|
|
# dynamic-function-decorator-return = "warn"
|
|
# unsound-assignment = "warn"
|
|
# redundant-condition-strict = "warn"
|
|
# disjoint-cast = "warn"
|
|
# missing-direct-dependency = "warn"
|
|
# ///
|
|
|
|
"""Update script lockfiles.
|
|
|
|
Run `uv run scripts/check-scripts.py` to update the lockfiles.
|
|
Use `--write-ty-args-file <path>` to write the discovered scripts to an argument file for ty
|
|
instead of updating lockfiles.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import subprocess
|
|
import sys
|
|
from collections.abc import Iterator
|
|
from pathlib import Path
|
|
|
|
from pathspec import GitIgnoreSpec
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
# Crate resources and completion fixtures are inputs, not project scripts.
|
|
COMPLETION_FIXTURES = Path("crates/ty_completion_eval/truth")
|
|
|
|
|
|
def scripts() -> Iterator[Path]:
|
|
"""Yield paths to Python scripts containing PEP 723 metadata.
|
|
|
|
The paths are relative to the repository root. Files ignored by the root
|
|
`.gitignore`, symlinks, crate resources, and completion fixtures are
|
|
excluded. Scripts with invalid metadata are included so `uv lock` can
|
|
report the error.
|
|
"""
|
|
|
|
gitignore = GitIgnoreSpec.from_lines((ROOT / ".gitignore").read_text().splitlines())
|
|
|
|
# uv's script listing skips invalid metadata, so find candidates before
|
|
# asking uv to validate and lock them.
|
|
#
|
|
# We use `.walk()` here rather than `.rglob()` because some of our ignored directories are
|
|
# huge; `.walk()` allows us to lazily inspect whether they're gitignored before recursively
|
|
# descending into them.
|
|
for directory, dirnames, filenames in ROOT.walk():
|
|
dirnames[:] = [
|
|
dirname
|
|
for dirname in dirnames
|
|
if (path := (directory / dirname).relative_to(ROOT)) != Path(".git")
|
|
and not gitignore.match_file(f"{path.as_posix()}/")
|
|
]
|
|
|
|
for filename in filenames:
|
|
if not filename.endswith(".py"):
|
|
continue
|
|
|
|
full_path = directory / filename
|
|
|
|
path = full_path.relative_to(ROOT)
|
|
|
|
if path.is_relative_to(COMPLETION_FIXTURES):
|
|
continue
|
|
|
|
match full_path.relative_to(ROOT).parts:
|
|
case ("crates", _, "resources", *_):
|
|
continue
|
|
|
|
if (
|
|
full_path.is_symlink()
|
|
or not full_path.is_file()
|
|
or gitignore.match_file(path)
|
|
):
|
|
continue
|
|
|
|
if b"# /// script" in full_path.read_bytes().splitlines():
|
|
yield path
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__, allow_abbrev=False)
|
|
parser.add_argument(
|
|
"--write-ty-args-file",
|
|
type=Path,
|
|
help="Write script paths to an argument file for ty",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
if args.write_ty_args_file is not None:
|
|
args.write_ty_args_file.write_text(
|
|
"".join(f"{script}\n" for script in scripts()), encoding="utf-8"
|
|
)
|
|
return 0
|
|
|
|
failed = False
|
|
|
|
for script in scripts():
|
|
print(script, flush=True)
|
|
command = ["uv", "lock", "--script", str(script), "--refresh", "--no-locked"]
|
|
result = subprocess.run(command, cwd=ROOT, check=False)
|
|
failed |= result.returncode != 0
|
|
|
|
return int(failed)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|