2023-09-16 13:18:09 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2023-09-16 01:52:04 +02:00
|
|
|
import re
|
2023-10-27 15:33:38 +02:00
|
|
|
import sys
|
2023-09-15 22:55:48 +02:00
|
|
|
from pathlib import Path
|
|
|
|
from pprint import pprint
|
2023-09-16 01:52:04 +02:00
|
|
|
|
2023-09-16 01:31:43 +02:00
|
|
|
import json5
|
2023-09-16 01:52:04 +02:00
|
|
|
import jstyleson
|
|
|
|
import yaml
|
2023-09-16 01:31:43 +02:00
|
|
|
|
|
|
|
# 'json', 'json5' or 'yaml'
|
|
|
|
# json: strict, but doesn't preserve line numbers necessarily, since it strips comments before parsing
|
2023-09-16 01:52:04 +02:00
|
|
|
# json5: strict and preserves line numbers even for files with line comments
|
2023-09-16 01:31:43 +02:00
|
|
|
# yaml: less strict, allows e.g. leading zeros
|
2023-10-27 15:30:35 +02:00
|
|
|
VALIDATION_TYPE = "json5"
|
2023-09-15 22:55:48 +02:00
|
|
|
|
|
|
|
errors = []
|
2023-10-27 15:30:35 +02:00
|
|
|
for path in sorted(Path(".").glob("**/*.json")):
|
2023-09-15 22:55:48 +02:00
|
|
|
# because path is an object and not a string
|
|
|
|
path_str = str(path)
|
|
|
|
try:
|
2023-10-27 15:30:35 +02:00
|
|
|
with open(path_str, "r") as file:
|
|
|
|
if VALIDATION_TYPE == "json":
|
2023-09-16 01:31:43 +02:00
|
|
|
jstyleson.load(file)
|
2023-10-27 15:30:35 +02:00
|
|
|
elif VALIDATION_TYPE == "json5":
|
2023-09-16 01:31:43 +02:00
|
|
|
json5.load(file)
|
2023-10-27 15:30:35 +02:00
|
|
|
elif VALIDATION_TYPE == "yaml":
|
2023-09-16 01:31:43 +02:00
|
|
|
file = file.read().replace("\t", " ")
|
|
|
|
file = file.replace("//", "#")
|
|
|
|
yaml.safe_load(file)
|
2023-09-15 22:55:48 +02:00
|
|
|
print(f"Validation of {path_str} succeeded")
|
|
|
|
except Exception as exc:
|
|
|
|
print(f"Validation of {path_str} failed")
|
|
|
|
pprint(exc)
|
2023-09-16 01:31:43 +02:00
|
|
|
|
|
|
|
error_pos = path_str
|
|
|
|
|
2023-09-16 13:18:09 +02:00
|
|
|
# create error position strings for each type of parser
|
2023-10-27 15:30:35 +02:00
|
|
|
if hasattr(exc, "pos"):
|
2023-09-16 13:18:09 +02:00
|
|
|
# 'json'
|
2023-09-16 01:31:43 +02:00
|
|
|
# https://stackoverflow.com/a/72850269/2278742
|
|
|
|
error_pos = f"{path_str}:{exc.lineno}:{exc.colno}"
|
|
|
|
print(error_pos)
|
2023-10-27 15:30:35 +02:00
|
|
|
elif VALIDATION_TYPE == "json5":
|
2023-09-16 13:18:09 +02:00
|
|
|
# 'json5'
|
2023-10-27 15:30:35 +02:00
|
|
|
pos = re.findall(r"\d+", str(exc))
|
2023-09-16 13:18:09 +02:00
|
|
|
error_pos = f"{path_str}:{pos[0]}:{pos[-1]}"
|
2023-10-27 15:30:35 +02:00
|
|
|
elif hasattr(exc, "problem_mark"):
|
2023-09-16 13:18:09 +02:00
|
|
|
# 'yaml'
|
2023-09-16 01:31:43 +02:00
|
|
|
mark = exc.problem_mark
|
|
|
|
error_pos = f"{path_str}:{mark.line+1}:{mark.column+1}"
|
|
|
|
print(error_pos)
|
|
|
|
|
|
|
|
errors.append({"error_pos": error_pos, "error_msg": exc})
|
2023-09-15 22:55:48 +02:00
|
|
|
|
|
|
|
if errors:
|
2023-10-27 15:33:38 +02:00
|
|
|
print("The following JSON files are invalid:")
|
2023-09-15 22:55:48 +02:00
|
|
|
pprint(errors)
|
2023-10-27 15:33:38 +02:00
|
|
|
sys.exit(1)
|