#!/usr/bin/env python3 """YAML linter using pure Python - no external dependencies.""" import sys import re from pathlib import Path def check_yaml_basic(filepath): """Basic YAML syntax check without external libs.""" errors = [] with open(filepath, "r") as f: lines = f.readlines() # Check for tabs (YAML spec violation) for i, line in enumerate(lines, 1): if "\t" in line: errors.append(f"Line {i}: Tab found (YAML uses spaces)") # Check for consistent indentation for i, line in enumerate(lines, 1): if line.strip() and not line.startswith("#"): # non-empty, non-comment indent = len(line) - len(line.lstrip()) if indent % 2 != 0: errors.append(f"Line {i}: Odd indentation ({indent} spaces)") # Check for valid key: value pattern for i, line in enumerate(lines, 1): stripped = line.strip() if stripped and not stripped.startswith("#"): if ":" not in stripped and not stripped.startswith("-"): # Could be a continuation line, skip pass return errors def main(): target_dir = sys.argv[1] if len(sys.argv) > 1 else "." base = Path(target_dir) yaml_files = [] for ext in ("*.yaml", "*.yml", "*.YML", "*.YAML"): yaml_files.extend(base.rglob(ext)) if not yaml_files: print(f"No YAML files found in {target_dir}") sys.exit(0) valid = [] invalid = [] for yf in sorted(yaml_files): errors = check_yaml_basic(yf) if errors: invalid.append((str(yf), errors)) else: valid.append(str(yf)) print(f"Checked {len(yaml_files)} YAML file(s)") print(f"Valid: {len(valid)}") if valid: for f in valid[:5]: print(f" ✓ {f}") if len(valid) > 5: print(f" ... and {len(valid) - 5} more") print(f"\nInvalid: {len(invalid)}") for filepath, errs in invalid[:5]: print(f" ✗ {filepath}") for e in errs[:3]: print(f" {e}") if invalid: print(f"\nVERDICT: {len(invalid)} YAML file(s) have syntax issues.") sys.exit(1) print("\nVERDICT: All YAML files pass basic syntax validation.") if __name__ == "__main__": main()