scripts: replace pykwalify with jsonschema

Converted `arch-schema.yml`, `board-schema.yml`, and `soc-schema.yml`
from PyYAML format to JSON Schema format, including baking in some of
the validation rules that were deferred to ad hoc Python right into the
schemas (e.g. mutual exclusivity of certain fields).

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
This commit is contained in:
Benjamin Cabé
2025-08-26 16:17:41 +02:00
committed by Chris Friedt
parent d7a5d84b1c
commit 8f4b253ac8
11 changed files with 676 additions and 387 deletions

View File

@@ -11,9 +11,10 @@ from collections import Counter, defaultdict
from dataclasses import dataclass, field
from pathlib import Path
import jsonschema
import list_hardware
import pykwalify.core
import yaml
from jsonschema.exceptions import best_match
from list_hardware import unique_paths
try:
@@ -21,11 +22,13 @@ try:
except ImportError:
from yaml import SafeLoader
BOARD_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'board-schema.yml')
BOARD_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'board-schema.yaml')
with open(BOARD_SCHEMA_PATH) as f:
board_schema = yaml.load(f.read(), Loader=SafeLoader)
BOARD_VALIDATOR = pykwalify.core.Core(schema_data=board_schema, source_data={})
validator_class = jsonschema.validators.validator_for(board_schema)
validator_class.check_schema(board_schema)
board_validator = validator_class(board_schema)
BOARD_YML = 'board.yml'
@@ -231,23 +234,14 @@ def load_v2_boards(board_name, board_yml, systems):
with board_yml.open('r', encoding='utf-8') as f:
b = yaml.load(f.read(), Loader=SafeLoader)
try:
BOARD_VALIDATOR.source = b
BOARD_VALIDATOR.validate()
except pykwalify.errors.SchemaError as e:
sys.exit(f'ERROR: Malformed "build" section in file: {board_yml.as_posix()}\n{e}')
mutual_exclusive = {'board', 'boards'}
if len(mutual_exclusive - b.keys()) < 1:
sys.exit(f'ERROR: Malformed content in file: {board_yml.as_posix()}\n'
f'{mutual_exclusive} are mutual exclusive at this level.')
errors = list(board_validator.iter_errors(b))
if errors:
sys.exit('ERROR: Malformed board YAML file: '
f'{board_yml.as_posix()}\n'
f'{best_match(errors).message} in {best_match(errors).json_path}')
board_array = b.get('boards', [b.get('board', None)])
for board in board_array:
mutual_exclusive = {'name', 'extend'}
if len(mutual_exclusive - board.keys()) < 1:
sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n'
f'{mutual_exclusive} are mutual exclusive at this level.')
# This is a extending an existing board, place in array to allow later processing.
if 'extend' in board:
@@ -260,19 +254,6 @@ def load_v2_boards(board_name, board_yml, systems):
# Not the board we're looking for, ignore.
continue
board_revision = board.get('revision')
if board_revision is not None and board_revision.get('format') != 'custom':
if board_revision.get('default') is None:
sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n'
"Cannot find required key 'default'. Path: '/board/revision.'")
if board_revision.get('revisions') is None:
sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n'
"Cannot find required key 'revisions'. Path: '/board/revision.'")
mutual_exclusive = {'socs', 'variants'}
if len(mutual_exclusive - board.keys()) < 1:
sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n'
f'{mutual_exclusive} are mutual exclusive at this level.')
socs = [Soc.from_soc(systems.get_soc(s['name']), s.get('variants', []))
for s in board.get('socs', {})]

View File

