From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jean-Jacques Hiblot Date: Thu, 18 Oct 2018 16:36:45 +0200 Subject: [U-Boot] [RFC PATCH v2 2/3] tools: Add a tool to get a list of defconfigs based on filters In-Reply-To: References: <1538574832-21910-1-git-send-email-jjhiblot@ti.com> <1538574832-21910-3-git-send-email-jjhiblot@ti.com> Message-ID: <942ecafc-5f59-430c-dc8c-6f5d01aabfbc@ti.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 09/10/2018 18:20, Simon Glass wrote: > Hi Jean-Jacques, > > On 3 October 2018 at 07:53, Jean-Jacques Hiblot 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 >> --- >> >> 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 >> +# >> + >> +""" >> +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 >