feat: add wutta
top-level command with make-uuid
subcommand
i think it only makes sense to have an "opinion" for command line interface in this project, and we probably need more `wutta` subcommands too but we'll see. main motivation for this currently is to allow poser apps to define their own CLI, in particular e.g. `poser install`
This commit is contained in:
parent
cb147c203d
commit
2deba45588
20 changed files with 446 additions and 47 deletions
105
docs/narr/cli/custom.rst
Normal file
105
docs/narr/cli/custom.rst
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
Custom Commands
|
||||
===============
|
||||
|
||||
WuttJamaican comes with :doc:`/narr/cli/builtin`.
|
||||
|
||||
Using the same framework, each :term:`package` can define additional
|
||||
top-level :term:`command(s)<command>` and
|
||||
:term:`subcommands<subcommand>` as needed.
|
||||
|
||||
|
||||
Top-Level Command
|
||||
-----------------
|
||||
|
||||
You must "define" *and* "register" your top-level command. Assuming a
|
||||
basic Poser example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
poser-project
|
||||
├── poser
|
||||
│ ├── __init__.py
|
||||
│ └── cli.py
|
||||
└── pyproject.toml
|
||||
|
||||
Add the command definition to the ``poser.cli`` module::
|
||||
|
||||
from wuttjamaican.cli import make_typer
|
||||
|
||||
poser_typer = make_typer(
|
||||
name='poser',
|
||||
help="Poser - the killer app"
|
||||
)
|
||||
|
||||
Then register the command as script in ``pyproject.toml``:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[project.scripts]
|
||||
poser = "poser.cli:poser_typer"
|
||||
|
||||
Then reinstall your project:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
pip install -e ~/src/poser
|
||||
|
||||
And now you can run your command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
poser --help
|
||||
|
||||
But it won't really do anything until you add subcommands.
|
||||
|
||||
|
||||
Subcommands
|
||||
-----------
|
||||
|
||||
You must "define" the subcommand of course, but do not need to
|
||||
"register" it. (That happens via function decorator; see below.)
|
||||
|
||||
However you *do* need to ensure all modules containing subcommands are
|
||||
"eagerly imported" so the runtime discovery process finds everything.
|
||||
|
||||
Here we'll define the ``poser hello`` subcommand, by adding it to our
|
||||
``poser.cli`` module (from example above)::
|
||||
|
||||
import sys
|
||||
import typer
|
||||
from wuttjamaican.cli import make_typer
|
||||
|
||||
# top-level command
|
||||
poser_typer = make_typer(
|
||||
name='poser',
|
||||
help="Poser - the killer app"
|
||||
)
|
||||
|
||||
# nb. function decorator will auto-register the subcommand
|
||||
@poser_typer.command()
|
||||
def hello(
|
||||
ctx: typer.Context,
|
||||
):
|
||||
"""
|
||||
Hello world example
|
||||
"""
|
||||
config = ctx.parent.wutta_config
|
||||
app = config.get_app()
|
||||
|
||||
name = config.get('hello.name', default="WhoAreYou")
|
||||
sys.stdout.write(f'hello {name}\n')
|
||||
|
||||
title = app.get_title()
|
||||
sys.stdout.write(f'from {title}\n')
|
||||
|
||||
# TODO: you may need to import other modules here, if they contain
|
||||
# subcommands and would not be automatically imported otherwise.
|
||||
# nb. *this* current module *is* automatically imported, only
|
||||
# because of the top-level command registration in pyproject.toml
|
||||
|
||||
No need to re-install, you can now use the subcommand:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
poser hello --help
|
Loading…
Add table
Add a link
Reference in a new issue