# Import standard OS path features import os # Import sys to handle runtime exits import sys # Import command-line argument parser utilities import argparse # Import subprocess to execute linter binaries import subprocess def run_command(command: list, description: str) -> bool: """Runs a shell command and displays output with color markers.""" # Display the active task title print(f"\n=== Running {description} ===") # Print the exact command list parsed into a string print(f"Command: {' '.join(command)}") try: # Run binary in subprocess, capturing output text blocks result = subprocess.run(command, capture_output=True, text=True) # Check if the execution returned exit code zero (success) if result.returncode == 0: print("โœ… SUCCESS") # Print standard output if text is present if result.stdout.strip(): print(result.stdout.strip()) return True # Handle execution failure (non-zero exit code) else: print("โŒ FAILED") # Print output logs to support troubleshooting if result.stdout.strip(): print("\nStdout:") print(result.stdout.strip()) # Print error logs if present if result.stderr.strip(): print("\nStderr:") print(result.stderr.strip()) return False except FileNotFoundError: # Log failure if linter binary cannot be found in virtual env print( f"โŒ ERROR: Command '{command[0]}' not found. Make sure dependencies are installed in your virtual environment." ) return False def cleanup_cache(workspace_dir: str): """Deletes .ruff_cache and all __pycache__ folders inside the workspace.""" import shutil print("\n๐Ÿงน Cleaning up cache folders...") # Delete .ruff_cache folder ruff_cache = os.path.join(workspace_dir, ".ruff_cache") if os.path.exists(ruff_cache): try: shutil.rmtree(ruff_cache) print("Removed .ruff_cache") except Exception as e: print(f"Failed to remove .ruff_cache: {e}") # Delete all __pycache__ folders recursively for root, dirs, files in os.walk(workspace_dir): # Walk and remove pycache directories in the project for d in list(dirs): if d == "__pycache__": pycache_path = os.path.join(root, d) try: shutil.rmtree(pycache_path) print( f"Removed pycache: {os.path.relpath(pycache_path, workspace_dir)}" ) dirs.remove(d) except Exception as e: print(f"Failed to remove pycache {pycache_path}: {e}") def main(): # Setup CLI argument parser parser = argparse.ArgumentParser( description="Code hygiene and quality verification pipeline." ) # Register the auto-fix parameter flag parser.add_argument( "--fix", "-f", action="store_true", help="Attempt to auto-format files and auto-fix linter issues.", ) # Parse incoming CLI command arguments args = parser.parse_args() # Resolve the absolute workspace directory of this checker script workspace_dir = os.path.dirname(os.path.abspath(__file__)) # Shift current working directory to workspace base os.chdir(workspace_dir) # Resolve virtual environment bin executable directory path venv_bin = os.path.join(workspace_dir, ".venv", "bin") # Prepend virtual environment bin path to PATH to locate local ruff/pyright binaries if os.path.exists(venv_bin): os.environ["PATH"] = venv_bin + os.pathsep + os.environ.get("PATH", "") # Execute auto-fixing parameters if flag is parsed if args.fix: print("๐Ÿ”ง Attempting to auto-correct issues...") # Execute Ruff formatting in write mode fmt_passed = run_command( ["ruff", "format", "."], "Ruff Code Formatting (Auto-fixing)" ) # Execute Ruff linter in auto-fix write mode lint_passed = run_command( ["ruff", "check", "--fix", "."], "Ruff Linter (Auto-fixing)" ) # Execute default validation parameters (dry run) else: # Execute Ruff formatting in validation check-only mode fmt_passed = run_command( ["ruff", "format", "--check", "."], "Ruff Code Formatting Validation" ) # Execute Ruff linter in check-only validation mode lint_passed = run_command(["ruff", "check", "."], "Ruff Linter Validation") # Run Pyright static type checker against the codebase type_passed = run_command(["pyright", "."], "Pyright Static Type Validation") # Clean up caching directories (Ruff cache and all __pycache__ folders) cleanup_cache(workspace_dir) # Evaluate if all checkers completed successfully if fmt_passed and lint_passed and type_passed: print( "\n๐ŸŽ‰ CODEBASE IS PRISTINE: Formatting is correct, lint checks passed, and type signatures are valid!" ) # Exit with success code sys.exit(0) else: # Report failure if any validation check fails print( "\nโš ๏ธ CODE BASE ISSUES FOUND: Please resolve the formatting, lint, or type signatures issues listed above." ) # Suggest auto-fix parameter tip if running in dry-run mode if not args.fix: print( "๐Ÿ’ก TIP: Run 'python verify_code.py --fix' to automatically resolve formatting and simple linter warnings." ) # Exit with failure code sys.exit(1) # Execute checks when running checker script directly if __name__ == "__main__": main()