131 lines
2.9 KiB
Python
Executable File
131 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# /// script
|
|
# requires-python = ">=3.12"
|
|
# dependencies = []
|
|
# ///
|
|
'''
|
|
Ruff lint checker for piker docstring and code style.
|
|
|
|
Checks staged files by default, or the full `piker/`
|
|
tree with `--all`. Uses the project's `ruff.toml`.
|
|
|
|
'''
|
|
import argparse
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def get_staged_py_files() -> list[str]:
|
|
'''
|
|
Return staged Python file paths (added/copied/modified).
|
|
|
|
'''
|
|
result = subprocess.run(
|
|
[
|
|
'git', 'diff',
|
|
'--cached',
|
|
'--name-only',
|
|
'--diff-filter=ACM',
|
|
'--', '*.py',
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
return [
|
|
f for f in result.stdout.strip().split('\n')
|
|
if f
|
|
]
|
|
|
|
|
|
def main() -> int:
|
|
'''
|
|
Parse args and run `ruff check` against targets.
|
|
|
|
'''
|
|
ap = argparse.ArgumentParser(
|
|
description=(
|
|
"Run ruff check with piker's ruff.toml config.\n"
|
|
'\n'
|
|
'Default: checks staged .py files only.\n'
|
|
'Use --all for the full piker/ tree.'
|
|
),
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
)
|
|
ap.add_argument(
|
|
'paths',
|
|
nargs='*',
|
|
help='files/dirs to check (default: staged)',
|
|
)
|
|
ap.add_argument(
|
|
'--all', '-a',
|
|
action='store_true',
|
|
dest='check_all',
|
|
help='check entire piker/ directory',
|
|
)
|
|
ap.add_argument(
|
|
'--fix',
|
|
action='store_true',
|
|
help='auto-fix fixable violations',
|
|
)
|
|
ap.add_argument(
|
|
'--diff',
|
|
action='store_true',
|
|
help='preview fixes as unified diff (dry-run)',
|
|
)
|
|
ap.add_argument(
|
|
'--stats',
|
|
action='store_true',
|
|
help='show per-rule violation counts only',
|
|
)
|
|
args = ap.parse_args()
|
|
|
|
# determine check targets
|
|
if args.check_all:
|
|
targets: list[str] = ['piker/']
|
|
elif args.paths:
|
|
targets = args.paths
|
|
else:
|
|
targets = get_staged_py_files()
|
|
if not targets:
|
|
print(
|
|
'No staged Python files found.\n'
|
|
'Use --all for full codebase '
|
|
'or pass file paths.'
|
|
)
|
|
return 0
|
|
print(
|
|
f'Checking {len(targets)} staged file(s)..\n'
|
|
)
|
|
|
|
# ensure ruff is available on PATH
|
|
if not shutil.which('ruff'):
|
|
print(
|
|
'Error: `ruff` not found on PATH.\n'
|
|
'On NixOS: add to flake.nix or '
|
|
'`nix-shell -p ruff`\n'
|
|
'Otherwise: `uv sync --group lint` or '
|
|
'`pip install ruff`'
|
|
)
|
|
return 127
|
|
|
|
# build ruff command
|
|
cmd: list[str] = ['ruff', 'check']
|
|
|
|
if args.diff:
|
|
cmd.append('--diff')
|
|
elif args.fix:
|
|
cmd.append('--fix')
|
|
|
|
if args.stats:
|
|
cmd.append('--statistics')
|
|
|
|
cmd.extend(targets)
|
|
|
|
result = subprocess.run(cmd)
|
|
return result.returncode
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|