Skip to content

Commit

Permalink
small cli api improvements (#339)
Browse files Browse the repository at this point in the history
the existing abstractions help separate dependencies, but these small
functions should help avoid a lot of boilerplate cli code.

**the cli.CommandContainer no longer extends apps.Container because
we're trying to decouple cli from apps packages so we don't get tied to
the same interfaces.**
  • Loading branch information
ms-lolo authored Oct 1, 2024
1 parent a4de54b commit 25b599a
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 209 deletions.
4 changes: 3 additions & 1 deletion rats-apps/src/python/rats/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
from ._annotations import CommandId, command, get_class_commands, get_class_groups, group
from ._app import ClickApp
from ._container import CommandContainer
from ._plugin import PluginContainer, PluginServices
from ._plugin import PluginContainer, PluginServices, attach, create_group

__all__ = [
"PluginContainer",
"command",
"get_class_commands",
"get_class_groups",
"create_group",
"attach",
"group",
"ClickApp",
"PluginServices",
Expand Down
4 changes: 1 addition & 3 deletions rats-apps/src/python/rats/cli/_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@

import click

from rats import apps

from ._annotations import get_class_commands

logger = logging.getLogger(__name__)


class CommandContainer(apps.Container, Protocol):
class CommandContainer(Protocol):
"""A container that can attach click commands to a click group."""

def attach(self, group: click.Group) -> None:
Expand Down
17 changes: 17 additions & 0 deletions rats-apps/src/python/rats/cli/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

from rats import apps

from ._container import CommandContainer


def create_group(group: click.Group, container: CommandContainer) -> click.Group:
container.attach(group)
return group


def attach(
group: click.Group,
command: click.Command | click.Group,
*commands: click.Command | click.Group,
) -> None:
group.add_command(command)
for c in commands:
group.add_command(c)


@apps.autoscope
class _PluginEvents:
Expand Down
263 changes: 142 additions & 121 deletions rats-devtools/poetry.lock

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions rats-devtools/src/python/rats/amlruntime/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,27 @@ def __init__(self, app: apps.Container) -> None:
self._app = app

@apps.group(devtools.PluginServices.EVENTS.OPENING)
def _runtime_cli(self) -> Iterator[apps.Executable]:
def run() -> None:
amlruntime = self._app.get(PluginServices.MAIN_CLICK)
parent = self._app.get(devtools.PluginServices.MAIN_CLICK)
parent.add_command(cast(click.Command, amlruntime))

yield apps.App(run)
def _on_open(self) -> Iterator[apps.Executable]:
yield apps.App(
lambda: cli.attach(
self._app.get(PluginServices.MAIN_CLICK),
self._app.get(devtools.PluginServices.MAIN_CLICK),
)
)

@apps.service(PluginServices.MAIN_EXE)
def _main_exe(self) -> apps.Executable:
return apps.App(lambda: self._app.get(PluginServices.MAIN_CLICK)())

@apps.service(PluginServices.MAIN_CLICK)
def _main_click(self) -> click.Group:
command_container = self._app.get(PluginServices.COMMANDS)
amlrunner = click.Group(
"aml-runtime",
help="run executables and groups on AzureML",
return cli.create_group(
click.Group(
"aml-runtime",
help="run executables and groups on AzureML",
),
self._app.get(PluginServices.COMMANDS),
)
command_container.attach(amlrunner)
return amlrunner

@apps.service(PluginServices.COMMANDS)
def _commands(self) -> cli.CommandContainer:
Expand Down
34 changes: 14 additions & 20 deletions rats-devtools/src/python/rats/ci/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ def __init__(self, app: apps.Container) -> None:

@apps.group(devtools.PluginServices.EVENTS.OPENING)
def _on_open(self) -> Iterator[apps.Executable]:
def run() -> None:
parent = self._app.get(devtools.PluginServices.MAIN_CLICK)
ci = self._app.get(PluginServices.MAIN_CLICK)
parent.add_command(ci)

yield apps.App(run)
yield apps.App(
lambda: cli.attach(
self._app.get(devtools.PluginServices.MAIN_CLICK),
self._app.get(PluginServices.MAIN_CLICK),
)
)

@apps.service(PluginServices.COMMANDS)
def _commands(self) -> cli.CommandContainer:
Expand Down Expand Up @@ -75,15 +75,9 @@ def _ruff_fix(self) -> Iterator[tuple[str, ...]]:
yield "ruff", "check", "--fix", "--unsafe-fixes"

@apps.fallback_group(PluginServices.CONFIGS.CHECK)
def _ruff_format_check(self) -> Iterator[tuple[str, ...]]:
def _default_checks(self) -> Iterator[tuple[str, ...]]:
yield "ruff", "format", "--check"

@apps.fallback_group(PluginServices.CONFIGS.CHECK)
def _ruff_check(self) -> Iterator[tuple[str, ...]]:
yield "ruff", "check"

@apps.fallback_group(PluginServices.CONFIGS.CHECK)
def _pyright(self) -> Iterator[tuple[str, ...]]:
yield ("pyright",)

@apps.fallback_group(PluginServices.CONFIGS.TEST)
Expand All @@ -96,11 +90,11 @@ def _main_exe(self) -> apps.Executable:

@apps.service(PluginServices.MAIN_CLICK)
def _main_click(self) -> click.Group:
command_container = self._app.get(PluginServices.COMMANDS)
ci = click.Group(
"ci",
help="commands used during ci/cd",
chain=True, # allow us to run more than one ci subcommand at once
return cli.create_group(
click.Group(
"ci",
help="commands used during ci/cd",
chain=True, # allow us to run more than one ci subcommand at once
),
self._app.get(PluginServices.COMMANDS),
)
command_container.attach(ci)
return ci
18 changes: 6 additions & 12 deletions rats-devtools/src/python/rats/devtools/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,13 @@ def _main_exe(self) -> apps.Executable:

@apps.service(PluginServices.MAIN_CLICK)
def _main_click(self) -> click.Group:
root = click.Group(
"rats-devtools",
help="develop your ideas with ease",
return cli.create_group(
click.Group(
"rats-devtools",
help="develop your ideas with ease",
),
self._app.get(PluginServices.COMMANDS),
)
return root

@apps.group(PluginServices.EVENTS.OPENING)
def _on_open(self) -> Iterator[apps.Executable]:
def run() -> None:
parent = self._app.get(PluginServices.MAIN_CLICK)
self._app.get(PluginServices.COMMANDS).attach(parent)

yield apps.App(run)

@apps.service(PluginServices.COMMANDS)
def _commands(self) -> cli.CommandContainer:
Expand Down
25 changes: 12 additions & 13 deletions rats-devtools/src/python/rats/docs/_plugin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
from collections.abc import Iterator
from typing import cast

import click

Expand Down Expand Up @@ -28,12 +27,12 @@ def __init__(self, app: apps.Container) -> None:

@apps.group(devtools.PluginServices.EVENTS.OPENING)
def _on_open(self) -> Iterator[apps.Executable]:
def run() -> None:
parent = self._app.get(devtools.PluginServices.MAIN_CLICK)
docs = self._app.get(PluginServices.MAIN_CLICK)
parent.add_command(cast(click.Command, docs))

yield apps.App(run)
yield apps.App(
lambda: cli.attach(
self._app.get(devtools.PluginServices.MAIN_CLICK),
self._app.get(PluginServices.MAIN_CLICK),
)
)

@apps.service(PluginServices.COMMANDS)
def _commands(self) -> cli.CommandContainer:
Expand All @@ -51,10 +50,10 @@ def _main_exe(self) -> apps.Executable:

@apps.service(PluginServices.MAIN_CLICK)
def _main_click(self) -> click.Group:
command_container = self._app.get(PluginServices.COMMANDS)
docs = click.Group(
"docs",
help="commands to help author docs-as-code",
return cli.create_group(
click.Group(
"docs",
help="commands to help author docs-as-code",
),
self._app.get(PluginServices.COMMANDS),
)
command_container.attach(docs)
return docs
28 changes: 13 additions & 15 deletions rats-devtools/src/python/rats/kuberuntime/_plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections.abc import Iterator
from typing import cast

import click

Expand Down Expand Up @@ -35,28 +34,27 @@ def __init__(self, app: apps.Container) -> None:
self._app = app

@apps.group(devtools.PluginServices.EVENTS.OPENING)
def _runner_cli(self) -> Iterator[apps.Executable]:
def run() -> None:
kuberuntime = self._app.get(PluginServices.MAIN_CLICK)
parent = self._app.get(devtools.PluginServices.MAIN_CLICK)
self._app.get(PluginServices.COMMANDS).attach(kuberuntime)
parent.add_command(cast(click.Command, kuberuntime))

yield apps.App(run)
def _on_open(self) -> Iterator[apps.Executable]:
yield apps.App(
lambda: cli.attach(
self._app.get(PluginServices.MAIN_CLICK),
self._app.get(devtools.PluginServices.MAIN_CLICK),
)
)

@apps.service(PluginServices.MAIN_EXE)
def _main_exe(self) -> apps.Executable:
return apps.App(lambda: self._app.get(PluginServices.MAIN_CLICK)())

@apps.service(PluginServices.MAIN_CLICK)
def _main_click(self) -> click.Group:
command_container = self._app.get(PluginServices.COMMANDS)
kuberuntime = click.Group(
"k8s-runtime",
help="submit executables and events to k8s",
return cli.create_group(
click.Group(
"k8s-runtime",
help="submit executables and events to k8s",
),
self._app.get(PluginServices.COMMANDS),
)
command_container.attach(kuberuntime)
return kuberuntime

@apps.service(PluginServices.COMMANDS)
def _commands(self) -> cli.CommandContainer:
Expand Down
23 changes: 12 additions & 11 deletions rats-devtools/src/python/rats/stdruntime/_plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections.abc import Iterator
from typing import cast

import click

Expand All @@ -23,19 +22,21 @@ def __init__(self, app: apps.Container) -> None:

@apps.group(devtools.PluginServices.EVENTS.OPENING)
def _runtime_cli(self) -> Iterator[apps.Executable]:
def run() -> None:
parent = self._app.get(devtools.PluginServices.MAIN_CLICK)
stdruntime = self._app.get(PluginServices.MAIN_CLICK)
self._app.get(PluginServices.COMMANDS).attach(stdruntime)
parent.add_command(cast(click.Command, stdruntime))

yield apps.App(run)
yield apps.App(
lambda: cli.attach(
self._app.get(devtools.PluginServices.MAIN_CLICK),
self._app.get(PluginServices.MAIN_CLICK),
)
)

@apps.service(PluginServices.MAIN_CLICK)
def _click_group(self) -> click.Group:
return click.Group(
"std-runtime",
help="submit executables and events to the in-thread runtime.",
return cli.create_group(
click.Group(
"std-runtime",
help="submit executables and events to the in-thread runtime.",
),
self._app.get(PluginServices.COMMANDS),
)

@apps.service(PluginServices.COMMANDS)
Expand Down

0 comments on commit 25b599a

Please sign in to comment.