diff --git a/src/python/jw/pkg/cmds/Cmd.py b/src/python/jw/pkg/cmds/Cmd.py index ecd90de8..7fbb7e21 100644 --- a/src/python/jw/pkg/cmds/Cmd.py +++ b/src/python/jw/pkg/cmds/Cmd.py @@ -6,12 +6,19 @@ from ..App import App as Parent from ..CmdBase import CmdBase as Base if TYPE_CHECKING: + from typing import Iterable from ..lib.Distro import Distro class Cmd(Base): # export - def __init__(self, parent: Parent, name: str, help: str) -> None: - super().__init__(parent, name, help) + def __init__( + self, + parent: Parent, + name: str, + help: str, + aliases: Iterable[str] | None = None + ) -> None: + super().__init__(parent, name, help, aliases = aliases) async def _run(self, args): # Missing subcommand diff --git a/src/python/jw/pkg/lib/App.py b/src/python/jw/pkg/lib/App.py index 343dc5b0..ccf8a21d 100644 --- a/src/python/jw/pkg/lib/App.py +++ b/src/python/jw/pkg/lib/App.py @@ -56,6 +56,7 @@ class App: # export cmd.name, help = cmd.help, description = cmd.description, + aliases = cmd.aliases, formatter_class = ArgumentDefaultsHelpFormatter, ) parser.set_defaults(func = cmd.run) @@ -88,14 +89,24 @@ class App: # export for cmd in cmds: cmd.set_parent(parent) scs[cmd.name] = SubCommand(cmd, add_cmd_to_parser(cmd, subparsers)) + for alias in cmd.aliases: + scs[alias] = scs[cmd.name] if all: + seen: set[int] = set() for sc in scs.values(): - add_cmds_to_parser(sc.cmd, sc.parser, sc.cmd.children, all = all) + if id(sc) not in seen: + seen.add(id(sc)) + add_cmds_to_parser( + sc.cmd, sc.parser, sc.cmd.children, all = all + ) return args, unknown = self.__parser.parse_known_args() - if args.command in scs: - sc = scs[args.command] - add_cmds_to_parser(sc.cmd, sc.parser, sc.cmd.children, all = all) + cmd_name = getattr(args, 'command', None) + if cmd_name in scs: + sc = scs[cmd_name] + add_cmds_to_parser( + sc.cmd, sc.parser, sc.cmd.children, all = all + ) from .Cmd import AbstractCmd diff --git a/src/python/jw/pkg/lib/Cmd.py b/src/python/jw/pkg/lib/Cmd.py index 91beb310..9a3caa39 100644 --- a/src/python/jw/pkg/lib/Cmd.py +++ b/src/python/jw/pkg/lib/Cmd.py @@ -10,7 +10,7 @@ from .Types import LoadTypes, Types if TYPE_CHECKING: from argparse import ArgumentParser - from typing import Any + from typing import Any, Iterable from .App import App @@ -150,6 +150,13 @@ class AbstractCmd(abc.ABC): def description(self) -> str: return self._description() + def _aliases(self) -> Iterable[str]: + return [] + + @property + def aliases(self) -> Iterable[str]: + return self._aliases() + class Cmd(AbstractCmd): # export def __init__( @@ -157,12 +164,14 @@ class Cmd(AbstractCmd): # export parent: App | Cmd, name: str, help: str, - description: str | None = None + description: str | None = None, + aliases: Iterable[str] | None = None ) -> None: super().__init__(parent) self.__name = name self.__help = help self.__description = description if description else help + self.__aliases = aliases if aliases else [] def _name(self) -> str: return self.__name @@ -172,3 +181,6 @@ class Cmd(AbstractCmd): # export def _description(self) -> str: return self.__description + + def _aliases(self) -> Iterable[str]: + return self.__aliases