makekconfig.py: Various Updates

* Python flake8 style fixes
* Update for the .local/bin change

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
Anna Schumaker 2023-07-19 11:42:34 -04:00
parent 941308e246
commit 70dfceccef
1 changed files with 81 additions and 47 deletions

View File

@ -1,117 +1,151 @@
#!/usr/bin/python #!/usr/bin/python
"""Iterate through KConfig options, enabling them one by one."""
import argparse import argparse
import pathlib import pathlib
import re import re
import subprocess import subprocess
import sys import sys
import termcolor import termcolor
import typing
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-q", "--quick", action="store_true", dest="quick", parser.add_argument("-q", "--quick", action="store_true", dest="quick",
help="Only compile the subdirectory containing the Kconfig file") help="Only compile the subdirectory "
parser.add_argument("kconfig", metavar="Kconfig", nargs=1, help="Path to Kconfig file") "containing the Kconfig file")
parser.add_argument("makeargs", metavar="Make Arguments", nargs="*", help="Options to pass to make") parser.add_argument("kconfig", metavar="Kconfig", nargs=1,
help="Path to Kconfig file")
parser.add_argument("makeargs", metavar="Make Arguments", nargs="*",
help="Options to pass to make")
Args = parser.parse_args() Args = parser.parse_args()
Kconfig = pathlib.Path(Args.kconfig[0]) Kconfig = pathlib.Path(Args.kconfig[0])
Config = pathlib.Path("scripts/config").absolute() Config = pathlib.Path("scripts/config").absolute()
Make = pathlib.Path("~/bin/makelinux.zsh").expanduser() Make = pathlib.Path("~/.local/bin/makelinux.zsh").expanduser()
MakeArg = Args.makeargs + ([ f"{str(Kconfig)}/" ] if Args.quick else [ ]) MakeArg = Args.makeargs + ([f"{str(Kconfig)}/"] if Args.quick else [])
Options = dict() Options = dict()
Colors = { "n" : "grey", "y" : "green", "m" : "cyan" } Colors = {"n": "dark_grey", "y": "green", "m": "cyan"}
Attrs = { "y" : [ "bold" ], "m" : [ "bold" ] } Attrs = {"y": ["bold"], "m": ["bold"]}
NameLen = 0 NameLen = 0
if Kconfig.is_dir(): if Kconfig.is_dir():
Kconfig = Kconfig / "Kconfig" Kconfig = Kconfig / "Kconfig"
def assert_exists(path):
for path in [Kconfig, Make, Config]:
if not path.exists(): if not path.exists():
print(f"Error: {path} does not exist!") print(f"Error: {path} does not exist!")
sys.exit(1) sys.exit(1)
assert_exists(Kconfig)
assert_exists(Make)
assert_exists(Config)
class Option: class Option:
def __init__(self, opt): """Represents a single CONFIG_* KConfig Option."""
def __init__(self, opt: str):
"""Initialize our Option class."""
lines = opt.splitlines() lines = opt.splitlines()
self.name = lines[0].strip() self.name = lines[0].strip()
self.type = lines[1].strip().split()[0] self.type = lines[1].strip().split()[0]
self.state = "y" self.state = "y"
self.res = None self.res = None
if search := re.search("\sdepends on (.*?)\n", opt): if search := re.search(r"\sdepends on (.*?)\n", opt):
depends = search.group(1).strip() depends = search.group(1).strip()
depends = [ d.strip() for d in re.split("[&&|=m|=y|=n]", depends) ] depends = [d.strip() for d in re.split("[&&|=m|=y|=n]", depends)]
self.depends = set([ d for d in depends if len(d) > 0 ]) self.depends = set([d for d in depends if len(d) > 0])
else: else:
self.depends = set() self.depends = set()
def __repr__(self): def __repr__(self) -> str:
"""Return a string representation of this Option."""
return f"{self.name}:{self.type}" return f"{self.name}:{self.type}"
def __lt__(self, rhs): def __lt__(self, rhs: typing.Self) -> bool:
if self.name.endswith("DEBUG"): return False """Check if this option is less than the `rhs` option."""
if rhs.name.endswith("DEBUG"): return True if self.name.endswith("DEBUG"):
return False
if rhs.name.endswith("DEBUG"):
return True
return self.name in rhs.dependencies() return self.name in rhs.dependencies()
def dependencies(self): def dependencies(self) -> set[typing.Self]:
"""Get a set of dependencies for this Option."""
ret = self.depends.copy() ret = self.depends.copy()
for dep in self.depends: for dep in self.depends:
if (opt := Options.get(dep)) is not None: if (opt := Options.get(dep)) is not None:
ret.update(opt.dependencies()) ret.update(opt.dependencies())
return ret return ret
def disable(self): def disable(self) -> None:
subprocess.run([ Config ] + [ "--disable", self.name ]).check_returncode() """Disable this Option."""
subprocess.run([Config] + ["--disable", self.name]).check_returncode()
self.state = "n" self.state = "n"
def enable(self): def enable(self) -> None:
"""Enable this Option."""
how = "--module" if self.type == "tristate" else "--enable" how = "--module" if self.type == "tristate" else "--enable"
subprocess.run([ Config ] + [ how, self.name ]).check_returncode() subprocess.run([Config] + [how, self.name]).check_returncode()
self.state = "m" if self.type == "tristate" else "y" self.state = "m" if self.type == "tristate" else "y"
def print(self): def print(self) -> None:
"""Print out this option (in color!)."""
print(" ", end="") print(" ", end="")
termcolor.cprint(self.name, Colors.get(self.state), attrs=["bold", "dark"], end="") termcolor.cprint(self.name, Colors.get(self.state),
attrs=["bold", "dark"], end="")
termcolor.cprint("=", "white", attrs=["bold"], end="") termcolor.cprint("=", "white", attrs=["bold"], end="")
termcolor.cprint(self.state, Colors.get(self.state), attrs=["bold", "dark"]) termcolor.cprint(self.state, Colors.get(self.state),
attrs=["bold", "dark"])
def print_result(self) -> None:
"""Print out this option and result."""
attrs = [] if self.res is None else ["bold"]
def print_result(self):
match self.res: match self.res:
case True: result = ("Success", "green") case True: result = ("Success", "green")
case False: result = ("Failed", "red") case False: result = ("Failed", "red")
case _: result = ("Not Run", "yellow") case _: result = ("Not Run", "yellow")
termcolor.cprint(" " + self.name + " ", Colors.get(self.state), attrs=["bold", "dark"], end="")
termcolor.cprint(" " * (NameLen - len(self.name)), "grey", attrs=["underline"], end="") termcolor.cprint(" " + self.name + " ", Colors.get(self.state),
termcolor.cprint(" " + result[0], result[1], attrs=["bold", "dark"]) attrs=attrs, end="")
termcolor.cprint(" " * (NameLen - len(self.name)), "grey",
attrs=["underline"], end="")
termcolor.cprint(" " + result[0], result[1], attrs=attrs)
with open(Kconfig) as f: with open(Kconfig) as f:
regex = re.compile("\nconfig") regex = re.compile("\nconfig")
opts = [ Option(opt) for opt in regex.split(f.read()) if opt[0] != "#" ] opts = [Option(opt) for opt in regex.split(f.read()) if opt[0] != "#"]
Options = { opt.name:opt for opt in opts if opt.type in [ "bool", "tristate" ]} Options = {opt.name: opt for opt in opts
if opt.type in ["bool", "tristate"]}
options = list(Options.values()) options = list(sorted(Options.values()))
options.sort()
def make_opt(option):
def make_opt(option: Option) -> None:
"""Enable and build a single option."""
option.enable() option.enable()
print() print()
for o in options: o.print() for o in options:
o.print()
option.res = False option.res = False
subprocess.run([ Make ] + [ "olddefconfig" ]).check_returncode() subprocess.run([Make] + ["olddefconfig"]).check_returncode()
subprocess.run([ Make ] + MakeArg).check_returncode() subprocess.run([Make] + MakeArg).check_returncode()
option.res = True option.res = True
try: try:
for opt in options: NameLen = max(NameLen, len(opt.name) + 2) for opt in options:
for opt in options: opt.disable() NameLen = max(NameLen, len(opt.name) + 2)
for opt in options: make_opt(opt) opt.disable()
for opt in options:
make_opt(opt)
except Exception as e: except Exception as e:
print(str(e)) print(str(e))
finally: finally:
termcolor.cprint(f"\nKconfig Results:", "yellow", attrs=["bold", "underline"]) print()
for opt in options: opt.print_result() termcolor.cprint("Kconfig Results:", "yellow", attrs=["bold", "underline"])
if False in [ opt.res for opt in options ]: sys.exit(1) for opt in options:
opt.print_result()
if False in [opt.res for opt in options]:
sys.exit(1)