Console Scripts¶
RunCommands makes it simple to create console scripts. First, define a command:
# project/package/commands.py
from runcommands import command
@command
def do_stuff(required_arg, optional_arg=None):
print(required_arg)
if optional_arg is not None:
print(optional_arg)
Then add an entry point:
# project/setup.py
setup(
name='package',
...,
entry_points="""
[console_scripts]
do-stuff = package.commands:do_stuff.console_script
"""
)
After reinstalling the package, the console script will now be directly runnable:
> do-stuff things
things
> do-stuff things -o wow
things
wow
Console Scripts with Subcommands¶
It’s also possible to create console scripts with subcommands a la git
:
# project/package/scripts/base.py
from runcommands import arg, command
@command
def base(subcommand: arg(default=None), verbosity=1):
# The base command will be called before the subcommand, so it
# can be used to do common work or show info.
print('Running base command with verbosity level', verbosity)
if subcommand is not None:
print('Running subcommand:', subcommand)
@base.subcommand
def sub(flag=False, verbosity=1):
print('Subcommand got flag', flag, 'and verbosity', verbosity)
Add the base command as a console script entry point:
# project/setup.py
setup(
name='package',
...,
entry_points="""
[console_scripts]
do-stuff = package.scripts.base:base.console_script
"""
)
Note
Generally, only the base command should be added.
Reinstall the package, then run the base command by itself or with a subcommand:
> base
Running base command with verbosity level 1
> base --verbosity 2
Running base command with verbosity level 2
> base --verbosity 2 sub
Running base command with verbosity level 2
Running subcommand: sub
Subcommand got flag False and verbosity 2
> base sub --flag --verbosity 2
Running base command with verbosity level 1
Running subcommand: sub
Subcommand got flag True and verbosity 2
Subcommand Notes¶
- The base command’s subcommand arg–i.e., its first arg–will have its
choices
automatically populated with the names of its subcommands (unlesschoices
is explictly set on the subcommand arg). - Base commands can only have a single positional arg, the subcommand.
- The example above doesn’t require a subcommand to be passed to the base
command, because that’s probably the most common scenario. To require a
subcommand, change
subcommand: arg(default=None)
to justsubcommand
(i.e., just a regular positional arg). - When a subcommand has options in common with its base command(s), the common
options will be passed down from the base command(s) (like
verbosity
in the example above). - Subcommands can also have subcommands, which can also have subcommands, and so on.
- Although subcommands are mostly intended to be run via console scripts
rather than via
runcommands
, they can be imported into a project’scommands.py
. The base command can then be run withruncommands base
. Subcommands can be run withruncommands base base:sub
orruncommands base:sub
(in the latter case, the base command(s) won’t be run).