Refactor CLI implementation: add help callback and improve help handling; update setup.py dependencies
This commit is contained in:
parent
c9176dbbce
commit
37eaee3dbe
@ -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():
|
def main():
|
||||||
cli = CLI("nut")
|
cli = CLI(help_callback=help_text)
|
||||||
|
|
||||||
cli.command("run") \
|
cli.command("run") \
|
||||||
.flag("debug", "d") \
|
.flag("debug", "d") \
|
||||||
@ -12,17 +17,13 @@ def main():
|
|||||||
|
|
||||||
return cli.run()
|
return cli.run()
|
||||||
|
|
||||||
def cmd_run(subcommands, flags):
|
def cmd_run(args, flags):
|
||||||
print("RUN")
|
print("RUN", args, flags)
|
||||||
print("sub:", subcommands)
|
|
||||||
print("flags:", flags)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def cmd_build(subcommands, flags):
|
def cmd_build(args, flags):
|
||||||
print("BUILD")
|
print("BUILD", args, flags)
|
||||||
print("sub:", subcommands)
|
|
||||||
print("flags:", flags)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
raise SystemExit(main())
|
raise SystemExit(main())
|
||||||
|
|||||||
61
nut/cli.py
61
nut/cli.py
@ -1,46 +1,78 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
from colorama import Fore, Style, init
|
||||||
|
|
||||||
|
init(autoreset=True)
|
||||||
|
|
||||||
class CLI:
|
class CLI:
|
||||||
def __init__(self, prog="nut"):
|
def __init__(self, prog="nut", help_callback=None):
|
||||||
self.parser = argparse.ArgumentParser(prog=prog)
|
self.parser = argparse.ArgumentParser(prog=prog, add_help=False)
|
||||||
self.subparsers = self.parser.add_subparsers(dest="command", required=True)
|
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):
|
def command(self, name):
|
||||||
parser = self.subparsers.add_parser(name)
|
parser = self.subparsers.add_parser(name, add_help=False)
|
||||||
|
|
||||||
cmd = _Command(parser)
|
cmd = _Command(parser)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
args = self.parser.parse_args()
|
args = self.parser.parse_args()
|
||||||
|
|
||||||
# extract structured data
|
if getattr(args, "help", False) or not getattr(args, "command", None):
|
||||||
sub_args = getattr(args, "_args", [])
|
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 = {
|
flags = {
|
||||||
k: v for k, v in vars(args).items()
|
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:
|
class _Command:
|
||||||
def __init__(self, parser):
|
def __init__(self, parser):
|
||||||
self.parser = parser
|
self.parser = parser
|
||||||
self.parser.set_defaults(func=self._missing)
|
self.parser.set_defaults(func=self._missing)
|
||||||
|
|
||||||
# default catch-all args
|
|
||||||
self.parser.add_argument("_args", nargs="*")
|
self.parser.add_argument("_args", nargs="*")
|
||||||
|
self.parser.add_argument("-h", "--help", action="store_true")
|
||||||
|
|
||||||
def arg(self, name, **kwargs):
|
def arg(self, name, **kwargs):
|
||||||
self.parser.add_argument(name, **kwargs)
|
self.parser.add_argument(name, **kwargs)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def flag(self, name, short=None):
|
def flag(self, name, short=None):
|
||||||
flags = [f"--{name}"]
|
opts = [f"--{name}"]
|
||||||
if short:
|
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
|
return self
|
||||||
|
|
||||||
def handle(self, func):
|
def handle(self, func):
|
||||||
@ -48,4 +80,5 @@ class _Command:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def _missing(self, *_):
|
def _missing(self, *_):
|
||||||
raise RuntimeError("No handler defined for command")
|
raise RuntimeError("No handler defined")
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user