From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jean-Jacques Hiblot Date: Thu, 18 Oct 2018 14:03:35 +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: <2cae025c-61c4-9584-3a73-6d619b5fba0c@ti.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable 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. It is very similar indeed and they certainly overlap. When time permits,=20 I'll look at the possibility to re-use=C2=A0 this code in buildman. > >> 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 n= ame. >> +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 informati= on >> +about the soc, vendor etc. for each of them. >> +Then it walks this list and outputs the defconfigs for which the info m= atch >> +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 filte= rs >> + >> +$ tools/find_defconfigs.py --soc 'omap[45]|k3' --vendor '(?!ti)' --sh= ow-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 =3D status >> + self.arch =3D arch >> + self.cpu =3D cpu >> + self.soc =3D soc >> + self.vendor =3D vendor >> + self.board =3D board >> + self.target =3D target >> + self.defconfig =3D "{}_defconfig".format(target) >> + self.options =3D options >> + self.maintainer =3D maintainer >> + >> + def show(self, sep=3D' | ', props=3DNone): > 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? > >> + >> + 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 =3D getattr(self, prop) >> + if not val or val =3D=3D "-": >> + return False >> + if not r.match(val): >> + return False >> + return True >> + >> + >> +def get_all_boards(): >> + """ extract a list of boards from 'boards.cfg' """ >> + result =3D [] >> + 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] =3D=3D "#": >> + continue >> + props =3D 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=3D"store_true") >> + parser.add_argument("--soc", >> + help=3D"regexp to filter on SoC. ex: 'omap[45]'= to inspect omap5 and omap5 targets") >> + parser.add_argument("--vendor", help=3D"regexp to filter on Vendor.= ") >> + parser.add_argument("--arch", help=3D"regexp to filter on Arch") >> + parser.add_argument("--cpu", help=3D"regexp to filter on CPU") >> + parser.add_argument("--board", help=3D"regexp to filter on Board") >> + parser.add_argument("--target", >> + help=3D"regexp to filter on Target (defconfig f= ilename without the '_defconfig' suffix)") >> + >> + >> +def get_matching_boards(args, fields=3Dget_default_options()): >> + # compile a list of regexp used to filter the targets >> + boards =3D [] >> + rules =3D [] >> + for f in fields: >> + arg =3D 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 =3D argparse.ArgumentParser(description=3D"Show CONFIG optio= ns usage") >> + update_parser_with_default_options(parser) >> + parser.add_argument("--maintainer", help=3D"regexp to filter on mai= ntainer.") >> + parser.add_argument("--status", help=3D"regexp to filter on status.= ") >> + parser.add_argument("--show-details", help=3D"show fields used as f= ilter", >> + action=3D"store_true") >> + parser.add_argument("--show-all", help=3D"show all fields", >> + action=3D"store_true") >> + args =3D parser.parse_args() >> + fields =3D get_default_options() + ["status", "maintainer"] >> + >> + for b in get_matching_boards(args, fields): >> + if args.show_details: >> + props =3D [f for f in fields if getattr(args, f)] >> + b.show(props=3Dprops) >> + elif args.show_all: >> + b.show() >> + else: >> + print(b.defconfig) >> + >> +if __name__ =3D=3D '__main__': >> + main() >> -- >> 2.7.4 >> > Regards, > Simon >