validate_shell.py 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #!/usr/bin/env python3
  2. import concurrent.futures
  3. import pathlib
  4. import subprocess
  5. import sys
  6. EXCLUDE_DIRS = {".git"}
  7. def find_shell_files(root="."):
  8. for path in pathlib.Path(root).rglob("*.sh"):
  9. if any(part in EXCLUDE_DIRS for part in path.parts):
  10. continue
  11. yield path
  12. def check_file(path):
  13. result = subprocess.run(
  14. ["bash", "-n", str(path)],
  15. capture_output=True,
  16. text=True,
  17. )
  18. if result.returncode != 0:
  19. return path, result.stderr.strip()
  20. return path, None
  21. def main():
  22. files = sorted(find_shell_files())
  23. if not files:
  24. print("No shell scripts found.")
  25. return 0
  26. status = 0
  27. with concurrent.futures.ThreadPoolExecutor() as executor:
  28. results = executor.map(check_file, files)
  29. for path, error in results:
  30. if error:
  31. print(f"Syntax error in: {path}")
  32. print(f" {error}")
  33. status = 1
  34. print(f"Checked {len(files)} shell script(s).")
  35. return status
  36. if __name__ == "__main__":
  37. sys.exit(main())