106 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
		
		
			
		
	
	
			106 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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
							 |