diff --git a/Makefile b/Makefile index 3c1f6eaf..d00081b8 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,7 @@ .DEFAULT_GOAL := all JSONSCHEMA ?= ./node_modules/@sourcemeta/jsonschema/npm/cli.js -JQ ?= jq SHELLCHECK ?= shellcheck -MKDIRP ?= mkdir -p NODE ?= node NPM ?= npm TIME ?= time @@ -11,21 +9,20 @@ TIME ?= time include generated.mk all: common test node_modules - $(NODE) $(JSONSCHEMA) fmt schemas meta test + $(NODE) $(JSONSCHEMA) fmt schemas meta rules test .PHONY: common common: $(GENERATED) node_modules - $(TIME) $(NODE) $(JSONSCHEMA) metaschema schemas meta + $(TIME) $(NODE) $(JSONSCHEMA) metaschema schemas meta rules $(TIME) $(NODE) $(JSONSCHEMA) lint schemas meta $(TIME) $(NODE) $(JSONSCHEMA) validate meta/schemas-root.json schemas - $(TIME) $(NODE) $(JSONSCHEMA) validate meta/schemas.json schemas $(SHELLCHECK) scripts/*.sh ./scripts/quality-schemas-tests-mirror.sh ./scripts/quality-templates-xbrl-utr-mirror.sh .PHONY: lint lint: common node_modules - $(TIME) $(NODE) $(JSONSCHEMA) fmt schemas meta test --check + $(TIME) $(NODE) $(JSONSCHEMA) fmt schemas meta rules test --check .PHONY: test test: node_modules diff --git a/generated.mk b/generated.mk index cc072428..cf656f9d 100644 --- a/generated.mk +++ b/generated.mk @@ -1,4 +1,6 @@ PYTHON ?= python3 +MKDIRP ?= mkdir -p +JQ ?= jq define MAKE_SCHEMA schemas/$1.json: templates/schemas/$1.jq $2.json node_modules diff --git a/jsonschema.json b/jsonschema.json index b901b358..c2c64519 100644 --- a/jsonschema.json +++ b/jsonschema.json @@ -6,5 +6,16 @@ "path": "./schemas", "resolve": { "urn:sourcemeta:std:ietf:jsonschema:2020-12:dialect:format-assertion": "./schemas/2020-12/ietf/jsonschema/2020-12/dialect/format-assertion.json" + }, + "lint": { + "rules": [ + "./rules/comment.json", + "./rules/dialect.json", + "./rules/identifiers.json", + "./rules/license.json", + "./rules/links.json", + "./rules/single-line-text.json", + "./rules/symbol.json" + ] } } diff --git a/meta/schemas-root.json b/meta/schemas-root.json index e47c2474..7096546f 100644 --- a/meta/schemas-root.json +++ b/meta/schemas-root.json @@ -7,54 +7,19 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Example Schema", "description": "An example schema conforming to the root meta-schema", - "examples": [ "example value" ], + "examples": [ "foo", "bar", "baz" ], "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", "x-links": [ "https://example.com" ], "type": "string" } ], - "x-lint-exclude": "simple_properties_identifiers", + "x-lint-exclude": "required_properties_in_properties", "type": "object", - "if": { - "properties": { - "const": true - } - }, - "else": { - "required": [ "examples" ], - "properties": { - "examples": { - "type": "array", - "minItems": 3 - } - } - }, - "required": [ "x-license", "x-links", "$schema" ], + "required": [ "$schema", "examples", "x-license", "x-links" ], "properties": { - "$schema": { - "enum": [ - "https://json-schema.org/draft/2020-12/schema", - "urn:sourcemeta:std:ietf:jsonschema:2020-12:dialect:format-assertion" - ] - }, - "$comment": { - "not": { - "$ref": "../schemas/2020-12/ietf/uri/uri-reference.json" - } - }, - "x-license": { - "const": "https://github.com/sourcemeta/std/blob/main/LICENSE" - }, - "x-symbol": { - "type": "string" - }, - "x-links": { + "examples": { "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "$ref": "../schemas/2020-12/ietf/http/https-url.json" - } + "minItems": 1 } } } diff --git a/rules/comment.json b/rules/comment.json new file mode 100644 index 00000000..39e4db02 --- /dev/null +++ b/rules/comment.json @@ -0,0 +1,12 @@ +{ + "$schema": "urn:sourcemeta:std:ietf:jsonschema:2020-12:dialect:format-assertion", + "title": "std/comment", + "description": "Comments must be prose and not URI references", + "properties": { + "$comment": { + "not": { + "format": "uri-reference" + } + } + } +} diff --git a/rules/dialect.json b/rules/dialect.json new file mode 100644 index 00000000..c7314fb9 --- /dev/null +++ b/rules/dialect.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "std/dialect", + "description": "Schemas must be written in the 2020-12 dialect or in one of the dialect variants of this collection", + "properties": { + "$schema": { + "enum": [ + "https://json-schema.org/draft/2020-12/schema", + "urn:sourcemeta:std:ietf:jsonschema:2020-12:dialect:format-assertion" + ] + } + } +} diff --git a/rules/identifiers.json b/rules/identifiers.json new file mode 100644 index 00000000..bb60ec32 --- /dev/null +++ b/rules/identifiers.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "std/identifiers", + "description": "Schemas must not declare identifiers, as the registry derives them from file paths", + "properties": { + "$id": false + } +} diff --git a/rules/license.json b/rules/license.json new file mode 100644 index 00000000..c3993eb0 --- /dev/null +++ b/rules/license.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "std/license", + "description": "The license must point to the official license of the collection", + "properties": { + "x-license": { + "const": "https://github.com/sourcemeta/std/blob/main/LICENSE" + } + } +} diff --git a/rules/links.json b/rules/links.json new file mode 100644 index 00000000..b5c245a9 --- /dev/null +++ b/rules/links.json @@ -0,0 +1,17 @@ +{ + "$schema": "urn:sourcemeta:std:ietf:jsonschema:2020-12:dialect:format-assertion", + "title": "std/links", + "description": "Links must be a non-empty array of unique HTTPS URLs", + "properties": { + "x-links": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^https://", + "format": "uri" + } + } + } +} diff --git a/meta/schemas.json b/rules/single-line-text.json similarity index 54% rename from meta/schemas.json rename to rules/single-line-text.json index 0cb31f30..47bc9ab4 100644 --- a/meta/schemas.json +++ b/rules/single-line-text.json @@ -1,28 +1,16 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$dynamicAnchor": "meta", - "title": "Schema meta-schema", - "description": "Meta-schema for validating all schemas", - "examples": [ - { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Example Schema", - "description": "An example valid schema", - "type": "string" - } - ], - "x-lint-exclude": "simple_properties_identifiers", - "$ref": "https://json-schema.org/draft/2020-12/schema", + "title": "std/single_line_text", + "description": "Titles, descriptions, and comments must be single-line prose without trailing punctuation", "properties": { - "$id": false, - "$comment": { - "$ref": "#/$defs/single-line-text" - }, "title": { "$ref": "#/$defs/single-line-text" }, "description": { "$ref": "#/$defs/single-line-text" + }, + "$comment": { + "$ref": "#/$defs/single-line-text" } }, "$defs": { diff --git a/rules/symbol.json b/rules/symbol.json new file mode 100644 index 00000000..1372f3ca --- /dev/null +++ b/rules/symbol.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "std/symbol", + "description": "Symbols must be non-empty strings", + "properties": { + "x-symbol": { + "type": "string", + "minLength": 1 + } + } +}