
On 15/06/2022 09:47, Neha Malcom Francis wrote:
For validating config files and generating binary config artifacts, here board specific config class is added.
Add function cfgBinaryGen() in tibcfg_gen.py. It uses TIBoardConfig class to load given schema and config files in YAML, validate them and generate binaries.
Signed-off-by: Tarun Sahu t-sahu@ti.com [n-francis@ti.com: prepared patch for upstreaming] Signed-off-by: Neha Malcom Francis n-francis@ti.com
test/py/requirements.txt | 1 + tools/tibcfg_gen.py | 114 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 tools/tibcfg_gen.py
diff --git a/test/py/requirements.txt b/test/py/requirements.txt index 33c5c0bbc4..a91ba64563 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -4,6 +4,7 @@ coverage==4.5.4 extras==1.0.0 fixtures==3.0.0 importlib-metadata==0.23 +jsonschema==4.0.0 linecache2==1.0.0 more-itertools==7.2.0 packaging==19.2 diff --git a/tools/tibcfg_gen.py b/tools/tibcfg_gen.py new file mode 100644 index 0000000000..e5fa2690c8 --- /dev/null +++ b/tools/tibcfg_gen.py @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ +# +# TI Board Configuration Class for Schema Validation and Binary Generation +#
+import os +import getopt +import sys
+import yaml
+from jsonschema import validate
+class TIBoardConfig:
- """ Texas Instruments Board Configuration File"""
- def __init__(self, file, schema, data_rules=""):
"""Load a YAML configuration file and YAML schema
Validation of the config file against the schema is also done."""
with open(file, 'r') as f:
self.file_yaml = yaml.safe_load(f)
with open(schema, 'r') as sch:
self.schema_yaml = yaml.safe_load(sch)
self.data_rules = data_rules
try:
validate(self.file_yaml, self.schema_yaml)
except Exception as e:
print(e)
Don't catch the exception here, so that we never have a non-validated TIBoardConfig object. Instead, catch it in cfgBinaryGen() below to report the validation error.
- def _convert_to_byte_chunk(self, val, data_type):
"""Convert value into byte array"""
size = 0
if(data_type == "#/definitions/u8"):
size = 1
elif(data_type == "#/definitions/u16"):
size = 2
elif(data_type == "#/definitions/u32"):
size = 4
Parentheses are unnecessary for these as well.
else:
raise Exception("Data type not present in definitions")
if type(val) == int:
br = val.to_bytes(size, byteorder="little")
return br
- def _compile_yaml(self, schema_yaml, file_yaml):
"""Convert YAML file into byte array based on YAML schema"""
br = bytearray()
for key in file_yaml.keys():
node = file_yaml[key]
node_schema = schema_yaml['properties'][key]
node_type = node_schema.get('type')
if not 'type' in node_schema:
br += self._convert_to_byte_chunk(node,
node_schema.get('$ref'))
elif node_type == 'object':
br += self._compile_yaml(node_schema, node)
elif node_type == 'array':
for item in node:
if not isinstance(item, dict):
br += self._convert_to_byte_chunk(
item, schema_yaml['properties'][key]['items']["$ref"])
else:
br += self._compile_yaml(node_schema.get('items'), item)
return br
- def generate_binaries(self, out_path=""):
"""Generate config binary artifacts from the loaded YAML configuration file"""
if not os.path.isdir(out_path):
os.mkdir(out_path)
for key in self.file_yaml.keys():
node = self.file_yaml[key]
node_schema = self.schema_yaml['properties'][key]
br = self._compile_yaml(node_schema, node)
path = os.path.join(out_path, key + ".bin")
with open(path, 'wb') as cfg:
cfg.write(br)
- def delete_binaries(self, out_path=""):
"""Delete generated binaries"""
if os.path.isdir(out_path):
for key in self.file_yaml.keys():
path = os.path.join(out_path, key + ".bin")
if os.path.isfile(path):
os.remove(path)
+def cfgBinaryGen():
- """Generate config binaries from YAML config file and YAML schema
Arguments:
- config_yaml: board config file in YAML
- schema_yaml: schema file in YAML to validate config_yaml against
- output_dir: output directory where generated binaries can be populated
- Pass the arguments along with the filename in the Makefile.
- """
- opts, args = getopt.getopt(sys.argv[1:], "c:s:o")
I'd prefer argparse, with both long/short forms of arguments and proper help messages.
- for opt, val in opts:
if opt == "-c":
config_yaml = val
elif opt == "-s":
schema_yaml = val
elif opt == "-o":
output_dir = os.path.abspath(val)
- try:
tibcfg = TIBoardConfig(config_yaml, schema_yaml)
tibcfg.generate_binaries(output_dir)
- except:
raise ValueError("Could not find config files!")
+cfgBinaryGen()
This needs to be
if __name__ == "__main__": cfgBinaryGen()
or it will be run when anything uses 'import tibcfg_gen' in Python.