@@ -9,8 +9,9 @@ import sys
from dataclasses import dataclass
from pathlib import Path, PurePath
import pykwalify.core
import jsonschema
import yaml
from jsonschema.exceptions import best_match
try:
from yaml import CSafeLoader as SafeLoader
@@ -18,17 +19,21 @@ except ImportError:
from yaml import SafeLoader
SOC_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'soc-schema.yml')
SOC_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'soc-schema.yaml')
with open(SOC_SCHEMA_PATH) as f:
soc_schema = yaml.load(f.read(), Loader=SafeLoader)
SOC_VALIDATOR = pykwalify.core.Core(schema_data=soc_schema, source_data={})
ARCH_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'arch-schema.yml')
ARCH_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'arch-schema.yaml')
with open(ARCH_SCHEMA_PATH) as f:
arch_schema = yaml.load(f.read(), Loader=SafeLoader)
ARCH_VALIDATOR = pykwalify.core.Core(schema_data=arch_schema, source_data={})
validator_class = jsonschema.validators.validator_for(soc_schema)
validator_class.check_schema(soc_schema)
soc_validator = validator_class(soc_schema)
validator_class = jsonschema.validators.validator_for(arch_schema)
validator_class.check_schema(arch_schema)
arch_validator = validator_class(arch_schema)
SOC_YML = 'soc.yml'
ARCHS_YML_PATH = PurePath('arch/archs.yml')
@@ -44,12 +49,12 @@ class Systems:
if soc_yaml is None:
return
try:
data = yaml.load(soc_yaml, Loader=SafeLoader)
SOC_VALIDATOR.source = data
SOC_VALIDATOR.validate()
except (yaml.YAMLError, pykwalify.errors.SchemaError) as e:
sys.exit(f'ERROR: Malformed yaml {soc_yaml.as_posix()}', e)
data = yaml.load(soc_yaml, Loader=SafeLoader)
errors = list(soc_validator.iter_errors(data))
if errors:
sys.exit('ERROR: Malformed soc YAML file: \n'
f'{soc_yaml}\n'
f'{best_match(errors).message} in {best_match(errors).json_path}')
for f in data.get('family', []):
family = Family(f['name'], [folder], [], [])
@@ -82,10 +87,6 @@ class Systems:
self._socs.extend(socs)
for soc in data.get('socs', []):
mutual_exclusive = {'name', 'extend'}
if len(mutual_exclusive - soc.keys()) < 1:
sys.exit(f'ERROR: Malformed content in SoC file: {soc_yaml}\n'
f'{mutual_exclusive} are mutual exclusive at this level.')
if soc.get('name') is not None:
self._socs.append(Soc(soc['name'], [c['name'] for c in soc.get('cpuclusters', [])],
[folder], '', ''))
@@ -94,8 +95,9 @@ class Systems:
[c['name'] for c in soc.get('cpuclusters', [])],
[folder], '', ''))
else:
# This should not happen if schema validation passed
sys.exit(f'ERROR: Malformed "socs" section in SoC file: {soc_yaml}\n'
f'Cannot find one of required keys {mutual_exclusive}.')
f'SoC entry must have either "name" or "extend" property.')
# Ensure that any runner configuration matches socs and cpuclusters declared in the same
# soc.yml file
@@ -217,11 +219,11 @@ def find_v2_archs(args):
with Path(archs_yml).open('r', encoding='utf-8') as f:
archs = yaml.load(f.read(), Loader=SafeLoader)
try:
ARCH_VALIDATOR.source = archs
ARCH_VALIDATOR.validate()
except pykwalify.errors.SchemaError as e:
sys.exit(f'ERROR: Malformed "build" section in file: {archs_yml.as_posix()}\n{e}')
errors = list(arch_validator.iter_errors(archs))
if errors:
sys.exit('ERROR: Malformed arch YAML file: '
f'{archs_yml.as_posix()}\n'
f'{best_match(errors).message} in {best_match(errors).json_path}')
if args.arch is not None:
archs = {'archs': list(filter(

View File

@@ -10,6 +10,7 @@ gitlint-core>=0.19.1
gitpython>=3.1.41
ijson
intelhex
jsonschema
junit2html
junitparser>=4.0.1
mypy

View File

@@ -15,7 +15,10 @@ astroid==3.3.10 \
attrs==25.3.0 \
--hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \
--hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b
# via reuse
# via
# jsonschema
# referencing
# reuse
awscli==1.41.2 \
--hash=sha256:2c219f88a810c2908954ac50b52f3791c875a3c3a439d16e5a8eac31190c95b7 \
--hash=sha256:428c5ff8a9c970405848ca49d7f4727e7afcfef5a93abd9227af730f77d24e03
@@ -471,6 +474,14 @@ jmespath==1.0.1 \
--hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \
--hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe
# via botocore
jsonschema==4.25.1 \
--hash=sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63 \
--hash=sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85
# via -r requirements-actions.in
jsonschema-specifications==2025.4.1 \
--hash=sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af \
--hash=sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608
# via jsonschema
junit2html==31.0.2 \
--hash=sha256:c7fd1f253d423f0df031d0cee8ef7d4d98d9f8bf6383a2d40dca639686814866
# via -r requirements-actions.in
@@ -953,6 +964,12 @@ rdflib==7.1.4 \
--hash=sha256:72f4adb1990fa5241abd22ddaf36d7cafa5d91d9ff2ba13f3086d339b213d997 \
--hash=sha256:fed46e24f26a788e2ab8e445f7077f00edcf95abb73bcef4b86cefa8b62dd174
# via spdx-tools
referencing==0.36.2 \
--hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \
--hash=sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0
# via
# jsonschema
# jsonschema-specifications
regex==2024.11.6 \
--hash=sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c \
--hash=sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60 \
@@ -1057,6 +1074,165 @@ reuse==5.0.2 \
--hash=sha256:7a680f00324e87a72061677a892d8cbabfddf7adcf7a5376aeeed2d78995bbbb \
--hash=sha256:878016ae5dd29c10bad4606d6676c12a268c12aa9fcfea66403598e16eed085c
# via -r requirements-actions.in
rpds-py==0.27.0 \
--hash=sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b \
--hash=sha256:05284439ebe7d9f5f5a668d4d8a0a1d851d16f7d47c78e1fab968c8ad30cab04 \
--hash=sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51 \
--hash=sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295 \
--hash=sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0 \
--hash=sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d \
--hash=sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e \
--hash=sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd \
--hash=sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5 \
--hash=sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03 \
--hash=sha256:11e8e28c0ba0373d052818b600474cfee2fafa6c9f36c8587d217b13ee28ca7d \
--hash=sha256:130c1ffa5039a333f5926b09e346ab335f0d4ec393b030a18549a7c7e7c2cea4 \
--hash=sha256:1321bce595ad70e80f97f998db37356b2e22cf98094eba6fe91782e626da2f71 \
--hash=sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9 \
--hash=sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34 \
--hash=sha256:15ea4d2e182345dd1b4286593601d766411b43f868924afe297570658c31a62b \
--hash=sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466 \
--hash=sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1 \
--hash=sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303 \
--hash=sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4 \
--hash=sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4 \
--hash=sha256:1d66f45b9399036e890fb9c04e9f70c33857fd8f58ac8db9f3278cfa835440c3 \
--hash=sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c \
--hash=sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec \
--hash=sha256:2406d034635d1497c596c40c85f86ecf2bf9611c1df73d14078af8444fe48031 \
--hash=sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e \
--hash=sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424 \
--hash=sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97 \
--hash=sha256:299a245537e697f28a7511d01038c310ac74e8ea213c0019e1fc65f52c0dcb23 \
--hash=sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd \
--hash=sha256:2e307cb5f66c59ede95c00e93cd84190a5b7f3533d7953690b2036780622ba81 \
--hash=sha256:2e39169ac6aae06dd79c07c8a69d9da867cef6a6d7883a0186b46bb46ccfb0c3 \
--hash=sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432 \
--hash=sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae \
--hash=sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5 \
--hash=sha256:33ba649a6e55ae3808e4c39e01580dc9a9b0d5b02e77b66bb86ef117922b1264 \
--hash=sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828 \
--hash=sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5 \
--hash=sha256:36184b44bf60a480863e51021c26aca3dfe8dd2f5eeabb33622b132b9d8b8b54 \
--hash=sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79 \
--hash=sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89 \
--hash=sha256:419dd9c98bcc9fb0242be89e0c6e922df333b975d4268faa90d58499fd9c9ebe \
--hash=sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c \
--hash=sha256:42ccc57ff99166a55a59d8c7d14f1a357b7749f9ed3584df74053fd098243451 \
--hash=sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc \
--hash=sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff \
--hash=sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8 \
--hash=sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859 \
--hash=sha256:46f48482c1a4748ab2773f75fffbdd1951eb59794e32788834b945da857c47a8 \
--hash=sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1 \
--hash=sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43 \
--hash=sha256:4c3f8a0d4802df34fcdbeb3dfe3a4d8c9a530baea8fafdf80816fcaac5379d83 \
--hash=sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1 \
--hash=sha256:555ed147cbe8c8f76e72a4c6cd3b7b761cbf9987891b9448808148204aed74a5 \
--hash=sha256:55d42a0ef2bdf6bc81e1cc2d49d12460f63c6ae1423c4f4851b828e454ccf6f1 \
--hash=sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85 \
--hash=sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be \
--hash=sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac \
--hash=sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7 \
--hash=sha256:5df559e9e7644d9042f626f2c3997b555f347d7a855a15f170b253f6c5bfe358 \
--hash=sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e \
--hash=sha256:61490d57e82e23b45c66f96184237994bfafa914433b8cd1a9bb57fecfced59d \
--hash=sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8 \
--hash=sha256:64a0fe3f334a40b989812de70160de6b0ec7e3c9e4a04c0bbc48d97c5d3600ae \
--hash=sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64 \
--hash=sha256:699c346abc73993962cac7bb4f02f58e438840fa5458a048d3a178a7a670ba86 \
--hash=sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669 \
--hash=sha256:6bde37765564cd22a676dd8101b657839a1854cfaa9c382c5abf6ff7accfd4ae \
--hash=sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3 \
--hash=sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b \
--hash=sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0 \
--hash=sha256:737005088449ddd3b3df5a95476ee1c2c5c669f5c30eed909548a92939c0e12d \
--hash=sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858 \
--hash=sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4 \
--hash=sha256:79af163a4b40bbd8cfd7ca86ec8b54b81121d3b213b4435ea27d6568bcba3e9d \
--hash=sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14 \
--hash=sha256:7cf9bc4508efb18d8dff6934b602324eb9f8c6644749627ce001d6f38a490889 \
--hash=sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f \
--hash=sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5 \
--hash=sha256:81f81bbd7cdb4bdc418c09a73809abeda8f263a6bf8f9c7f93ed98b5597af39d \
--hash=sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d \
--hash=sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114 \
--hash=sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e \
--hash=sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5 \
--hash=sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391 \
--hash=sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f \
--hash=sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f \
--hash=sha256:8de567dec6d451649a781633d36f5c7501711adee329d76c095be2178855b042 \
--hash=sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774 \
--hash=sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156 \
--hash=sha256:935afcdea4751b0ac918047a2df3f720212892347767aea28f5b3bf7be4f27c0 \
--hash=sha256:9a0ff7ee28583ab30a52f371b40f54e7138c52ca67f8ca17ccb7ccf0b383cb5f \
--hash=sha256:9ad08547995a57e74fea6abaf5940d399447935faebbd2612b3b0ca6f987946b \
--hash=sha256:9b2a4e17bfd68536c3b801800941c95a1d4a06e3cada11c146093ba939d9638d \
--hash=sha256:9b78430703cfcf5f5e86eb74027a1ed03a93509273d7c705babb547f03e60016 \
--hash=sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185 \
--hash=sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d \
--hash=sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b \
--hash=sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9 \
--hash=sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2 \
--hash=sha256:a4cf32a26fa744101b67bfd28c55d992cd19438aff611a46cac7f066afca8fd4 \
--hash=sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb \
--hash=sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726 \
--hash=sha256:af22763a0a1eff106426a6e1f13c4582e0d0ad89c1493ab6c058236174cd6c6a \
--hash=sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c \
--hash=sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23 \
--hash=sha256:b2eff8ee57c5996b0d2a07c3601fb4ce5fbc37547344a26945dd9e5cbd1ed27a \
--hash=sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374 \
--hash=sha256:b8a4131698b6992b2a56015f51646711ec5d893a0b314a4b985477868e240c87 \
--hash=sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367 \
--hash=sha256:ba783541be46f27c8faea5a6645e193943c17ea2f0ffe593639d906a327a9bcc \
--hash=sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c \
--hash=sha256:be3964f7312ea05ed283b20f87cb533fdc555b2e428cc7be64612c0b2124f08c \
--hash=sha256:be806e2961cd390a89d6c3ce8c2ae34271cfcd05660f716257838bb560f1c3b6 \
--hash=sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d \
--hash=sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f \
--hash=sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626 \
--hash=sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd \
--hash=sha256:cb0702c12983be3b2fab98ead349ac63a98216d28dda6f518f52da5498a27a1b \
--hash=sha256:cbc619e84a5e3ab2d452de831c88bdcad824414e9c2d28cd101f94dbdf26329c \
--hash=sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc \
--hash=sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8 \
--hash=sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a \
--hash=sha256:d2a81bdcfde4245468f7030a75a37d50400ac2455c3a4819d9d550c937f90ab5 \
--hash=sha256:d2cc2b34f9e1d31ce255174da82902ad75bd7c0d88a33df54a77a22f2ef421ee \
--hash=sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e \
--hash=sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6 \
--hash=sha256:d7cf5e726b6fa977e428a61880fb108a62f28b6d0c7ef675b117eaff7076df49 \
--hash=sha256:d85d784c619370d9329bbd670f41ff5f2ae62ea4519761b679d0f57f0f0ee267 \
--hash=sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b \
--hash=sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615 \
--hash=sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622 \
--hash=sha256:dbd749cff1defbde270ca346b69b3baf5f1297213ef322254bf2a28537f0b046 \
--hash=sha256:dc662bc9375a6a394b62dfd331874c434819f10ee3902123200dbcf116963f89 \
--hash=sha256:dc6b0d5a1ea0318ef2def2b6a55dccf1dcaf77d605672347271ed7b829860765 \
--hash=sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2 \
--hash=sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e \
--hash=sha256:dea0808153f1fbbad772669d906cddd92100277533a03845de6893cadeffc8be \
--hash=sha256:e0d7151a1bd5d0a203a5008fc4ae51a159a610cb82ab0a9b2c4d80241745582e \
--hash=sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9 \
--hash=sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261 \
--hash=sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015 \
--hash=sha256:e377e4cf8795cdbdff75b8f0223d7b6c68ff4fef36799d88ccf3a995a91c0112 \
--hash=sha256:e3acb9c16530362aeaef4e84d57db357002dc5cbfac9a23414c3e73c08301ab2 \
--hash=sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d \
--hash=sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089 \
--hash=sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433 \
--hash=sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60 \
--hash=sha256:f09c9d4c26fa79c1bad927efb05aca2391350b8e61c38cbc0d7d3c814e463124 \
--hash=sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb \
--hash=sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410 \
--hash=sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171 \
--hash=sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e \
--hash=sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42 \
--hash=sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe
# via
# jsonschema
# referencing
rsa==4.7.2 \
--hash=sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2 \
--hash=sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9
@@ -1231,6 +1407,7 @@ typing-extensions==4.14.0 \
# mypy
# pygithub
# python-can
# referencing
# tox
unidiff==0.7.5 \
--hash=sha256:2e5f0162052248946b9f0970a40e9e124236bf86c82b70821143a6fc1dea2574 \

View File

@@ -12,6 +12,7 @@ PyYAML>=6.0
# YAML validation. Used by zephyr_module.
pykwalify
jsonschema
# used by west_commands
canopen

View File

@@ -0,0 +1,40 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
# JSON Schema for architecture metadata YAML files
# When possible, constraints and validation rules should be modeled directly in this file.
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "https://zephyrproject.org/schemas/zephyr/arch"
title: Zephyr Architecture Schema
description: Schema for validating Zephyr architecture metadata files
type: object
properties:
archs:
type: array
description: List of supported architectures
items:
type: object
properties:
name:
type: string
description: Name of the architecture
full_name:
type: string
description: Full display name of the architecture
path:
type: string
description: >-
Location of the architecture implementation relative to the
archs.yml file
comment:
type: string
description: Free form comment with extra information regarding the architecture
required:
- name
- path
additionalProperties: false
required:
- archs
additionalProperties: false

View File

@@ -1,33 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
## A pykwalify schema for basic validation of the structure of a
## arch metadata YAML file.
##
# The archs.yml file is a simple list of key value pairs containing architectures
# and their location which is used by the build system.
type: map
mapping:
archs:
required: true
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
desc: Name of the arch
path:
required: true
type: str
desc: Location of the arch implementation relative to the archs.yml file.
full_name:
required: false
type: str
desc: Full display name of the architecture
comment:
required: false
type: str
desc: Free form comment with extra information regarding the arch.

View File

@@ -0,0 +1,262 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
# JSON Schema for board metadata YAML files
# When possible, constraints and validation rules should be modeled directly in this file.
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "https://zephyrproject.org/schemas/zephyr/board"
title: Zephyr Board Schema
description: Schema for validating Zephyr board metadata files
type: object
$defs:
# Common regex patterns for revision formats
letterRevisionPattern:
pattern: "^[A-Z]$"
majorMinorPatchRevisionPattern:
pattern: "^0|[1-9][0-9]*\\.[0-9]+\\.[0-9]+$"
numberRevisionPattern:
pattern: "^\\d+$"
variantSchema:
type: array
items:
type: object
properties:
name:
type: string
cpucluster:
type: string
variants:
$ref: "#/$defs/variantSchema" # Recursive definition
required:
- name
additionalProperties: false
extendVariantSchema:
type: array
items:
type: object
properties:
name:
type: string
qualifier:
type: string
required:
- name
- qualifier
additionalProperties: false
boardSchema:
type: object
properties:
name:
type: string
description: Name of the board
full_name:
type: string
description: Full name of the board. Typically set to the commercial name of the board.
extend:
type: string
vendor:
type: string
description: SoC family of the SoC on the board.
revision:
type: object
properties:
format:
type: string
enum:
- "major.minor.patch"
- "letter"
- "number"
- "custom"
default:
type: string
exact:
type: boolean
revisions:
type: array
items:
type: object
properties:
name:
type: string
required:
- name
required:
- format
additionalProperties: false
# Conditional logic: 'default' and 'revisions' are required if 'format' is not 'custom'
allOf:
- if:
properties:
format:
not:
const: "custom"
then:
required:
- default
- revisions
# Validation for 'letter' format: default and revision names must be [A-Z]
- if:
properties:
format:
const: "letter"
then:
properties:
default:
$ref: "#/$defs/letterRevisionPattern"
revisions:
type: array
items:
type: object
properties:
name:
$ref: "#/$defs/letterRevisionPattern"
# Validation for 'major.minor.patch' format: default and revision names must be x.y.z
- if:
properties:
format:
const: "major.minor.patch"
then:
properties:
default:
$ref: "#/$defs/majorMinorPatchRevisionPattern"
revisions:
type: array
items:
type: object
properties:
name:
$ref: "#/$defs/majorMinorPatchRevisionPattern"
# Validation for 'number' format: default and revision names must be integers
- if:
properties:
format:
const: "number"
then:
properties:
default:
$ref: "#/$defs/numberRevisionPattern"
revisions:
type: array
items:
type: object
properties:
name:
$ref: "#/$defs/numberRevisionPattern"
socs:
type: array
items:
type: object
properties:
name:
type: string
variants:
$ref: "#/$defs/variantSchema"
required:
- name
additionalProperties: false
variants:
$ref: "#/$defs/extendVariantSchema"
# Conditional logic for requirements
allOf:
# 'name' and 'extend' are mutually exclusive: we're either defining a new board or extending
# an existing one.
- oneOf:
- required: [name]
- required: [extend]
# A base board (identified by 'name') must define its hardware via the 'socs' property.
- if:
required: [name]
then:
required: [socs]
# An extending board inherits its SoC and must not redefine it. It should define 'variants'
# instead.
- if:
required: [extend]
then:
not:
required: [socs]
additionalProperties: false
runnerSchema:
type: object
properties:
priority:
type: integer
description: |
Priority of this flash run once configuration. The highest value data will be used
instead of any with lower priorities. If omitted, will default to 10.
run_once:
type: object
description: |
Allows for restricting west flash commands when using sysbuild to run once per given
grouping of board targets. This is to allow for future image program cycles to not
erase the flash of a device which has just been programmed by another image.
patternProperties:
"^(.*)$":
description: |
A dictionary of commands which should be limited to running once per invocation
of west flash for a given set of flash runners and board targets.
type: array
items:
type: object
properties:
run:
type: string
enum: ["first", "last"]
description: |
If first, will run this command once when the first image is flashed, if
last, will run this command once when the final image is flashed.
runners:
type: array
items:
type: string
description: |
A list of flash runners that this applies to, can use `all` to apply
to all runners.
groups:
type: array
items:
type: object
description: |
A grouping of board targets which the command should apply to. Can
be used multiple times to have multiple groups.
properties:
boards:
type: array
items:
type: string
description: |
A board target to match against in regex. Must be one entry
per board target, a single regex entry will not match two
board targets even if they both match.
required:
- boards
required:
- run
- runners
- groups
additionalProperties: false
properties:
board:
$ref: "#/$defs/boardSchema"
boards:
type: array
items:
$ref: "#/$defs/boardSchema"
runners:
$ref: "#/$defs/runnerSchema"
dependentSchemas:
# A board.yml file may define either a single board or multiple boards, but not both.
board:
not:
required: ["boards"]
boards:
not:
required: ["board"]
additionalProperties: false

View File

@@ -1,158 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
## A pykwalify schema for basic validation of the structure of a
## board metadata YAML file.
##
# The board.yml file is a simple list of key value pairs containing board
# information like: name, vendor, socs, variants.
schema;variant-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
cpucluster:
required: false
type: str
variants:
required: false
include: variant-schema
schema;extend-variant-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
qualifier:
required: true
type: str
schema;board-schema:
type: map
mapping:
name:
required: false # Note: either name or extend is required, but that is handled in python
type: str
desc: Name of the board
full_name:
required: false
type: str
desc: Full name of the board. Typically set to the commercial name of the board.
extend:
required: false # Note: either name or extend is required, but that is handled in python
type: str
vendor:
required: false
type: str
desc: SoC family of the SoC on the board.
revision:
required: false
type: map
mapping:
format:
required: true
type: str
enum:
["major.minor.patch", "letter", "number", "custom"]
default:
required: false # This field is required when 'format' != 'custom'
type: str
exact:
required: false
type: bool
revisions:
required: false # This field is required when 'format' != 'custom'
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
socs:
required: false # Required for name:, but not for extend.
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
variants:
include: variant-schema
variants:
include: extend-variant-schema
type: map
mapping:
board:
include: board-schema
boards:
type: seq
sequence:
- include: board-schema
runners:
type: map
mapping:
priority:
type: int
desc: |
Priority of this flash run once configuration. The highest value data will be used
instead of any with lower priorities. If omitted, will default to 10.
run_once:
type: map
desc: |
Allows for restricting west flash commands when using sysbuild to run once per given
grouping of board targets. This is to allow for future image program cycles to not
erase the flash of a device which has just been programmed by another image.
mapping:
regex;(.*):
type: seq
desc: |
A dictionary of commands which should be limited to running once per invocation
of west flash for a given set of flash runners and board targets.
sequence:
- type: map
mapping:
run:
required: true
type: str
enum: ['first', 'last']
desc: |
If first, will run this command once when the first image is flashed, if
last, will run this command once when the final image is flashed.
runners:
required: true
type: seq
sequence:
- type: str
desc: |
A list of flash runners that this applies to, can use `all` to apply
to all runners.
groups:
required: true
type: seq
sequence:
- type: map
desc: |
A grouping of board targets which the command should apply to. Can
be used multiple times to have multiple groups.
mapping:
boards:
required: true
type: seq
sequence:
- type: str
desc: |
A board target to match against in regex. Must be one entry
per board target, a single regex entry will not match two
board targets even if they both match.

View File

@@ -0,0 +1,159 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
# JSON Schema for SoC metadata YAML files
# When possible, constraints and validation rules should be modeled directly in this file.
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "https://zephyrproject.org/schemas/zephyr/soc"
title: Zephyr SoC Schema
description: Schema for validating Zephyr SoC metadata files
type: object
$defs:
cpucluster:
type: object
properties:
name:
type: string
description: Name of the CPU cluster
required:
- name
additionalProperties: false
soc:
type: object
properties:
name:
type: string
description: Name of the SoC
cpuclusters:
type: array
items:
$ref: "#/$defs/cpucluster"
required:
- name
additionalProperties: false
soc-extend:
type: object
oneOf:
- type: object
properties:
name:
type: string
description: Name of the SoC
cpuclusters:
type: array
items:
$ref: "#/$defs/cpucluster"
required:
- name
additionalProperties: false
- type: object
properties:
extend:
type: string
description: Name of the SoC to extend
cpuclusters:
type: array
items:
$ref: "#/$defs/cpucluster"
required:
- extend
additionalProperties: false
series:
type: object
properties:
name:
type: string
description: Name of the series
socs:
type: array
items:
$ref: "#/$defs/soc"
required:
- name
additionalProperties: false
family:
type: object
properties:
name:
type: string
description: Name of the family
series:
type: array
items:
$ref: "#/$defs/series"
socs:
type: array
items:
$ref: "#/$defs/soc"
required:
- name
additionalProperties: false
runner-group:
type: object
properties:
qualifiers:
type: array
items:
type: string
description: Board qualifier to match against in regex form
required:
- qualifiers
runner-command:
type: object
properties:
run:
type: string
enum:
- first
- last
description: When to run this command - first or last image
runners:
type: array
items:
type: string
description: List of flash runners this applies to
groups:
type: array
items:
$ref: "#/$defs/runner-group"
required:
- run
- runners
- groups
additionalProperties: false
properties:
family:
type: array
items:
$ref: "#/$defs/family"
series:
type: array
items:
$ref: "#/$defs/series"
socs:
type: array
items:
$ref: "#/$defs/soc-extend"
vendor:
type: string
description: SoC series of the SoC
comment:
type: string
description: Free form comment with extra information regarding the SoC
runners:
type: object
properties:
priority:
type: integer
description: Priority of this flash run once configuration
run_once:
type: object
patternProperties:
.*:
type: array
items:
$ref: "#/$defs/runner-command"
additionalProperties: false
additionalProperties: false

View File

@@ -1,143 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
## A pykwalify schema for basic validation of the structure of a SoC
## metadata YAML file.
##
# The soc.yml file is a simple list of key value pairs containing SoCs
# located and the current structure level.
schema;cpucluster-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
schema;soc-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true # Note: either name or extend is required, but that is handled in python
type: str
cpuclusters:
include: cpucluster-schema
schema;soc-extend-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: false # Note: either name or extend is required, but that is handled in python
type: str
extend:
required: false # Note: either name or extend is required, but that is handled in python
type: str
cpuclusters:
include: cpucluster-schema
schema;series-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
socs:
required: false
include: soc-schema
type: map
mapping:
family:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
series:
include: series-schema
socs:
include: soc-schema
series:
include: series-schema
socs:
include: soc-extend-schema
vendor:
required: false
type: str
desc: SoC series of the SoC.
This field is of informational use and can be used for filtering of SoCs.
comment:
required: false
type: str
desc: Free form comment with extra information regarding the SoC.
runners:
type: map
mapping:
priority:
type: int
desc: |
Priority of this flash run once configuration. The highest value data will be used
instead of any with lower priorities. If omitted, will default to 0.
run_once:
type: map
desc: |
Allows for restricting west flash commands when using sysbuild to run once per given
grouping of board targets. This is to allow for future image program cycles to not
erase the flash of a device which has just been programmed by another image.
mapping:
regex;(.*):
type: seq
desc: |
A dictionary of commands which should be limited to running once per invocation
of west flash for a given set of flash runners and board targets.
sequence:
- type: map
mapping:
run:
required: true
type: str
enum: ['first', 'last']
desc: |
If first, will run this command once when the first image is flashed, if
last, will run this command once when the final image is flashed.
runners:
required: true
type: seq
sequence:
- type: str
desc: |
A list of flash runners that this applies to, can use `all` to apply
to all runners.
groups:
required: true
type: seq
sequence:
- type: map
desc: |
A grouping of board targets which the command should apply to. Can
be used multiple times to have multiple groups.
mapping:
qualifiers:
required: true
type: seq
sequence:
- type: str
desc: |
A board qualifier to match against in regex form. Must be one
entry per board target, a single regex entry will not match
two board targets even if they both match.