diff --git a/completions/_makekconfig.py.zsh b/completions/_makekconfig.py.zsh new file mode 100644 index 0000000..8b9e3a6 --- /dev/null +++ b/completions/_makekconfig.py.zsh @@ -0,0 +1,11 @@ +#compdef makekconfig.py + +function _makekconfig.py() { + _arguments \ + {-h,--help}'[print help text]' \ + {-q,--quick}'[only compile the subdirectory containing the Kconfig file]' \ + '1:Kconfig:_files -g "**/Kconfig"' \ + '*:Make Options:_make' +} + +_makekconfig.py "$@" diff --git a/makekconfig.py b/makekconfig.py new file mode 100755 index 0000000..71d56ba --- /dev/null +++ b/makekconfig.py @@ -0,0 +1,109 @@ +#!/usr/bin/python +import argparse +import pathlib +import re +import subprocess +import sys +import termcolor + +parser = argparse.ArgumentParser() +parser.add_argument("-q", "--quick", action="store_true", dest="quick", + help="Only compile the subdirectory containing the Kconfig file") +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() +Kconfig = pathlib.Path(Args.kconfig[0]) +Config = pathlib.Path("scripts/config").absolute() +Make = pathlib.Path("~/bin/makelinux.zsh").expanduser() +MakeArg = Args.makeargs + ([ f"{str(Kconfig.parent)}/" ] if Args.quick else [ ]) +Options = dict() +Colors = { "n" : "grey", "y" : "green", "m" : "cyan" } +Attrs = { "y" : [ "bold" ], "m" : [ "bold" ] } +NameLen = 0 + +if Kconfig.is_dir(): + Kconfig = Kconfig / "Kconfig" + +def assert_exists(path): + if not path.exists(): + print(f"Error: {path} does not exist!") + sys.exit(1) +assert_exists(Kconfig) +assert_exists(Make) +assert_exists(Config) + + +class Option: + def __init__(self, opt): + lines = opt.splitlines() + self.name = lines[0].strip() + self.type = lines[1].strip().split()[0] + self.state = "y" + self.res = None + + depends = re.search("\sdepends on (.*?)\n", opt).group(1).strip() + depends = [ d.strip() for d in re.split("[&&|=m|=y|=n]", depends) ] + self.depends = set([ d for d in depends if len(d) > 0 ]) + + def __repr__(self): + return f"{self.name}:{self.type}" + + def __lt__(self, rhs): + if self.name.endswith("DEBUG"): return False + if rhs.name.endswith("DEBUG"): return True + return self.name in rhs.dependencies() + + def dependencies(self): + ret = self.depends.copy() + for dep in self.depends: + if (opt := Options.get(dep)) is not None: + ret.update(opt.dependencies()) + return ret + + def disable(self): + subprocess.run([ Config ] + [ "--disable", self.name ]).check_returncode() + self.state = "n" + + def enable(self): + how = "--module" if self.type == "tristate" else "--enable" + subprocess.run([ Config ] + [ how, self.name ]).check_returncode() + self.state = "m" if self.type == "tristate" else "y" + + def print(self): + print(" ", end="") + termcolor.cprint(self.name, Colors.get(self.state), attrs=["bold", "dark"], end="") + termcolor.cprint("=", "white", attrs=["bold"], end="") + termcolor.cprint(self.state, Colors.get(self.state), attrs=["bold", "dark"]) + + def print_result(self): + result = ("Success", "green") if self.res == True else ("Failed", "red") + termcolor.cprint(" " + self.name + " ", Colors.get(self.state), attrs=["bold", "dark"], end="") + termcolor.cprint(" " * (NameLen - len(self.name)), "grey", attrs=["underline"], end="") + termcolor.cprint(" " + result[0], result[1], attrs=["bold", "dark"]) + +with open(Kconfig) as f: + regex = re.compile("\nconfig") + 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 = list(Options.values()) +options.sort() + +def make_opt(option): + option.enable() + print() + for o in options: o.print() + subprocess.run([ Make ] + [ "olddefconfig" ]).check_returncode() + subprocess.run([ Make ] + MakeArg).check_returncode() + option.res = True + +try: + for opt in options: NameLen = max(NameLen, len(opt.name) + 2) + for opt in options: opt.disable() + for opt in options: make_opt(opt) +except Exception as e: + print(str(e)) +finally: + termcolor.cprint(f"\nKconfig Results:", "yellow", attrs=["bold", "underline"]) + for opt in options: opt.print_result()