Repository navigation
Expand file tree
/
Copy pathcheck-scripts.py
More file actions
executable file
·132 lines (106 loc) · 3.88 KB
/
Copy pathcheck-scripts.py
File metadata and controls
executable file
·132 lines (106 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env -S uv run --script
#
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "pathspec>=1.1.1",
# ]
#
# [tool.ty.analysis]
# return-type-inference = "always"
#
# [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"
#
# [tool.uv]
# require-build-hashes = true
# preview-features = ["build-dependency-hashes", "missing-exclude-newer-package-lock"]
# ///
"""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())