diff --git a/niar/__init__.py b/niar/__init__.py index aa239e1..36415c7 100644 --- a/niar/__init__.py +++ b/niar/__init__.py @@ -12,15 +12,13 @@ def cli(np: Project): subparsers = parser.add_subparsers(required=True) build.add_arguments( - np, - subparsers.add_parser( - "build", help="build the design, and optionally program it" - ), - ) + np, subparsers.add_parser("build", help="build the design, and optionally program it")) if np.cxxrtl_targets: cxxrtl.add_arguments( - np, subparsers.add_parser("cxxrtl", help="run the C++ simulator tests") - ) + np, subparsers.add_parser("cxxrtl", help="run the C++ simulator tests")) + + for command in np.commands: + command.add_arguments(np, subparsers.add_parser(command.name, help=command.help)) args = parser.parse_args() args.func(args) diff --git a/niar/command.py b/niar/command.py new file mode 100644 index 0000000..8acc1da --- /dev/null +++ b/niar/command.py @@ -0,0 +1,13 @@ +from typing import Callable + +__all__ = ["Command"] + +class Command: + add_arguments: Callable + name: str + help: str + + def __init__(self, *, add_arguments, help): + self.add_arguments = add_arguments + self.name = add_arguments.__name__ + self.help = help diff --git a/niar/project.py b/niar/project.py index ff84eea..9ef1e28 100644 --- a/niar/project.py +++ b/niar/project.py @@ -6,6 +6,7 @@ from typing import Optional from amaranth import Elaboratable from amaranth.build import Platform +from .command import Command from .cxxrtl_platform import CxxrtlPlatform __all__ = ["Project"] @@ -84,6 +85,7 @@ class Project: targets: list[type[Platform]] cxxrtl_targets: list[type[CxxrtlPlatform]] = [] externals: list[str] = [] + commands: list[Command] = [] origin: Path @@ -118,6 +120,12 @@ class Project: required=False, isinstance_list=str, ), + Prop( + "commands", + description="a list of Command objects which extend the CLI", + required=False, + isinstance_list=Command, + ), ] def __init_subclass__(cls): @@ -164,6 +172,15 @@ class Project: def path(self): return ProjectPath(self) + @classmethod + def command(cls, *, help): + def inner(add_arguments): + cls.commands.append(Command( + add_arguments=add_arguments, + help=help, + )) + return inner + class ProjectPath: def __init__(self, np: Project):