"""
CLI subcommands
A command provides a :attr:`~.CommandBase.jobs` property that returns a sequence
of :class:`~.jobs.base.JobBase` instances.
It is important that the jobs are only instantiated once and the
:attr:`~.CommandBase.jobs` property doesn't create new jobs every time it is
accessed. The easiest way to achieve this is with the
:func:`functools.cached_property` decorator.
CLI arguments are available as :attr:`~.CommandBase.args` and configuration
files as :attr:`~.CommandBase.config`. These should be used to create arguments
for jobs.
The docstrings of :class:`~.base.CommandBase` subclasses are used as the
description in the ``--help`` output.
"""
import functools
from ....utils import subclasses, submodules
from .base import CommandBase
@functools.cache
def _register_commands():
subcmdclss = sorted(subclasses(CommandBase, submodules(__package__)),
key=lambda subcmdcls: subcmdcls.names[0])
for subcmdcls in subcmdclss:
subcmdcls.register()
[docs]
def run(args):
"""
Instantiate :class:`~.base.CommandBase`
This is just a thin wrapper around :meth:`~.base.CommandBase.run` that
ensures all commands are registered first.
:param args: CLI arguments
"""
_register_commands()
return CommandBase.run(args)