75 lines
2.1 KiB
Python
75 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
JSON Config Validator - Validates and pretty-prints JSON files
|
|
Usage: python3 json_config_validator.py <file.json>
|
|
Exit codes: 0=valid, 1=invalid, 2=file not found
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def validate_json_file(filepath: str) -> tuple[bool, str, dict | None, str]:
|
|
"""Validate a JSON file and return (is_valid, pretty_json, data, error_msg)."""
|
|
p = Path(filepath)
|
|
|
|
if not p.exists():
|
|
return False, "", None, f"File not found: {filepath}"
|
|
|
|
try:
|
|
with open(p, 'r') as f:
|
|
data = json.load(f)
|
|
pretty = json.dumps(data, indent=2, sort_keys=True)
|
|
return True, pretty, data, ""
|
|
except json.JSONDecodeError as e:
|
|
return False, "", None, f"JSON error at line {e.lineno}, column {e.colno}: {e.msg}"
|
|
except Exception as e:
|
|
return False, "", None, str(e)
|
|
|
|
|
|
def extract_schema_info(data: dict) -> dict:
|
|
"""Extract basic schema info from JSON data."""
|
|
if not isinstance(data, dict):
|
|
return {"type": type(data).__name__, "keys": [] if isinstance(data, list) else None}
|
|
|
|
keys = list(data.keys())
|
|
types = {k: type(v).__name__ for k, v in data.items()}
|
|
|
|
return {
|
|
"type": "object",
|
|
"key_count": len(keys),
|
|
"keys": keys,
|
|
"value_types": types
|
|
}
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("Usage: json_config_validator.py <file.json>", file=sys.stderr)
|
|
sys.exit(2)
|
|
|
|
filepath = sys.argv[1]
|
|
is_valid, pretty, data, error = validate_json_file(filepath)
|
|
|
|
if not is_valid:
|
|
print(f"INVALID: {error}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
print(f"VALID: {filepath}")
|
|
print(f"Size: {len(pretty)} bytes, {len(data) if isinstance(data, dict) else len(data) if isinstance(data, list) else 1} top-level items")
|
|
print()
|
|
print("CONTENT:")
|
|
print(pretty)
|
|
|
|
if isinstance(data, dict):
|
|
schema = extract_schema_info(data)
|
|
print()
|
|
print("SCHEMA INFO:")
|
|
print(json.dumps(schema, indent=2, sort_keys=True))
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |