diff --git a/nut/__main__.py b/nut/__main__.py index d4c7761..ee4f07c 100644 --- a/nut/__main__.py +++ b/nut/__main__.py @@ -1,7 +1,12 @@ -from cli import CLI +from .cli import CLI + +def help_text(): + return [ + "%bold%%cyan%nut CLI ... you expected a help menu? cute :3%reset%" + ] def main(): - cli = CLI("nut") + cli = CLI(help_callback=help_text) cli.command("run") \ .flag("debug", "d") \ @@ -12,17 +17,13 @@ def main(): return cli.run() -def cmd_run(subcommands, flags): - print("RUN") - print("sub:", subcommands) - print("flags:", flags) +def cmd_run(args, flags): + print("RUN", args, flags) return 0 -def cmd_build(subcommands, flags): - print("BUILD") - print("sub:", subcommands) - print("flags:", flags) +def cmd_build(args, flags): + print("BUILD", args, flags) return 0 if __name__ == "__main__": - raise SystemExit(main()) \ No newline at end of file + raise SystemExit(main()) diff --git a/nut/cli.py b/nut/cli.py index 8bea7d1..25d2c7e 100644 --- a/nut/cli.py +++ b/nut/cli.py @@ -1,46 +1,78 @@ import argparse +from colorama import Fore, Style, init + +init(autoreset=True) class CLI: - def __init__(self, prog="nut"): - self.parser = argparse.ArgumentParser(prog=prog) - self.subparsers = self.parser.add_subparsers(dest="command", required=True) + def __init__(self, prog="nut", help_callback=None): + self.parser = argparse.ArgumentParser(prog=prog, add_help=False) + self.subparsers = self.parser.add_subparsers(dest="command") + + self.help_callback = help_callback + + self.parser.add_argument("-h", "--help", action="store_true") def command(self, name): - parser = self.subparsers.add_parser(name) - + parser = self.subparsers.add_parser(name, add_help=False) cmd = _Command(parser) return cmd def run(self): args = self.parser.parse_args() - # extract structured data - sub_args = getattr(args, "_args", []) + if getattr(args, "help", False) or not getattr(args, "command", None): + if self.help_callback: + for line in self.help_callback(): + print(self._color(line)) + else: + self.parser.print_help() + return 0 + + args_list = getattr(args, "_args", []) + flags = { k: v for k, v in vars(args).items() - if k not in ("command", "func", "_args") + if k not in ("command", "func", "_args", "help") } - return args.func(sub_args, flags) + return args.func(args_list, flags) + + def _color(self, text: str) -> str: + mapping = { + "%red%": Fore.RED, + "%green%": Fore.GREEN, + "%yellow%": Fore.YELLOW, + "%blue%": Fore.BLUE, + "%magenta%": Fore.MAGENTA, + "%cyan%": Fore.CYAN, + "%white%": Fore.WHITE, + "%reset%": Style.RESET_ALL, + "%bold%": Style.BRIGHT, + } + + for key, value in mapping.items(): + text = text.replace(key, value) + + return text class _Command: def __init__(self, parser): self.parser = parser self.parser.set_defaults(func=self._missing) - # default catch-all args self.parser.add_argument("_args", nargs="*") + self.parser.add_argument("-h", "--help", action="store_true") def arg(self, name, **kwargs): self.parser.add_argument(name, **kwargs) return self def flag(self, name, short=None): - flags = [f"--{name}"] + opts = [f"--{name}"] if short: - flags.append(f"-{short}") + opts.append(f"-{short}") - self.parser.add_argument(*flags, action="store_true") + self.parser.add_argument(*opts, action="store_true") return self def handle(self, func): @@ -48,4 +80,5 @@ class _Command: return self def _missing(self, *_): - raise RuntimeError("No handler defined for command") \ No newline at end of file + raise RuntimeError("No handler defined") + \ No newline at end of file diff --git a/setup.py b/setup.py index afd1c31..5c24b6a 100644 --- a/setup.py +++ b/setup.py @@ -7,5 +7,5 @@ setup( author="Chipperfluff", packages=find_packages(), python_requires=">=3.8", - install_requires=["chipenv"], + install_requires=["chipenv", "colorama", "PyYAML"], )