#!/usr/bin/env python3 """ Unified Code Validator ====================== Runs all validation scripts (architecture, security, performance, audit) in sequence. This provides a single entry point for comprehensive code validation, useful for CI/CD pipelines and pre-commit hooks. Usage: python scripts/validate/validate_all.py # Run all validators python scripts/validate/validate_all.py --security # Run only security validator python scripts/validate/validate_all.py --performance # Run only performance validator python scripts/validate/validate_all.py --architecture # Run only architecture validator python scripts/validate/validate_all.py --audit # Run only audit validator python scripts/validate/validate_all.py -v # Verbose output python scripts/validate/validate_all.py --fail-fast # Stop on first failure python scripts/validate/validate_all.py --json # JSON output Options: --architecture Run architecture validator --security Run security validator --performance Run performance validator --audit Run audit validator --fail-fast Stop on first validator failure -v, --verbose Show detailed output --errors-only Only show errors --json Output results as JSON """ import argparse import json import sys from pathlib import Path # Add parent directory to path for imports sys.path.insert(0, str(Path(__file__).parent)) def run_architecture_validator(verbose: bool = False) -> tuple[int, dict]: """Run the architecture validator""" try: # Import dynamically to avoid circular imports from validate_architecture import ArchitectureValidator config_path = Path.cwd() / ".architecture-rules.yaml" validator = ArchitectureValidator(config_path=config_path, verbose=verbose) result = validator.validate_all() return ( 1 if result.has_errors() else 0, { "name": "Architecture", "files_checked": result.files_checked, "errors": sum(1 for v in result.violations if v.severity.value == "error"), "warnings": sum(1 for v in result.violations if v.severity.value == "warning"), "info": sum(1 for v in result.violations if v.severity.value == "info"), } ) except ImportError as e: print(f"⚠️ Architecture validator not available: {e}") return 0, {"name": "Architecture", "skipped": True} except Exception as e: print(f"❌ Architecture validator failed: {e}") return 1, {"name": "Architecture", "error": str(e)} def run_security_validator(verbose: bool = False) -> tuple[int, dict]: """Run the security validator""" try: from validate_security import SecurityValidator validator = SecurityValidator(verbose=verbose) result = validator.validate_all() return ( 1 if result.has_errors() else 0, { "name": "Security", "files_checked": result.files_checked, "errors": result.error_count(), "warnings": result.warning_count(), "info": result.info_count(), } ) except ImportError as e: print(f"⚠️ Security validator not available: {e}") return 0, {"name": "Security", "skipped": True} except Exception as e: print(f"❌ Security validator failed: {e}") return 1, {"name": "Security", "error": str(e)} def run_performance_validator(verbose: bool = False) -> tuple[int, dict]: """Run the performance validator""" try: from validate_performance import PerformanceValidator validator = PerformanceValidator(verbose=verbose) result = validator.validate_all() return ( 1 if result.has_errors() else 0, { "name": "Performance", "files_checked": result.files_checked, "errors": result.error_count(), "warnings": result.warning_count(), "info": result.info_count(), } ) except ImportError as e: print(f"⚠️ Performance validator not available: {e}") return 0, {"name": "Performance", "skipped": True} except Exception as e: print(f"❌ Performance validator failed: {e}") return 1, {"name": "Performance", "error": str(e)} def run_audit_validator(verbose: bool = False) -> tuple[int, dict]: """Run the audit validator""" try: from validate_audit import AuditValidator validator = AuditValidator() has_errors = not validator.validate() return ( 1 if has_errors else 0, { "name": "Audit", "files_checked": len(validator.files_checked) if hasattr(validator, 'files_checked') else 0, "errors": len(validator.errors), "warnings": len(validator.warnings), "info": len(validator.info) if hasattr(validator, 'info') else 0, } ) except ImportError as e: print(f"⚠️ Audit validator not available: {e}") return 0, {"name": "Audit", "skipped": True} except Exception as e: print(f"❌ Audit validator failed: {e}") return 1, {"name": "Audit", "error": str(e)} def print_summary(results: list[dict], json_output: bool = False): """Print validation summary""" if json_output: print(json.dumps({"validators": results}, indent=2)) return print("\n" + "=" * 80) print("📊 UNIFIED VALIDATION SUMMARY") print("=" * 80) total_errors = 0 total_warnings = 0 total_info = 0 for result in results: if result.get("skipped"): print(f"\n⏭️ {result['name']}: Skipped") elif result.get("error"): print(f"\n❌ {result['name']}: Error - {result['error']}") else: errors = result.get("errors", 0) warnings = result.get("warnings", 0) info = result.get("info", 0) total_errors += errors total_warnings += warnings total_info += info status = "✅" if errors == 0 else "❌" print(f"\n{status} {result['name']}:") print(f" Files: {result.get('files_checked', 0)}") print(f" Errors: {errors}, Warnings: {warnings}, Info: {info}") print("\n" + "-" * 80) print(f"TOTAL: {total_errors} errors, {total_warnings} warnings, {total_info} info") print("=" * 80) if total_errors > 0: print("❌ VALIDATION FAILED") elif total_warnings > 0: print(f"⚠️ VALIDATION PASSED WITH {total_warnings} WARNING(S)") else: print("✅ VALIDATION PASSED") print("=" * 80) def main(): parser = argparse.ArgumentParser( description="Unified code validator - runs architecture, security, performance, and audit checks", formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument("--architecture", action="store_true", help="Run architecture validator") parser.add_argument("--security", action="store_true", help="Run security validator") parser.add_argument("--performance", action="store_true", help="Run performance validator") parser.add_argument("--audit", action="store_true", help="Run audit validator") parser.add_argument("--fail-fast", action="store_true", help="Stop on first failure") parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output") parser.add_argument("--errors-only", action="store_true", help="Only show errors") parser.add_argument("--json", action="store_true", help="JSON output") args = parser.parse_args() # If no specific validators selected, run all run_all = not (args.architecture or args.security or args.performance or args.audit) print("\n🔍 UNIFIED CODE VALIDATION") print("=" * 80) validators = [] if run_all or args.architecture: validators.append(("Architecture", run_architecture_validator)) if run_all or args.security: validators.append(("Security", run_security_validator)) if run_all or args.performance: validators.append(("Performance", run_performance_validator)) if run_all or args.audit: validators.append(("Audit", run_audit_validator)) results = [] exit_code = 0 for name, validator_func in validators: print(f"\n{'=' * 40}") print(f"🔍 Running {name} Validator...") print("=" * 40) code, result = validator_func(verbose=args.verbose) results.append(result) if code != 0: exit_code = 1 if args.fail_fast: print(f"\n❌ {name} validator failed. Stopping (--fail-fast)") break print_summary(results, json_output=args.json) sys.exit(exit_code) if __name__ == "__main__": main()