public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Neha Malcom Francis <n-francis@ti.com>
To: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Cc: <sjg@chromium.org>, <marek.behun@nic.cz>, <xypron.glpk@gmx.de>,
	<vigneshr@ti.com>, <a-govindraju@ti.com>, <kristo@kernel.org>,
	<s-anna@ti.com>, <kishon@ti.com>, <joel.peshkin@broadcom.com>,
	<patrick.delaunay@foss.st.com>, <mr.nuke.me@gmail.com>,
	<nm@ti.com>, <u-boot@lists.denx.de>
Subject: Re: [RESEND, RFC 1/8] tools: config: yaml: Add board config class to generate config binaries
Date: Tue, 19 Apr 2022 08:19:41 +0530	[thread overview]
Message-ID: <63d3bf8d-e70e-03d3-9c7a-c8cd66311d18@ti.com> (raw)
In-Reply-To: <5993486a-5e8e-b38d-2293-a9379e0365af@gmail.com>

On 19/04/22 01:25, Alper Nebi Yasak wrote:
> On 06/04/2022 15:29, 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.
> 
> The subject lines (of other patches as well) sound too generic when most
> of them are TI specific, I'd expect at least a 'ti:' tag except where
> you already include more specific terms like a board name.
> 
> (This one could be "tools: ti: Add ..." for example).
> 
>>
>> 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      | 116 +++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 117 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..7635596906
>> --- /dev/null
>> +++ b/tools/tibcfg_gen.py
>> @@ -0,0 +1,116 @@
>> +# 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
>> +#
>> +
>> +from jsonschema import validate
>> +
>> +import yaml
>> +import os
>> +import sys
> 
> Standard library imports should appear before third-party libraries,
> with an empty line between them.
> 
>> +
>> +
>> +class TIBoardConfig:
>> +    file_yaml = {}
>> +    schema_yaml = {}
>> +    data_rules = {}
> 
> These belong in __init__ as they are per-instance attributes.
> 
>> +
>> +    def __init__(self):
>> +        pass
>> +
>> +    def Load(self, file, schema, data_rules=""):
> 
> You can rename this to be the __init__ function.
> 
>> +        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
>> +
>> +    def CheckValidity(self):
>> +        try:
>> +            validate(self.file_yaml, self.schema_yaml)
>> +            return True
>> +        except Exception as e:
>> +            print(e)
>> +            return False
> 
> You can also do this validation immediately after loading the yaml files
> in the __init__(), and then safely assume any created object is valid.
> 
>> +
>> +    def __ConvertToByteChunk(self, val, data_type):
> 
> Methods should be in snake_case. Also consider using a single underscore
> as the prefix, double underscore does some special name mangling.
> 
>> +        br = []
>> +        size = 0
>> +        if(data_type == "#/definitions/u8"):
>> +            size = 1
>> +        elif(data_type == "#/definitions/u16"):
>> +            size = 2
>> +        elif(data_type == "#/definitions/u32"):
>> +            size = 4
>> +        else:
>> +            return -1
> 
> I think this case should raise an error of some kind.
> 
>> +        if(type(val) == int):
>> +            while(val != 0):
> 
> In general, don't use parentheses with if, while etc.
> 
>> +                br = br + [(val & 0xFF)]
>> +                val = val >> 8
>> +        while(len(br) < size):
>> +            br = br + [0]
>> +        return br
> 
> This all looks like val.to_bytes(size, 'little'), but as a list instead
> of bytes. If you want to get fancy, have a look at the struct module.
> (For example, struct.pack('<L', val) )
> 
>> +
>> +    def __CompileYaml(self, schema_yaml, file_yaml):
>> +        br = []
> 
> Consider using a bytearray instead of a list-of-ints here.
> 
>> +        for key in file_yaml.keys():
> 
> I think things would be more readable if you extracted
> 
>      node = file_yaml[key]
>      node_schema = schema_yaml['properties'][key]
>      node_type = node_schema.get('type')
> 
> as variables here and used those in the following code.
> 
>> +            if not 'type' in schema_yaml['properties'][key]:
>> +                br = br + \
> 
> br += ... would be nicer for all of these.
> 
>> +                    self.__ConvertToByteChunk(
>> +                        file_yaml[key], schema_yaml['properties'][key]["$ref"])
>> +            elif schema_yaml['properties'][key]['type'] == 'object':
>> +                br = br + \
>> +                    self.__CompileYaml(
>> +                        schema_yaml['properties'][key], file_yaml[key])
>> +            elif schema_yaml['properties'][key]['type'] == 'array':
>> +                for item in file_yaml[key]:
>> +                    if not isinstance(item, dict):
>> +                        br = br + \
>> +                            self.__ConvertToByteChunk(
>> +                                item, schema_yaml['properties'][key]['items']["$ref"])
>> +                    else:
>> +                        br = br + \
>> +                            self.__CompileYaml(
>> +                                schema_yaml['properties'][key]['items'], item)
>> +        return br
>> +
>> +    def GenerateBinaries(self, out_path=""):
>> +        if not os.path.isdir(out_path):
>> +            os.mkdir(out_path)
>> +        if(self.CheckValidity()):
>> +            for key in self.file_yaml.keys():
>> +                br = []
> 
> You don't need this assignment, it's overwritten in the next one anyway.
> 
>> +                br = self.__CompileYaml(
>> +                    self.schema_yaml['properties'][key], self.file_yaml[key])
>> +                with open(out_path + "/" + key + ".bin", 'wb') as cfg:
> 
> Construct file paths with os.path.join() here and below.
> 
>> +                    cfg.write(bytearray(br))
>> +        else:
>> +            raise ValueError("Config YAML Validation failed!")
>> +
>> +    def DeleteBinaries(self, out_path=""):
>> +        if os.path.isdir(out_path):
>> +            for key in self.file_yaml.keys():
>> +                if os.path.isfile(out_path + "/" + key + ".bin"):
>> +                    os.remove(out_path + "/" + key + ".bin")
>> +
>> +
>> +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
>> +    Pass the arguments along with the filename in the Makefile.
>> +    """
>> +    tibcfg = TIBoardConfig()
>> +    config_yaml = sys.argv[1]
>> +    schema_yaml = sys.argv[2]
>> +    try:
>> +        tibcfg.Load(config_yaml, schema_yaml)
>> +    except:
>> +        raise ValueError("Could not find config files!")
>> +    tibcfg.GenerateBinaries(os.environ['O'])
> 
> I think it'd be better to pass the directory as an -o / --output-dir
> argument instead of reading it from environment. You can use argparse to
> parse the command line arguments.
> 
>> +
>> +
>> +cfgBinaryGen()
> 
> This should be guarded by if __name__ == '__main__'.

Thanks for all the comments, I'll reformat all these patches and make 
the necessary changes.

-- 
Thanking You
Neha Malcom Francis

  reply	other threads:[~2022-04-19  2:50 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-06 12:29 [RESEND, RFC 0/8] Integration of sysfw and tispl with U-Boot Neha Malcom Francis
2022-04-06 12:29 ` [RESEND, RFC 1/8] tools: config: yaml: Add board config class to generate config binaries Neha Malcom Francis
2022-04-18 19:55   ` Alper Nebi Yasak
2022-04-19  2:49     ` Neha Malcom Francis [this message]
2022-04-06 12:29 ` [RESEND, RFC 2/8] binman: etype: sysfw: Add entry type for sysfw Neha Malcom Francis
2022-04-18 19:56   ` Alper Nebi Yasak
2022-04-19  2:49     ` Neha Malcom Francis
2022-04-06 12:29 ` [RESEND, RFC 3/8] schema: yaml: Add board config schema Neha Malcom Francis
2022-04-06 12:29 ` [RESEND, RFC 4/8] config: yaml: j721e_evm: Add board config for J721E EVM Neha Malcom Francis
2022-04-06 12:29 ` [RESEND, RFC 5/8] binman: sysfw: Add support for packaging tiboot3.bin and sysfw.itb Neha Malcom Francis
2022-04-18 19:56   ` Alper Nebi Yasak
2022-04-06 12:29 ` [RESEND, RFC 6/8] binman: dtsi: sysfw: j721e: Use binman to package sysfw.itb Neha Malcom Francis
2022-04-18 19:56   ` Alper Nebi Yasak
2022-04-06 12:29 ` [RESEND, RFC 7/8] binman: etype: dm: Add entry type for TI DM Neha Malcom Francis
2022-04-18 19:56   ` Alper Nebi Yasak
2022-04-06 12:29 ` [RESEND, RFC 8/8] binman: dtsi: tispl: j721e: Use binman to package tispl.bin Neha Malcom Francis
2022-04-18 19:57   ` Alper Nebi Yasak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=63d3bf8d-e70e-03d3-9c7a-c8cd66311d18@ti.com \
    --to=n-francis@ti.com \
    --cc=a-govindraju@ti.com \
    --cc=alpernebiyasak@gmail.com \
    --cc=joel.peshkin@broadcom.com \
    --cc=kishon@ti.com \
    --cc=kristo@kernel.org \
    --cc=marek.behun@nic.cz \
    --cc=mr.nuke.me@gmail.com \
    --cc=nm@ti.com \
    --cc=patrick.delaunay@foss.st.com \
    --cc=s-anna@ti.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    --cc=vigneshr@ti.com \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox