From d3d00b9f0e565980d49c38951027624f4146db62 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Fri, 16 Jun 2023 17:13:08 +0700 Subject: [PATCH] Also validate patches on CI --- .github/workflows/validate-json.yml | 3 +- tools/atlas.schema.json | 116 -------------------------- tools/ci/validate_json.py | 31 +++++-- tools/schema/atlas.json | 121 ++++++++++++++++++++++++++++ tools/schema/patch.json | 16 ++++ 5 files changed, 162 insertions(+), 125 deletions(-) delete mode 100644 tools/atlas.schema.json create mode 100644 tools/schema/atlas.json create mode 100644 tools/schema/patch.json diff --git a/.github/workflows/validate-json.yml b/.github/workflows/validate-json.yml index 36674e66..fb903685 100644 --- a/.github/workflows/validate-json.yml +++ b/.github/workflows/validate-json.yml @@ -23,4 +23,5 @@ jobs: - name: Validate run: | pip3 install -r tools/ci/requirements.txt - python3 tools/ci/validate_json.py web/atlas.json tools/atlas.schema.json \ No newline at end of file + python3 tools/ci/validate_json.py web/atlas.json tools/schema/atlas.json + python3 tools/ci/validate_json.py data/patches tools/schema/patch.json \ No newline at end of file diff --git a/tools/atlas.schema.json b/tools/atlas.schema.json deleted file mode 100644 index cf4f764d..00000000 --- a/tools/atlas.schema.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft-07/schema", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer", - "minimum": 0 - } - ], - "description": "The ID of the entry. Usually this is the post ID of the new entry submission." - }, - "name": { - "type": "string", - "description": "The short, descriptive name of the entry." - }, - "description": { - "type": "string", - "description": "The description of the entry. that will also be understood by somebody not familiar with the topic. Usually, the first sentence on Wikipedia is a good example." - }, - "links": { - "type": "object", - "description": "The links related to the entry.", - "properties": { - "subreddit": { - "type": "array", - "description": "Subreddits that's either most relevant to the topic, or that was responsible for creating the artwork, excluding the r/.", - "items": { - "type": "string", - "description": "A subreddit that's either most relevant to the topic, or that was responsible for creating the artwork.", - "pattern": "^[A-Za-z0-9][A-Za-z0-9_]{1,20}$", - "minItems": 1 - } - }, - "website": { - "type": "array", - "description": "URL to websites related to the entry, including the http/https protocol. If you're describing a project, the project's main website would be suitable here.", - "items": { - "type": "string", - "description": "The URL to a website related to the entry.", - "pattern": "^https?://[^\\s/$.?#].[^\\s]*$", - "minItems": 1 - } - }, - "discord": { - "type": "array", - "description": "Invite codes of Discord servers related to the entry (excluding discord.gg/)", - "items": { - "type": "string", - "description": "The invite code of a Discord server related to the entry.", - "minItems": 1 - } - }, - "wiki": { - "type": "array", - "description": "Wiki pages related to the entry.", - "items": { - "type": "string", - "description": "The title of the wiki page related to the entry.", - "minItems": 1 - } - } - }, - "additionalProperties": false - }, - "path": { - "type": "object", - "description": "The path of the entry.", - "patternProperties": { - "^(\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?)(, (\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?))*$": { - "type": "array", - "description": "A period containing the path points.", - "items": { - "type": "array", - "description": "A point.", - "items": { - "type": "number" - }, - "minItems": 2, - "maxItems": 2 - }, - "minItems": 3 - } - }, - "additionalProperties": false, - "minProperties": 1 - }, - "center": { - "type": "object", - "description": "The center of the entry.", - "patternProperties": { - "^(\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?)(, (\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?))*$": { - "type": "array", - "description": "A period containing the center point.", - "items": { - "type": "number", - "description": "A point." - }, - "minItems": 2, - "maxItems": 2 - } - }, - "additionalProperties": false, - "minProperties": 1 - } - }, - "required": ["id", "name", "description", "links", "path", "center"], - "additionalItems": true - } -} \ No newline at end of file diff --git a/tools/ci/validate_json.py b/tools/ci/validate_json.py index a9fc25d5..cf698286 100644 --- a/tools/ci/validate_json.py +++ b/tools/ci/validate_json.py @@ -2,23 +2,38 @@ import sys import json -from jsonschema import validate +from jsonschema import validate, RefResolver +from pathlib import Path, PurePosixPath +import os -atlasPath = "./../../web/atlas.json" +instance_path = "../../web/atlas.json" # path override as 1st param: validate_json.py path_to_file.json if (len(sys.argv) > 1): - atlasPath = sys.argv[1] + instance_path = sys.argv[1] -schemaPath = "./../atlas.schema.json" +schema_path = "../schema/atlas.json" # schema override as 2nd param: validate_json.py [...] path_to_schema.json if (len(sys.argv) > 2): - schemaPath = sys.argv[2] + schema_path = sys.argv[2] -atlas = json.load(open(atlasPath, "r", encoding='utf-8')) -schema = json.load(open(schemaPath, "r", encoding='utf-8')) +relative_path = "file:" + str(PurePosixPath(Path(os.getcwd(), schema_path))) -validate(atlas, schema) +schema = json.load(open(schema_path, "r", encoding='utf-8')) +# exit() + +resolver = RefResolver(relative_path, schema) +if os.path.isdir(instance_path): + for filename in os.listdir(instance_path): + f = os.path.join(instance_path, filename) + print(f) + + instance = json.load(open(f, "r", encoding='utf-8')) + validate(instance, schema, resolver=resolver) +elif os.path.isfile(instance_path): + print(instance_path) + instance = json.load(open(instance_path, "r", encoding='utf-8')) + validate(instance, schema, resolver=resolver) print("JSON is valid") \ No newline at end of file diff --git a/tools/schema/atlas.json b/tools/schema/atlas.json new file mode 100644 index 00000000..ebbcbb18 --- /dev/null +++ b/tools/schema/atlas.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema", + "type": "array", + "definitions": { + "entry": { + "type": "object", + "properties": { + "id": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer", + "minimum": 0 + } + ], + "description": "The ID of the entry. Usually this is the post ID of the new entry submission." + }, + "name": { + "type": "string", + "description": "The short, descriptive name of the entry." + }, + "description": { + "type": "string", + "description": "The description of the entry. that will also be understood by somebody not familiar with the topic. Usually, the first sentence on Wikipedia is a good example." + }, + "links": { + "type": "object", + "description": "The links related to the entry.", + "properties": { + "subreddit": { + "type": "array", + "description": "Subreddits that's either most relevant to the topic, or that was responsible for creating the artwork, excluding the r/.", + "items": { + "type": "string", + "description": "A subreddit that's either most relevant to the topic, or that was responsible for creating the artwork.", + "pattern": "^[A-Za-z0-9][A-Za-z0-9_]{1,20}$", + "minItems": 1 + } + }, + "website": { + "type": "array", + "description": "URL to websites related to the entry, including the http/https protocol. If you're describing a project, the project's main website would be suitable here.", + "items": { + "type": "string", + "description": "The URL to a website related to the entry.", + "pattern": "^https?://[^\\s/$.?#].[^\\s]*$", + "minItems": 1 + } + }, + "discord": { + "type": "array", + "description": "Invite codes of Discord servers related to the entry (excluding discord.gg/)", + "items": { + "type": "string", + "description": "The invite code of a Discord server related to the entry.", + "minItems": 1 + } + }, + "wiki": { + "type": "array", + "description": "Wiki pages related to the entry.", + "items": { + "type": "string", + "description": "The title of the wiki page related to the entry.", + "minItems": 1 + } + } + }, + "additionalProperties": false + }, + "path": { + "type": "object", + "description": "The path of the entry.", + "patternProperties": { + "^(\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?)(, (\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?))*$": { + "type": "array", + "description": "A period containing the path points.", + "items": { + "type": "array", + "description": "A point.", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + }, + "minItems": 3 + } + }, + "additionalProperties": false, + "minProperties": 1 + }, + "center": { + "type": "object", + "description": "The center of the entry.", + "patternProperties": { + "^(\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?)(, (\\d+(-\\d+)?|\\w+(:\\d+(-\\d+)?)?))*$": { + "type": "array", + "description": "A period containing the center point.", + "items": { + "type": "number", + "description": "A point." + }, + "minItems": 2, + "maxItems": 2 + } + }, + "additionalProperties": false, + "minProperties": 1 + } + }, + "required": ["id", "name", "description", "links", "path", "center"], + "additionalItems": true + } + }, + "items": { + "$ref": "#/definitions/entry" + } +} \ No newline at end of file diff --git a/tools/schema/patch.json b/tools/schema/patch.json new file mode 100644 index 00000000..081aa57a --- /dev/null +++ b/tools/schema/patch.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema", + "$ref": "atlas.json#/definitions/entry", + "properties": { + "_author": { + "type": "string", + "description": "Patch only: Author of the entry.", + "minLength": 1 + }, + "_reddit_id": { + "type": "string", + "description": "Patch only: Submission ID, if submitted from Reddit.", + "minLength": 1 + } + } +} \ No newline at end of file