fix: add mechanism to discover external wutta
subcommands
for sake of wuttasync, e.g. `wutta import-csv`
This commit is contained in:
parent
3a1ea22e9b
commit
a9eebc682e
|
@ -33,5 +33,9 @@ This (``wuttjamaican.cli``) namespace exposes the following:
|
|||
|
||||
from .base import wutta_typer, make_typer
|
||||
|
||||
# TODO: is this the best we can do, to register available commands?
|
||||
# nb. must bring in all modules for discovery to work
|
||||
from . import make_uuid
|
||||
|
||||
# discover more commands, installed via other packages
|
||||
from .base import typer_eager_imports
|
||||
typer_eager_imports(wutta_typer)
|
||||
|
|
|
@ -41,6 +41,7 @@ import typer
|
|||
from typing_extensions import Annotated
|
||||
|
||||
from wuttjamaican.conf import make_config
|
||||
from wuttjamaican.util import load_entry_points
|
||||
|
||||
|
||||
def make_cli_config(ctx: typer.Context):
|
||||
|
@ -84,6 +85,43 @@ def typer_callback(
|
|||
ctx.wutta_config = make_cli_config(ctx)
|
||||
|
||||
|
||||
def typer_eager_imports(
|
||||
group: [typer.Typer, str]):
|
||||
"""
|
||||
Eagerly import all modules which are registered as having
|
||||
:term:`subcommands <subcommand>` belonging to the given group
|
||||
(i.e. top-level :term:`command`).
|
||||
|
||||
This is used to locate subcommands which may be defined by
|
||||
multiple different packages. It is mostly needed for the main
|
||||
``wutta`` command, since e.g. various extension packages may
|
||||
define additional subcommands for it.
|
||||
|
||||
Most custom apps will define their own top-level command and some
|
||||
subcommands, but will have no need to "discover" additional
|
||||
subcommands defined elsewhere. Hence you normally would not need
|
||||
to call this function.
|
||||
|
||||
However if you wish to define a ``wutta`` subcommand(s), you
|
||||
*would* need to register the entry point for your module(s)
|
||||
containing the subcommand(s) like so (in ``pyproject.toml``):
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[project.entry-points."wutta.typer_imports"]
|
||||
poser = "poser.commands"
|
||||
|
||||
Note that the ``wutta.typer_imports`` above indicates you are
|
||||
registering a module which defines ``wutta`` subcommands. The
|
||||
``poser`` name is arbitrary but should match your package name.
|
||||
|
||||
:param group: Typer group command, or the name of one.
|
||||
"""
|
||||
if isinstance(group, typer.Typer):
|
||||
group = group.info.name
|
||||
load_entry_points(f'{group}.typer_imports')
|
||||
|
||||
|
||||
def make_typer(**kwargs):
|
||||
"""
|
||||
Create a Typer command instance, per Wutta conventions.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import os
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import typer
|
||||
|
||||
|
@ -32,6 +32,15 @@ class TestTyperCallback(TestCase):
|
|||
self.assertEqual(ctx.wutta_config.files_read, [example_conf])
|
||||
|
||||
|
||||
class TestTyperEagerImports(TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
typr = mod.make_typer(name='foobreezy')
|
||||
with patch.object(mod, 'load_entry_points') as load_entry_points:
|
||||
mod.typer_eager_imports(typr)
|
||||
load_entry_points.assert_called_once_with('foobreezy.typer_imports')
|
||||
|
||||
|
||||
class TestMakeTyper(TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
|
|
Loading…
Reference in a new issue