initial commit
This commit is contained in:
151
libraries/FastLED/ci/pyright-cached.py
Normal file
151
libraries/FastLED/ci/pyright-cached.py
Normal file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python3
|
||||
# pyright: reportUnknownMemberType=false
|
||||
"""
|
||||
Caching wrapper for pyright that only runs if files have changed.
|
||||
This significantly speeds up repeated pyright runs during development.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
|
||||
def get_file_hash(file_path: Path) -> str:
|
||||
"""Get SHA256 hash of a file."""
|
||||
try:
|
||||
with open(file_path, "rb") as f:
|
||||
return hashlib.sha256(f.read()).hexdigest()
|
||||
except (OSError, IOError):
|
||||
return ""
|
||||
|
||||
|
||||
def get_directory_hash(directory: Path, extensions: Optional[List[str]] = None) -> str:
|
||||
"""Get combined hash of all files in a directory."""
|
||||
if extensions is None:
|
||||
extensions = [".py"]
|
||||
|
||||
hashes: List[str] = []
|
||||
if directory.exists():
|
||||
for ext in extensions:
|
||||
for file_path in directory.rglob(f"*{ext}"):
|
||||
if file_path.is_file():
|
||||
hashes.append(
|
||||
f"{file_path.relative_to(directory)}:{get_file_hash(file_path)}"
|
||||
)
|
||||
|
||||
hashes.sort() # Ensure consistent ordering
|
||||
return hashlib.sha256("\n".join(hashes).encode()).hexdigest()
|
||||
|
||||
|
||||
def get_cache_file() -> Path:
|
||||
"""Get the cache file path."""
|
||||
cache_dir = Path(".cache/pyright")
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
return cache_dir / "file_hashes.json"
|
||||
|
||||
|
||||
def load_cache() -> Dict[str, str]:
|
||||
"""Load the cache file."""
|
||||
cache_file = get_cache_file()
|
||||
if cache_file.exists():
|
||||
try:
|
||||
with open(cache_file, "r") as f:
|
||||
return json.load(f)
|
||||
except (json.JSONDecodeError, IOError):
|
||||
pass
|
||||
return {}
|
||||
|
||||
|
||||
def save_cache(cache: Dict[str, str]) -> None:
|
||||
"""Save the cache file."""
|
||||
cache_file = get_cache_file()
|
||||
try:
|
||||
with open(cache_file, "w") as f:
|
||||
json.dump(cache, f, indent=2)
|
||||
except IOError:
|
||||
pass # Ignore cache save errors
|
||||
|
||||
|
||||
def has_files_changed() -> bool:
|
||||
"""Check if any relevant files have changed since last run."""
|
||||
cache = load_cache()
|
||||
changed = False
|
||||
|
||||
# Files and directories to check
|
||||
files_to_check = [
|
||||
Path("pyrightconfig.json"),
|
||||
Path(".pyrightconfig.json"),
|
||||
Path("pyproject.toml"),
|
||||
]
|
||||
|
||||
directories_to_check = [
|
||||
Path("ci"),
|
||||
]
|
||||
|
||||
# Check individual files
|
||||
for file_path in files_to_check:
|
||||
if file_path.exists():
|
||||
current_hash = get_file_hash(file_path)
|
||||
if cache.get(str(file_path)) != current_hash:
|
||||
cache[str(file_path)] = current_hash
|
||||
changed = True
|
||||
|
||||
# Check directories
|
||||
for dir_path in directories_to_check:
|
||||
if dir_path.exists():
|
||||
current_hash = get_directory_hash(dir_path)
|
||||
cache_key = f"dir:{dir_path}"
|
||||
if cache.get(cache_key) != current_hash:
|
||||
cache[cache_key] = current_hash
|
||||
changed = True
|
||||
|
||||
# Save cache if any changes were detected
|
||||
if changed:
|
||||
save_cache(cache)
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
def run_pyright(args: List[str]) -> int:
|
||||
"""Run pyright with the given arguments."""
|
||||
env = os.environ.copy()
|
||||
# env["PYRIGHT_PYTHON_FORCE_VERSION"] = "latest"
|
||||
env["PYRIGHT_PYTHON_CACHE_DIR"] = ".cache/pyright"
|
||||
|
||||
cmd = ["uv", "run", "pyright"] + args
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, env=env)
|
||||
return result.returncode
|
||||
except KeyboardInterrupt:
|
||||
return 1
|
||||
except Exception as e:
|
||||
print(f"Error running pyright: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Main entry point."""
|
||||
args = sys.argv[1:] # Remove script name
|
||||
|
||||
# If --force is passed, skip cache check
|
||||
if "--force" in args:
|
||||
args.remove("--force")
|
||||
print("Forcing pyright run (--force flag detected)")
|
||||
return run_pyright(args)
|
||||
|
||||
# Check if files have changed
|
||||
if not has_files_changed():
|
||||
print("No changes detected, skipping pyright (use --force to override)")
|
||||
return 0
|
||||
|
||||
print("Changes detected, running pyright...")
|
||||
return run_pyright(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user