import argparse import json import sys from pathlib import Path from typing import Any, Dict from .validator import SchemaValidator from .errors import ValidationError def load_json_file(file_path: str) -> Dict[str, Any]: """Load JSON data from file. Args: file_path: Path to JSON file Returns: Parsed JSON data Raises: SystemExit: If file cannot be loaded or parsed """ try: with open(file_path, 'r', encoding='utf-8') as f: return json.load(f) except FileNotFoundError: print(f"Error: File '{file_path}' not found.", file=sys.stderr) sys.exit(1) except json.JSONDecodeError as e: print(f"Error: Invalid JSON in file '{file_path}': {e}", file=sys.stderr) sys.exit(1) except Exception as e: print(f"Error: Failed to read file '{file_path}': {e}", file=sys.stderr) sys.exit(1) def format_validation_results(errors: list, data_file: str) -> str: """Format validation results for output. Args: errors: List of ValidationError objects data_file: Name of the data file being validated Returns: Formatted validation results """ if not errors: return f"✓ Validation successful: '{data_file}' is valid according to the schema." result = f"✗ Validation failed: '{data_file}' has {len(errors)} error(s):\n\n" for i, error in enumerate(errors, 1): result += f"{i}. {error}\n" return result def main(): """Main CLI entry point.""" parser = argparse.ArgumentParser( description="JSON Schema Validator - Validate JSON data against a schema" ) parser.add_argument( "--schema", required=True, help="Path to JSON schema file" ) parser.add_argument( "--data", required=True, help="Path to JSON data file to validate" ) parser.add_argument( "--format", choices=["human", "json"], default="human", help="Output format (default: human)" ) args = parser.parse_args() # Load schema and data files schema = load_json_file(args.schema) data = load_json_file(args.data) # Create validator and perform validation try: validator = SchemaValidator(schema) errors = validator.validate(data) # Output results based on format if args.format == "json": result = { "valid": len(errors) == 0, "errors": [error.to_dict() for error in errors] } print(json.dumps(result, indent=2)) else: print(format_validation_results(errors, args.data)) # Exit with appropriate code sys.exit(0 if len(errors) == 0 else 1) except Exception as e: print(f"Error during validation: {e}", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main()