Browse Source

Merge pull request #2842 from Alexander-Wilms/develop

Add JSON validation as a CI stage
Ivan Savenko 2 years ago
parent
commit
c6a86d9a5f
2 changed files with 67 additions and 0 deletions
  1. 59 0
      .github/validate_json.py
  2. 8 0
      .github/workflows/github.yml

+ 59 - 0
.github/validate_json.py

@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+import re
+from pathlib import Path
+from pprint import pprint
+
+import json5
+import jstyleson
+import yaml
+
+# 'json', 'json5' or 'yaml'
+# json:  strict, but doesn't preserve line numbers necessarily, since it strips comments before parsing
+# json5: strict and preserves line numbers even for files with line comments
+# yaml:  less strict, allows e.g. leading zeros
+VALIDATION_TYPE = 'json5'
+
+errors = []
+for path in sorted(Path('.').glob('**/*.json')):
+    # because path is an object and not a string
+    path_str = str(path)
+    try:
+        with open(path_str, 'r') as file:
+            if VALIDATION_TYPE == 'json':
+                jstyleson.load(file)
+            elif VALIDATION_TYPE == 'json5':
+                json5.load(file)
+            elif VALIDATION_TYPE == 'yaml':
+                file = file.read().replace("\t", "    ")
+                file = file.replace("//", "#")
+                yaml.safe_load(file)
+        print(f"Validation of {path_str} succeeded")
+    except Exception as exc:
+        print(f"Validation of {path_str} failed")
+        pprint(exc)
+
+        error_pos = path_str
+
+        # create error position strings for each type of parser
+        if hasattr(exc, 'pos'):
+            # 'json'
+            # https://stackoverflow.com/a/72850269/2278742
+            error_pos = f"{path_str}:{exc.lineno}:{exc.colno}"
+            print(error_pos)
+        elif VALIDATION_TYPE == 'json5':
+            # 'json5'
+            pos = re.findall(r'\d+', str(exc))
+            error_pos = f"{path_str}:{pos[0]}:{pos[-1]}"
+        elif hasattr(exc, 'problem_mark'):
+            # 'yaml'
+            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})
+
+if errors:
+    print("Summary of errors:")
+    pprint(errors)
+    raise Exception("Not all JSON files are valid")

+ 8 - 0
.github/workflows/github.yml

@@ -145,6 +145,14 @@ jobs:
       with:
         submodules: recursive
 
+    - name: Validate JSON
+      # the Python yaml module doesn't seem to work on mac-arm
+      # also, running it on multiple presets is redundant and slightly increases already long CI built times
+      if: ${{ startsWith(matrix.preset, 'linux-clang-test') }}
+      run: |
+        pip3 install json5 jstyleson
+        python3 .github/validate_json.py
+
     - name: Dependencies
       run: source '${{github.workspace}}/CI/${{matrix.platform}}/before_install.sh'
       env: