-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlint
More file actions
executable file
·115 lines (97 loc) · 3.14 KB
/
Copy pathlint
File metadata and controls
executable file
·115 lines (97 loc) · 3.14 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
#!/usr/bin/env python3
"""Run workspace linting: rustfmt, Clippy, and pinned custom Dylint checks.
Usage:
uv run --script lint # full workspace lint
uv run --script lint --fix # auto-fix formatting + clippy
uv run --script lint <file.rs> # single-file rustfmt + per-crate Clippy/Dylint
"""
import os
import subprocess
import sys
from pathlib import Path
SCRIPT_DIR = Path(__file__).parent.resolve()
# Activate rustup toolchain on PATH before any Rust tool invocations
sys.path.insert(0, str(SCRIPT_DIR))
from ci.env import activate
activate()
def detect_crate(file_path: str) -> str:
"""Detect crate name from file path (e.g. crates/fbuild-build/... -> fbuild-build)."""
normalized = file_path.replace("\\", "/")
if "crates/" in normalized:
after = normalized.split("crates/", 1)[1]
crate_dir = after.split("/", 1)[0]
if crate_dir:
return crate_dir
return ""
def run(args: list[str]) -> int:
"""Run a command and return exit code."""
result = subprocess.run(args, cwd=str(SCRIPT_DIR), check=False)
return result.returncode
def run_dylint(crate: str = "") -> int:
"""Run all custom lints over the workspace or an edited file's crate."""
args = [sys.executable, "-m", "ci.run_dylint"]
if crate:
args.extend(["--package", crate])
return run(args)
def main() -> int:
fix = False
file_arg = ""
for arg in sys.argv[1:]:
if arg == "--fix":
fix = True
elif arg.endswith(".rs"):
file_arg = arg
# --fix mode
if fix:
rc = run(["soldr", "cargo", "fmt", "--all"])
if rc != 0:
return rc
# Single file mode
if file_arg:
file_path = str(Path(file_arg).resolve())
if not os.path.isfile(file_path):
print(f"File not found: {file_path}", file=sys.stderr)
return 1
rc = run(["soldr", "rustfmt", file_path])
if rc != 0:
return rc
crate = detect_crate(file_path)
if crate:
rc = run(
[
"soldr", "cargo", "clippy",
"-p", crate, "--all-targets", "--", "-D", "warnings",
]
)
else:
rc = run(
[
"soldr", "cargo", "clippy",
"--workspace", "--all-targets", "--", "-D", "warnings",
]
)
return rc if rc else run_dylint(crate)
# Full workspace mode
for checker in (
"ci/check_rust_toolchain_pins.py",
"ci/enforce_platform_boundary.py",
):
rc = run([sys.executable, checker])
if rc != 0:
return rc
rc = run(["soldr", "cargo", "fmt", "--all", "--check"])
if rc != 0:
print(
"Formatting issues found. Run 'uv run --script lint --fix' to auto-fix.",
file=sys.stderr,
)
return 1
rc = run(
[
"soldr", "cargo", "clippy",
"--workspace", "--all-targets", "--", "-D", "warnings",
]
)
return rc if rc else run_dylint()
if __name__ == "__main__":
sys.exit(main())