Skip to content

Commit

Permalink
meta: refactor schema versioning to improve errors
Browse files Browse the repository at this point in the history
This greatly improves the quality of the validating error messages.

Related: python-jsonschema/jsonschema#1002
  • Loading branch information
ssbarnea committed Sep 14, 2022
1 parent b6b627c commit a2f1194
Show file tree
Hide file tree
Showing 15 changed files with 193 additions and 252 deletions.
10 changes: 5 additions & 5 deletions Taskfile.yml
Expand Up @@ -57,7 +57,7 @@ tasks:
- ".github"
- ".vscode"
- data
- f
- f/**
- negative_test
- src/**
- test/**
Expand All @@ -70,10 +70,10 @@ tasks:
- npm run test
- task: summary
sources:
- f/
- negative_test/
- test/
- src/
- f/**
- negative_test/**
- test/**
- src/**
- package.json
- package-lock.json
- Taskfile.yml
Expand Down
37 changes: 26 additions & 11 deletions f/ansible-meta.json
Expand Up @@ -1323,7 +1323,9 @@
"const": 1
}
},
"title": "Meta Schema v1 (standalone role)"
"required": ["version"],
"title": "Meta Schema v1 (standalone role)",
"type": "object"
},
"v2": {
"additionalProperties": false,
Expand All @@ -1349,7 +1351,8 @@
"const": 2
}
},
"title": "Meta Schema v2 (role inside collection)"
"title": "Meta Schema v2 (role inside collection)",
"type": "object"
},
"vCenterPlatformModel": {
"properties": {
Expand Down Expand Up @@ -1392,14 +1395,26 @@
},
"$id": "https://raw.githubusercontent.com/ansible/schemas/main/f/ansible-meta.json",
"$schema": "http://json-schema.org/draft-07/schema",
"anyOf": [
{
"$ref": "#/$defs/v1"
},
{
"$ref": "#/$defs/v2"
}
],
"else": {
"$ref": "#/$defs/v2"
},
"examples": ["meta/main.yml"],
"title": "Ansible Meta Schema v1/v2"
"if": {
"properties": {
"version": {
"const": 1
}
}
},
"properties": {
"version": {
"enum": [1, 2],
"type": "integer"
}
},
"then": {
"$ref": "#/$defs/v1"
},
"title": "Ansible Meta Schema v1/v2",
"type": "object"
}
Empty file.
58 changes: 58 additions & 0 deletions negative_test/roles/empty_meta/meta/main.yml.md
@@ -0,0 +1,58 @@
# ajv errors

```json
[
{
"instancePath": "",
"keyword": "type",
"message": "must be object",
"params": {
"type": "object"
},
"schemaPath": "#/type"
},
{
"instancePath": "",
"keyword": "if",
"message": "must match \"then\" schema",
"params": {
"failingKeyword": "then"
},
"schemaPath": "#/if"
},
{
"instancePath": "",
"keyword": "type",
"message": "must be object",
"params": {
"type": "object"
},
"schemaPath": "#/type"
}
]
```

# check-jsonschema

stdout:

```json
{
"status": "fail",
"errors": [
{
"filename": "negative_test/roles/empty_meta/meta/main.yml",
"path": "$",
"message": "None is not of type 'object'",
"has_sub_errors": false
},
{
"filename": "negative_test/roles/empty_meta/meta/main.yml",
"path": "$",
"message": "None is not of type 'object'",
"has_sub_errors": false
}
],
"parse_errors": []
}
```
1 change: 1 addition & 0 deletions negative_test/roles/meta/main.yml
@@ -1,3 +1,4 @@
version: 1
galaxy_info:
description: bar
min_ansible_version: "2.9"
Expand Down
46 changes: 8 additions & 38 deletions negative_test/roles/meta/main.yml.md
Expand Up @@ -12,29 +12,13 @@
"schemaPath": "#/properties/galaxy_tags/type"
},
{
"instancePath": "/galaxy_info",
"keyword": "additionalProperties",
"message": "must NOT have additional properties",
"params": {
"additionalProperty": "min_ansible_version"
},
"schemaPath": "#/additionalProperties"
},
{
"instancePath": "/galaxy_info",
"keyword": "additionalProperties",
"message": "must NOT have additional properties",
"instancePath": "",
"keyword": "if",
"message": "must match \"then\" schema",
"params": {
"additionalProperty": "galaxy_tags"
"failingKeyword": "then"
},
"schemaPath": "#/additionalProperties"
},
{
"instancePath": "",
"keyword": "anyOf",
"message": "must match a schema in anyOf",
"params": {},
"schemaPath": "#/anyOf"
"schemaPath": "#/if"
}
]
```
Expand All @@ -49,23 +33,9 @@ stdout:
"errors": [
{
"filename": "negative_test/roles/meta/main.yml",
"path": "$",
"message": "{'galaxy_info': {'description': 'bar', 'min_ansible_version': '2.9', 'company': 'foo', 'license': 'MIT', 'galaxy_tags': 'database', 'platforms': [{'name': 'Alpine', 'versions': ['all']}]}} is not valid under any of the given schemas",
"has_sub_errors": true,
"best_match": {
"path": "$.galaxy_info",
"message": "Additional properties are not allowed ('galaxy_tags', 'min_ansible_version' were unexpected)"
},
"sub_errors": [
{
"path": "$.galaxy_info.galaxy_tags",
"message": "'database' is not of type 'array'"
},
{
"path": "$.galaxy_info",
"message": "Additional properties are not allowed ('galaxy_tags', 'min_ansible_version' were unexpected)"
}
]
"path": "$.galaxy_info.galaxy_tags",
"message": "'database' is not of type 'array'",
"has_sub_errors": false
}
],
"parse_errors": []
Expand Down
2 changes: 1 addition & 1 deletion negative_test/roles/meta_invalid_collection/meta/main.yml
@@ -1,9 +1,9 @@
version: 2 # <-- role inside a collection
collections:
- foo # invalid pattern
galaxy_info:
description: foo
license: bar
min_ansible_version: "2.10"
platforms:
- name: Fedora
versions:
Expand Down
50 changes: 8 additions & 42 deletions negative_test/roles/meta_invalid_collection/meta/main.yml.md
Expand Up @@ -12,29 +12,13 @@
"schemaPath": "#/$defs/collections/items/pattern"
},
{
"instancePath": "/collections/0",
"keyword": "pattern",
"message": "must match pattern \"^[a-z_]+\\.[a-z_]+$\"",
"params": {
"pattern": "^[a-z_]+\\.[a-z_]+$"
},
"schemaPath": "#/$defs/collections/items/pattern"
},
{
"instancePath": "/galaxy_info",
"keyword": "additionalProperties",
"message": "must NOT have additional properties",
"instancePath": "",
"keyword": "if",
"message": "must match \"else\" schema",
"params": {
"additionalProperty": "min_ansible_version"
"failingKeyword": "else"
},
"schemaPath": "#/additionalProperties"
},
{
"instancePath": "",
"keyword": "anyOf",
"message": "must match a schema in anyOf",
"params": {},
"schemaPath": "#/anyOf"
"schemaPath": "#/if"
}
]
```
Expand All @@ -49,27 +33,9 @@ stdout:
"errors": [
{
"filename": "negative_test/roles/meta_invalid_collection/meta/main.yml",
"path": "$",
"message": "{'collections': ['foo'], 'galaxy_info': {'description': 'foo', 'license': 'bar', 'min_ansible_version': '2.10', 'platforms': [{'name': 'Fedora', 'versions': ['all']}]}} is not valid under any of the given schemas",
"has_sub_errors": true,
"best_match": {
"path": "$.galaxy_info",
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
},
"sub_errors": [
{
"path": "$.collections[0]",
"message": "'foo' does not match '^[a-z_]+\\\\.[a-z_]+$'"
},
{
"path": "$.collections[0]",
"message": "'foo' does not match '^[a-z_]+\\\\.[a-z_]+$'"
},
{
"path": "$.galaxy_info",
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
}
]
"path": "$.collections[0]",
"message": "'foo' does not match '^[a-z_]+\\\\.[a-z_]+$'",
"has_sub_errors": false
}
],
"parse_errors": []
Expand Down
2 changes: 1 addition & 1 deletion negative_test/roles/meta_invalid_collections/meta/main.yml
@@ -1,9 +1,9 @@
version: 2 # <-- role inside a collection
collections:
- FOO.BAR # invalid pattern, need to use lowercase
galaxy_info:
description: foo
license: bar
min_ansible_version: "2.10"
platforms:
- name: Fedora
versions:
Expand Down
50 changes: 8 additions & 42 deletions negative_test/roles/meta_invalid_collections/meta/main.yml.md
Expand Up @@ -12,29 +12,13 @@
"schemaPath": "#/$defs/collections/items/pattern"
},
{
"instancePath": "/collections/0",
"keyword": "pattern",
"message": "must match pattern \"^[a-z_]+\\.[a-z_]+$\"",
"params": {
"pattern": "^[a-z_]+\\.[a-z_]+$"
},
"schemaPath": "#/$defs/collections/items/pattern"
},
{
"instancePath": "/galaxy_info",
"keyword": "additionalProperties",
"message": "must NOT have additional properties",
"instancePath": "",
"keyword": "if",
"message": "must match \"else\" schema",
"params": {
"additionalProperty": "min_ansible_version"
"failingKeyword": "else"
},
"schemaPath": "#/additionalProperties"
},
{
"instancePath": "",
"keyword": "anyOf",
"message": "must match a schema in anyOf",
"params": {},
"schemaPath": "#/anyOf"
"schemaPath": "#/if"
}
]
```
Expand All @@ -49,27 +33,9 @@ stdout:
"errors": [
{
"filename": "negative_test/roles/meta_invalid_collections/meta/main.yml",
"path": "$",
"message": "{'collections': ['FOO.BAR'], 'galaxy_info': {'description': 'foo', 'license': 'bar', 'min_ansible_version': '2.10', 'platforms': [{'name': 'Fedora', 'versions': ['all']}]}} is not valid under any of the given schemas",
"has_sub_errors": true,
"best_match": {
"path": "$.galaxy_info",
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
},
"sub_errors": [
{
"path": "$.collections[0]",
"message": "'FOO.BAR' does not match '^[a-z_]+\\\\.[a-z_]+$'"
},
{
"path": "$.collections[0]",
"message": "'FOO.BAR' does not match '^[a-z_]+\\\\.[a-z_]+$'"
},
{
"path": "$.galaxy_info",
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
}
]
"path": "$.collections[0]",
"message": "'FOO.BAR' does not match '^[a-z_]+\\\\.[a-z_]+$'",
"has_sub_errors": false
}
],
"parse_errors": []
Expand Down
@@ -1,4 +1,5 @@
---
version: 1 # <-- old standalone role
galaxy_info:
description: foo
min_ansible_version: "2.9"
Expand Down

0 comments on commit a2f1194

Please sign in to comment.