Skip to content

Commit 47ee136

Browse files
committed
net: scripts: Convert yaml config script to support jsonschema
As pykwalify is no longer used in zephyr, the yaml schema format is changed to jsonschema format. This requires changes to python script that generates C struct configuration definitions. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 508dd4a commit 47ee136

File tree

1 file changed

+54
-27
lines changed

1 file changed

+54
-27
lines changed

scripts/net/net-yaml-config.py

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,37 @@ def create_yaml_file():
195195

196196
# If user has supplied an argument, treat it as a schema file
197197
if bool(data) and len(sys.argv[1:]) > 0:
198-
# If pykwalify is installed, then validate the yaml
198+
# If jsonschema is installed, then validate the yaml
199199
try:
200-
import pykwalify.core
200+
import jsonschema
201201

202202
def yaml_validate(data, schema):
203203
if not schema:
204204
return
205-
c = pykwalify.core.Core(source_data=data, schema_files=[schema])
206-
c.validate(raise_exception=True)
205+
206+
try:
207+
from yaml import CSafeLoader as SafeLoader
208+
except ImportError:
209+
from yaml import SafeLoader
210+
211+
with open(schema) as f:
212+
net_schema = yaml.load(f.read(), Loader=SafeLoader)
213+
214+
validator_class = jsonschema.validators.validator_for(net_schema)
215+
validator_class.check_schema(net_schema)
216+
validator = validator_class(net_schema)
217+
218+
errors = sorted(validator.iter_errors(data), key=lambda e: e.path)
219+
if errors:
220+
# Build a readable message with each error and its path
221+
lines = []
222+
for e in errors:
223+
path = ".".join(map(str, list(e.path))) or "<root>"
224+
lines.append(f"{path}: {e.message}")
225+
raise jsonschema.ValidationError("\n".join(lines))
207226

208227
except ImportError as e:
209-
sys.stderr.write("can't import pykwalify; won't validate YAML (%s)", e)
228+
sys.stderr.write("can't import jsonschema; won't validate YAML (%s)", e)
210229

211230
def yaml_validate(data, schema):
212231
pass
@@ -311,33 +330,52 @@ def walk_dict_schema(level, top_level_name, cdict, key_upper, map, indent):
311330
global changed
312331
for key, value in map.items():
313332
if key == "type":
314-
if value == "str":
333+
# Use value instead of items to avoid changing too many places in C code
334+
if key_upper == "items":
335+
key_upper = "value"
336+
337+
if value == "string":
315338
output(indent, "const char *" + key_upper + ";")
316339
changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n"
317-
elif value == "bool":
340+
elif value == "boolean":
318341
output(indent, "bool " + key_upper + ";")
319342
changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n"
320-
elif value == "int":
343+
elif value == "integer":
321344
output(indent, "int " + key_upper + ";")
322345
changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n"
323-
elif value == "seq":
346+
elif value == "array":
324347
print(changed, end="")
325348
changed = ""
326349
output(indent, "struct " + top_level_name + "_" + key_upper + " {")
327-
elif value == "map":
350+
elif value == "object":
328351
print(changed, end="")
329352
changed = ""
330353
if key_upper != "value":
331354
if level == 1:
332355
output(indent, "struct " + key_upper + " {")
333356
else:
334357
output(indent, "struct " + top_level_name + "_" + key_upper + " {")
335-
elif value == "any" and key_upper == "bind_to":
336-
output(indent, "int bind_to;")
337-
changed += indent + "bool " + "__bind_to_changed : 1;" + "\n"
338358
continue
339-
elif key == "mapping":
359+
360+
if key == "bind_to":
361+
output(indent, "int bind_to;")
362+
changed += indent + "bool " + "__bind_to_changed : 1;" + "\n"
363+
continue
364+
365+
if isinstance(value, dict):
340366
walk_dict_schema(level + 1, top_level_name, cdict, key, value, "\t" + indent)
367+
elif isinstance(value, list):
368+
walk_list_schema(level + 1, top_level_name, cdict, key, value, "\t" + indent)
369+
370+
if key == "items":
371+
print(changed, end="")
372+
changed = ""
373+
if key_upper in combined_data:
374+
output(indent, "} " + key_upper + "[" + str(combined_data[key_upper]) + "];")
375+
else:
376+
output(indent, "} " + key_upper + "[1];")
377+
378+
elif key == "properties":
341379
print(changed, end="")
342380
changed = ""
343381
if key_upper != "value":
@@ -347,19 +385,6 @@ def walk_dict_schema(level, top_level_name, cdict, key_upper, map, indent):
347385
output(indent, "};")
348386
else:
349387
output(indent, "} " + key_upper + ";")
350-
continue
351-
elif key == "sequence":
352-
walk_list_schema(level + 1, top_level_name, cdict, "value", value, "\t" + indent)
353-
print(changed, end="")
354-
changed = ""
355-
if key_upper in combined_data:
356-
output(indent, "} " + key_upper + "[" + str(combined_data[key_upper]) + "];")
357-
else:
358-
output(indent, "} " + key_upper + "[1];")
359-
continue
360-
361-
if isinstance(value, dict):
362-
walk_dict_schema(level + 1, top_level_name, cdict, key, value, indent)
363388

364389

365390
def walk_list_schema(level, top_level_name, cdict, key, lst, indent):
@@ -384,6 +409,8 @@ def walk_list_schema(level, top_level_name, cdict, key, lst, indent):
384409
# Create C struct definition. Prefix some of the generated C struct fields with
385410
# by the name of the struct to make them unambiguous.
386411
for key, value in schema.items():
412+
if key in ('$id', '$schema', 'title', 'description'):
413+
print("/* " + key + ": " + str(value) + " */")
387414
if isinstance(value, dict):
388415
walk_dict_schema(0, list(data.keys())[0], schema_data, key, value, "")
389416

0 commit comments

Comments
 (0)