[U-Boot] [RFC PATCH v2 2/3] tools: Add a tool to get a list of defconfigs based on filters
Jean-Jacques Hiblot
jjhiblot at ti.com
Thu Oct 18 14:36:45 UTC 2018
On 09/10/2018 18:20, Simon Glass wrote:
> Hi Jean-Jacques,
>
> On 3 October 2018 at 07:53, Jean-Jacques Hiblot <jjhiblot at ti.com> wrote:
>> The possible filters are "arch", "vendor", "soc", "cpu" and "arch".
>>
>> The list of all the defconfigs is read from boards.cfg. If this file
>> doesn't exist, then tools/genboardscfg.py is called to generate it.
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot at ti.com>
>> ---
>>
>> Changes in v2: None
>>
>> tools/find_defconfigs.py | 167 +++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 167 insertions(+)
>> create mode 100755 tools/find_defconfigs.py
> This looks good, but I have some style comments below.
>
> Also it seems to do a similar thing to tools/buildman/board.py. Should
> we replace that impl with what you have here? It looks more flexible
> that what buildman currently provides.
>
>> diff --git a/tools/find_defconfigs.py b/tools/find_defconfigs.py
>> new file mode 100755
>> index 0000000..9d68cef
>> --- /dev/null
>> +++ b/tools/find_defconfigs.py
>> @@ -0,0 +1,167 @@
>> +#!/usr/bin/env python
>> +# SPDX-License-Identifier: GPL-2.0+
>> +#
>> +# Author: JJ Hiblot <jjhiblot at ti.com>
>> +#
>> +
>> +"""
>> +Output a list of defconfig matching criteria.
> I think you mean defconfig-matching?
>
>> +
>> +The possible criteria are soc, vendor, arch, cpu, board and defconfig name.
>> +The criteria are expressed as regexp, allowing for complex selection.
>> +
>> +How does it work?
>> +-----------------
>> +
>> +This tools uses the boards.cfg file produced by tools/genboardscfg.py
>> +It reads the file to get a list of all the defconfigs and the information
>> +about the soc, vendor etc. for each of them.
>> +Then it walks this list and outputs the defconfigs for which the info match
>> +the regexp passed to the program.
>> +
>> +examples:
>> +---------
>> +
>> +1) Get the list of defconfigs for boards built around omap5, omap4 and k3, not built by TI
>> +
>> +$ tools/find_defconfigs.py --soc 'omap[45]|k3' --vendor '(?!ti)'
>> +kc1_defconfig
>> +duovero_defconfig
>> +cl-som-am57x_defconfig
>> +cm_t54_defconfig
>> +
>> +2) Same list but iwth more details on the items that were used as filters
>> +
>> +$ tools/find_defconfigs.py --soc 'omap[45]|k3' --vendor '(?!ti)' --show-details
>> +kc1_defconfig | omap4 | amazon
>> +duovero_defconfig | omap4 | gumstix
>> +cl-som-am57x_defconfig | omap5 | compulab
>> +cm_t54_defconfig | omap5 | compulab
>> +
>> +
>> +"""
>> +
>> +import re
>> +import os
>> +import argparse
> Please sort these
>
>> +
>> +
>> +class board:
>> +
> Need a class comment here, also use Board since it is a class name
>
>> + def __init__(self, status, arch, cpu, soc,
>> + vendor, board, target, options, maintainer):
>> + self.status = status
>> + self.arch = arch
>> + self.cpu = cpu
>> + self.soc = soc
>> + self.vendor = vendor
>> + self.board = board
>> + self.target = target
>> + self.defconfig = "{}_defconfig".format(target)
>> + self.options = options
>> + self.maintainer = maintainer
>> +
>> + def show(self, sep=' | ', props=None):
> Function comment (see other tools for style). Need to document args
> and any return value.
>
>> + if not props:
>> + print(
>> + sep.join([self.defconfig,
>> + self.vendor,
>> + self.arch,
>> + self.cpu,
>> + self.soc,
>> + self.board,
>> + self.status,
>> + self.maintainer]))
>> + else:
>> + print(sep.join([self.defconfig] + [getattr(self, prop) for prop in props]))
> Does this need to import print_function from __future__ for Python 2?
No it doesn't. You can run this program as-is with python2 or python3.
>
>> +
>> + def cleanup(self):
>> + """ remove the directory in which the cfg files have been built """
> Please use comment style from other tools. Same below.
>
>> + shutil.rmtree(self.temp_dir)
>> +
>> + def match(self, rules):
>> + """ return True if the board match all the criteria """
>> + for prop, r in rules:
>> + val = getattr(self, prop)
>> + if not val or val == "-":
>> + return False
>> + if not r.match(val):
>> + return False
>> + return True
>> +
>> +
>> +def get_all_boards():
>> + """ extract a list of boards from 'boards.cfg' """
>> + result = []
>> + if not os.path.isfile("boards.cfg"):
>> + os.system('tools/genboardscfg.py')
>> +
>> + with open('boards.cfg', 'r') as f:
>> + for l in f.readlines():
>> + if not l or l[0] == "#":
>> + continue
>> + props = l.strip().split(None, 8)
>> + if not props:
>> + continue
>> + if len(props) < 9:
>> + props.extend(["-"] * (9 - len(props)))
>> + result.append(board(*props))
>> + return result
>> +
>> +
>> +def get_default_options():
>> + return ["board", "soc", "vendor", "arch", "cpu", "target"]
>> +
>> +
>> +def update_parser_with_default_options(parser):
>> + parser.add_argument('-i', '--ignore-case', action="store_true")
>> + parser.add_argument("--soc",
>> + help="regexp to filter on SoC. ex: 'omap[45]' to inspect omap5 and omap5 targets")
>> + parser.add_argument("--vendor", help="regexp to filter on Vendor.")
>> + parser.add_argument("--arch", help="regexp to filter on Arch")
>> + parser.add_argument("--cpu", help="regexp to filter on CPU")
>> + parser.add_argument("--board", help="regexp to filter on Board")
>> + parser.add_argument("--target",
>> + help="regexp to filter on Target (defconfig filename without the '_defconfig' suffix)")
>> +
>> +
>> +def get_matching_boards(args, fields=get_default_options()):
>> + # compile a list of regexp used to filter the targets
>> + boards = []
>> + rules = []
>> + for f in fields:
>> + arg = getattr(args, f)
>> + if arg:
>> + rules.append((f, re.compile("\\b{}\\b".format(arg),
>> + re.IGNORECASE if args.ignore_case else 0)))
>> +
>> + # get a list of boards matching the rules
>> + for b in get_all_boards():
>> + if b.match(rules):
>> + boards.append(b)
>> + return boards
>> +
>> +
>> +def main():
>> + parser = argparse.ArgumentParser(description="Show CONFIG options usage")
>> + update_parser_with_default_options(parser)
>> + parser.add_argument("--maintainer", help="regexp to filter on maintainer.")
>> + parser.add_argument("--status", help="regexp to filter on status.")
>> + parser.add_argument("--show-details", help="show fields used as filter",
>> + action="store_true")
>> + parser.add_argument("--show-all", help="show all fields",
>> + action="store_true")
>> + args = parser.parse_args()
>> + fields = get_default_options() + ["status", "maintainer"]
>> +
>> + for b in get_matching_boards(args, fields):
>> + if args.show_details:
>> + props = [f for f in fields if getattr(args, f)]
>> + b.show(props=props)
>> + elif args.show_all:
>> + b.show()
>> + else:
>> + print(b.defconfig)
>> +
>> +if __name__ == '__main__':
>> + main()
>> --
>> 2.7.4
>>
> Regards,
> Simon
>
More information about the U-Boot
mailing list