#!/usr/bin/env python3 """Validate project manifest integrity.""" import argparse import json import os import sys def validate_structure(manifest: dict) -> list: """Validate manifest has required structure.""" errors = [] required_keys = ["project", "state", "entities", "dependencies"] for key in required_keys: if key not in manifest: errors.append(f"Missing required key: {key}") if "entities" in manifest: entity_types = ["pages", "components", "api_endpoints", "database_tables"] for etype in entity_types: if etype not in manifest["entities"]: errors.append(f"Missing entity type: {etype}") return errors def validate_pages(pages: list) -> list: """Validate page entities.""" errors = [] for page in pages: if "id" not in page: errors.append(f"Page missing id: {page}") if "path" not in page: errors.append(f"Page {page.get('id', 'unknown')} missing path") if "file_path" not in page: errors.append(f"Page {page.get('id', 'unknown')} missing file_path") return errors def validate_components(components: list) -> list: """Validate component entities.""" errors = [] for comp in components: if "id" not in comp: errors.append(f"Component missing id: {comp}") if "name" not in comp: errors.append(f"Component {comp.get('id', 'unknown')} missing name") if "file_path" not in comp: errors.append(f"Component {comp.get('id', 'unknown')} missing file_path") return errors def validate_apis(apis: list) -> list: """Validate API endpoint entities.""" errors = [] for api in apis: if "id" not in api: errors.append(f"API missing id: {api}") if "method" not in api: errors.append(f"API {api.get('id', 'unknown')} missing method") if "path" not in api: errors.append(f"API {api.get('id', 'unknown')} missing path") return errors def validate_tables(tables: list) -> list: """Validate database table entities.""" errors = [] for table in tables: if "id" not in table: errors.append(f"Table missing id: {table}") if "name" not in table: errors.append(f"Table {table.get('id', 'unknown')} missing name") if "columns" not in table: errors.append(f"Table {table.get('id', 'unknown')} missing columns") return errors def main(): parser = argparse.ArgumentParser(description="Validate project manifest") parser.add_argument("--strict", action="store_true", help="Treat warnings as errors") parser.add_argument("--manifest", default="project_manifest.json", help="Path to manifest") args = parser.parse_args() manifest_path = args.manifest if not os.path.isabs(manifest_path): manifest_path = os.path.join(os.getcwd(), manifest_path) if not os.path.exists(manifest_path): print(f"Error: Manifest not found at {manifest_path}") return 1 with open(manifest_path) as f: manifest = json.load(f) errors = [] warnings = [] # Structure validation errors.extend(validate_structure(manifest)) if "entities" in manifest: errors.extend(validate_pages(manifest["entities"].get("pages", []))) errors.extend(validate_components(manifest["entities"].get("components", []))) errors.extend(validate_apis(manifest["entities"].get("api_endpoints", []))) errors.extend(validate_tables(manifest["entities"].get("database_tables", []))) # Report results if errors: print("VALIDATION FAILED") for error in errors: print(f" ERROR: {error}") return 1 if warnings: print("VALIDATION PASSED WITH WARNINGS") for warning in warnings: print(f" WARNING: {warning}") if args.strict: return 1 return 0 print("VALIDATION PASSED") return 0 if __name__ == "__main__": exit(main())