Skip to content
This repository was archived by the owner on Dec 2, 2022. It is now read-only.

Commit 20f13a9

Browse files
authored
meta: refactor schema versioning to improve errors (#385)
This greatly improves the quality of the validating error messages. Improvement of error messages comes with a minor downside, as from now on schema validation for meta would not pass on empty files. Users will have to either put real content in meta files to pass schema validation, such as version at least to pass. That was needed for technical reasons as without it the error messages would be considerably less easy to understand. Related: python-jsonschema/jsonschema#1002
1 parent b6b627c commit 20f13a9

File tree

15 files changed

+135
-253
lines changed

15 files changed

+135
-253
lines changed

Taskfile.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ tasks:
5757
- ".github"
5858
- ".vscode"
5959
- data
60-
- f
60+
- f/**
6161
- negative_test
6262
- src/**
6363
- test/**
@@ -70,10 +70,10 @@ tasks:
7070
- npm run test
7171
- task: summary
7272
sources:
73-
- f/
74-
- negative_test/
75-
- test/
76-
- src/
73+
- f/**
74+
- negative_test/**
75+
- test/**
76+
- src/**
7777
- package.json
7878
- package-lock.json
7979
- Taskfile.yml

f/ansible-meta.json

+26-11
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,9 @@
13231323
"const": 1
13241324
}
13251325
},
1326-
"title": "Meta Schema v1 (standalone role)"
1326+
"required": ["version"],
1327+
"title": "Meta Schema v1 (standalone role)",
1328+
"type": "object"
13271329
},
13281330
"v2": {
13291331
"additionalProperties": false,
@@ -1349,7 +1351,8 @@
13491351
"const": 2
13501352
}
13511353
},
1352-
"title": "Meta Schema v2 (role inside collection)"
1354+
"title": "Meta Schema v2 (role inside collection)",
1355+
"type": "object"
13531356
},
13541357
"vCenterPlatformModel": {
13551358
"properties": {
@@ -1392,14 +1395,26 @@
13921395
},
13931396
"$id": "https://raw.githubusercontent.com/ansible/schemas/main/f/ansible-meta.json",
13941397
"$schema": "http://json-schema.org/draft-07/schema",
1395-
"anyOf": [
1396-
{
1397-
"$ref": "#/$defs/v1"
1398-
},
1399-
{
1400-
"$ref": "#/$defs/v2"
1401-
}
1402-
],
1398+
"else": {
1399+
"$ref": "#/$defs/v2"
1400+
},
14031401
"examples": ["meta/main.yml"],
1404-
"title": "Ansible Meta Schema v1/v2"
1402+
"if": {
1403+
"properties": {
1404+
"version": {
1405+
"const": 1
1406+
}
1407+
}
1408+
},
1409+
"properties": {
1410+
"version": {
1411+
"enum": [1, 2],
1412+
"type": "integer"
1413+
}
1414+
},
1415+
"then": {
1416+
"$ref": "#/$defs/v1"
1417+
},
1418+
"title": "Ansible Meta Schema v1/v2",
1419+
"type": "object"
14051420
}

negative_test/roles/empty_meta/meta/main.yml

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# ajv errors
2+
3+
```json
4+
[
5+
{
6+
"instancePath": "",
7+
"keyword": "type",
8+
"message": "must be object",
9+
"params": {
10+
"type": "object"
11+
},
12+
"schemaPath": "#/type"
13+
},
14+
{
15+
"instancePath": "",
16+
"keyword": "if",
17+
"message": "must match \"then\" schema",
18+
"params": {
19+
"failingKeyword": "then"
20+
},
21+
"schemaPath": "#/if"
22+
},
23+
{
24+
"instancePath": "",
25+
"keyword": "type",
26+
"message": "must be object",
27+
"params": {
28+
"type": "object"
29+
},
30+
"schemaPath": "#/type"
31+
}
32+
]
33+
```
34+
35+
# check-jsonschema
36+
37+
stdout:
38+
39+
```json
40+
{
41+
"status": "fail",
42+
"errors": [
43+
{
44+
"filename": "negative_test/roles/empty_meta/meta/main.yml",
45+
"path": "$",
46+
"message": "None is not of type 'object'",
47+
"has_sub_errors": false
48+
},
49+
{
50+
"filename": "negative_test/roles/empty_meta/meta/main.yml",
51+
"path": "$",
52+
"message": "None is not of type 'object'",
53+
"has_sub_errors": false
54+
}
55+
],
56+
"parse_errors": []
57+
}
58+
```

negative_test/roles/meta/main.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
version: 1
12
galaxy_info:
23
description: bar
34
min_ansible_version: "2.9"

negative_test/roles/meta/main.yml.md

+8-38
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,13 @@
1212
"schemaPath": "#/properties/galaxy_tags/type"
1313
},
1414
{
15-
"instancePath": "/galaxy_info",
16-
"keyword": "additionalProperties",
17-
"message": "must NOT have additional properties",
18-
"params": {
19-
"additionalProperty": "min_ansible_version"
20-
},
21-
"schemaPath": "#/additionalProperties"
22-
},
23-
{
24-
"instancePath": "/galaxy_info",
25-
"keyword": "additionalProperties",
26-
"message": "must NOT have additional properties",
15+
"instancePath": "",
16+
"keyword": "if",
17+
"message": "must match \"then\" schema",
2718
"params": {
28-
"additionalProperty": "galaxy_tags"
19+
"failingKeyword": "then"
2920
},
30-
"schemaPath": "#/additionalProperties"
31-
},
32-
{
33-
"instancePath": "",
34-
"keyword": "anyOf",
35-
"message": "must match a schema in anyOf",
36-
"params": {},
37-
"schemaPath": "#/anyOf"
21+
"schemaPath": "#/if"
3822
}
3923
]
4024
```
@@ -49,23 +33,9 @@ stdout:
4933
"errors": [
5034
{
5135
"filename": "negative_test/roles/meta/main.yml",
52-
"path": "$",
53-
"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",
54-
"has_sub_errors": true,
55-
"best_match": {
56-
"path": "$.galaxy_info",
57-
"message": "Additional properties are not allowed ('galaxy_tags', 'min_ansible_version' were unexpected)"
58-
},
59-
"sub_errors": [
60-
{
61-
"path": "$.galaxy_info.galaxy_tags",
62-
"message": "'database' is not of type 'array'"
63-
},
64-
{
65-
"path": "$.galaxy_info",
66-
"message": "Additional properties are not allowed ('galaxy_tags', 'min_ansible_version' were unexpected)"
67-
}
68-
]
36+
"path": "$.galaxy_info.galaxy_tags",
37+
"message": "'database' is not of type 'array'",
38+
"has_sub_errors": false
6939
}
7040
],
7141
"parse_errors": []

negative_test/roles/meta_invalid_collection/meta/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
version: 2 # <-- role inside a collection
12
collections:
23
- foo # invalid pattern
34
galaxy_info:
45
description: foo
56
license: bar
6-
min_ansible_version: "2.10"
77
platforms:
88
- name: Fedora
99
versions:

negative_test/roles/meta_invalid_collection/meta/main.yml.md

+8-42
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,13 @@
1212
"schemaPath": "#/$defs/collections/items/pattern"
1313
},
1414
{
15-
"instancePath": "/collections/0",
16-
"keyword": "pattern",
17-
"message": "must match pattern \"^[a-z_]+\\.[a-z_]+$\"",
18-
"params": {
19-
"pattern": "^[a-z_]+\\.[a-z_]+$"
20-
},
21-
"schemaPath": "#/$defs/collections/items/pattern"
22-
},
23-
{
24-
"instancePath": "/galaxy_info",
25-
"keyword": "additionalProperties",
26-
"message": "must NOT have additional properties",
15+
"instancePath": "",
16+
"keyword": "if",
17+
"message": "must match \"else\" schema",
2718
"params": {
28-
"additionalProperty": "min_ansible_version"
19+
"failingKeyword": "else"
2920
},
30-
"schemaPath": "#/additionalProperties"
31-
},
32-
{
33-
"instancePath": "",
34-
"keyword": "anyOf",
35-
"message": "must match a schema in anyOf",
36-
"params": {},
37-
"schemaPath": "#/anyOf"
21+
"schemaPath": "#/if"
3822
}
3923
]
4024
```
@@ -49,27 +33,9 @@ stdout:
4933
"errors": [
5034
{
5135
"filename": "negative_test/roles/meta_invalid_collection/meta/main.yml",
52-
"path": "$",
53-
"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",
54-
"has_sub_errors": true,
55-
"best_match": {
56-
"path": "$.galaxy_info",
57-
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
58-
},
59-
"sub_errors": [
60-
{
61-
"path": "$.collections[0]",
62-
"message": "'foo' does not match '^[a-z_]+\\\\.[a-z_]+$'"
63-
},
64-
{
65-
"path": "$.collections[0]",
66-
"message": "'foo' does not match '^[a-z_]+\\\\.[a-z_]+$'"
67-
},
68-
{
69-
"path": "$.galaxy_info",
70-
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
71-
}
72-
]
36+
"path": "$.collections[0]",
37+
"message": "'foo' does not match '^[a-z_]+\\\\.[a-z_]+$'",
38+
"has_sub_errors": false
7339
}
7440
],
7541
"parse_errors": []

negative_test/roles/meta_invalid_collections/meta/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
version: 2 # <-- role inside a collection
12
collections:
23
- FOO.BAR # invalid pattern, need to use lowercase
34
galaxy_info:
45
description: foo
56
license: bar
6-
min_ansible_version: "2.10"
77
platforms:
88
- name: Fedora
99
versions:

negative_test/roles/meta_invalid_collections/meta/main.yml.md

+8-42
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,13 @@
1212
"schemaPath": "#/$defs/collections/items/pattern"
1313
},
1414
{
15-
"instancePath": "/collections/0",
16-
"keyword": "pattern",
17-
"message": "must match pattern \"^[a-z_]+\\.[a-z_]+$\"",
18-
"params": {
19-
"pattern": "^[a-z_]+\\.[a-z_]+$"
20-
},
21-
"schemaPath": "#/$defs/collections/items/pattern"
22-
},
23-
{
24-
"instancePath": "/galaxy_info",
25-
"keyword": "additionalProperties",
26-
"message": "must NOT have additional properties",
15+
"instancePath": "",
16+
"keyword": "if",
17+
"message": "must match \"else\" schema",
2718
"params": {
28-
"additionalProperty": "min_ansible_version"
19+
"failingKeyword": "else"
2920
},
30-
"schemaPath": "#/additionalProperties"
31-
},
32-
{
33-
"instancePath": "",
34-
"keyword": "anyOf",
35-
"message": "must match a schema in anyOf",
36-
"params": {},
37-
"schemaPath": "#/anyOf"
21+
"schemaPath": "#/if"
3822
}
3923
]
4024
```
@@ -49,27 +33,9 @@ stdout:
4933
"errors": [
5034
{
5135
"filename": "negative_test/roles/meta_invalid_collections/meta/main.yml",
52-
"path": "$",
53-
"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",
54-
"has_sub_errors": true,
55-
"best_match": {
56-
"path": "$.galaxy_info",
57-
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
58-
},
59-
"sub_errors": [
60-
{
61-
"path": "$.collections[0]",
62-
"message": "'FOO.BAR' does not match '^[a-z_]+\\\\.[a-z_]+$'"
63-
},
64-
{
65-
"path": "$.collections[0]",
66-
"message": "'FOO.BAR' does not match '^[a-z_]+\\\\.[a-z_]+$'"
67-
},
68-
{
69-
"path": "$.galaxy_info",
70-
"message": "Additional properties are not allowed ('min_ansible_version' was unexpected)"
71-
}
72-
]
36+
"path": "$.collections[0]",
37+
"message": "'FOO.BAR' does not match '^[a-z_]+\\\\.[a-z_]+$'",
38+
"has_sub_errors": false
7339
}
7440
],
7541
"parse_errors": []

negative_test/roles/meta_invalid_role_namespace/meta/main.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
2+
version: 1 # <-- old standalone role
23
galaxy_info:
34
description: foo
45
min_ansible_version: "2.9"

0 commit comments

Comments
 (0)