mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #3605 from Alexander-Wilms/json5-validation
Simplify validation of JSON with comments & CI ccache fix for feature branches in forks
This commit is contained in:
		
							
								
								
									
										8
									
								
								.github/workflows/github.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/github.yml
									
									
									
									
										vendored
									
									
								
							| @@ -124,7 +124,7 @@ jobs: | ||||
|       # 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 | ||||
|         pip3 install jstyleson | ||||
|         python3 CI/linux-qt6/validate_json.py | ||||
|  | ||||
|     - name: Dependencies | ||||
| @@ -134,7 +134,7 @@ jobs: | ||||
|  | ||||
|     # ensure the ccache for each PR is separate so they don't interfere with each other | ||||
|     # fall back to ccache of the vcmi/vcmi repo if no PR-specific ccache is found | ||||
|     - name: Ccache for PRs | ||||
|     - name: ccache for PRs | ||||
|       uses: hendrikmuhs/ccache-action@v1.2 | ||||
|       if: ${{ github.event.number != '' }} | ||||
|       with: | ||||
| @@ -146,9 +146,9 @@ jobs: | ||||
|         max-size: "5G" | ||||
|         verbose: 2 | ||||
|  | ||||
|     - name: Ccache for vcmi/vcmi's develop branch | ||||
|     - name: ccache for everything but PRs | ||||
|       uses: hendrikmuhs/ccache-action@v1.2 | ||||
|       if: ${{ github.event.number == '' && github.ref == 'refs/heads/develop' }} | ||||
|       if: ${{ (github.repository == 'vcmi/vcmi' && github.event.number == '' && github.ref == 'refs/heads/develop') ||  github.repository != 'vcmi/vcmi' }} | ||||
|       with: | ||||
|         key: ${{ matrix.preset }}-no-PR | ||||
|         restore-keys: | | ||||
|   | ||||
| @@ -5,56 +5,24 @@ import sys | ||||
| from pathlib import Path | ||||
| from pprint import pprint | ||||
|  | ||||
| import json5 | ||||
| import jstyleson | ||||
| import yaml | ||||
| # VCMI supports JSON with comments, but not JSON5 | ||||
| import jstyleson  | ||||
|  | ||||
| # '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" | ||||
| validation_failed = False | ||||
|  | ||||
| errors = [] | ||||
| for path in sorted(Path(".").glob("**/*.json")): | ||||
| for path in sorted(Path(".").glob("**/*.json"), key=lambda path: str(path).lower()): | ||||
|     # because path is an object and not a string | ||||
|     path_str = str(path) | ||||
|     if path_str.startswith("."): | ||||
|         continue | ||||
|  | ||||
|     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") | ||||
|             jstyleson.load(file) | ||||
|         print(f"✅ {path_str}") | ||||
|     except Exception as exc: | ||||
|         print(f"Validation of {path_str} failed") | ||||
|         pprint(exc) | ||||
|         print(f"❌ {path_str}: {exc}") | ||||
|         validation_failed = True | ||||
|  | ||||
|         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("The following JSON files are invalid:") | ||||
|     pprint(errors) | ||||
| if validation_failed: | ||||
|     sys.exit(1) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user