CLI internals#

The cotainr command line interface (CLI) is designed around a subcommand for each major action, cotainr provides. Each subcommand then supports a set of options. They all support --help for displaying a help message.

The CLI is build using argparse.

The main way to invoke the CLI (sub)commands is via the cotainr entrypoint defined in the project.scripts table in the pyproject.toml file,

$ cotainr build <positional_arg> <non-positional args>
$ cotainr info

This assumes that cotainr is installed as a wheel, e.g. via pip install cotainr. Alternatively, the CLI (sub)commands may also be executed directly from the source code via the bin/cotainr executable script.

Internal subcommand design#

The command line interface is implemented in the cotainr.cli module. It defines the main CotainrCLI class that implements the main CLI command. When instantiated, it exposes the following two attributes:

  • args: A types.SimpleNamespace containing the parsed CLI arguments.

  • subcommand: An instance of the subcommand class that was requested when the CotainrCLI was instantiated.

The CotainrCLI class is intended to be used as:

cli = CotainrCLI()
cli.subcommand.execute()

Each of the subcommands is implemented as a separate subclass of the CotainrSubcommand class which defines the following interface:

In order to add a new subcommand, one has to:

  • Implement a subclass of CotainrSubcommand that:

    • Is named as the desired subcommand name.

    • Implements the above subcommands interface.

  • Add the class to the cotainr.cli.CotainrCLI._subcommands class attribute.

This implementation was inspired by Satya Sai Vineeth Guna’s cli_design.py.

Automatic help messages extraction#

Throughout the implementation of the CLI, we try to avoid repeating (in the source code) help messages for the CLI by (ab)using the __doc__ dunder to automatically extract such help messages from a single place of definition. That is, the text shown when running cotainr --help, cotainr build --help, etc. is automatically extracted from the docstrings of the classes implementing those (sub)commands. Specifically, we automatically extract:

  • The main CLI description text from the CotainrCLI class docstring short summary.

  • The subcommands description and help summary from their class docstring short summary, e.g. for the cotainr build subcommand we extract it from the Build class docstring.

  • The subcommands help texts from the Parameters section in their class docstring. For easing this, we have the cotainr.cli._extract_help_from_docstring() function. Note that this utility function relies on the assumption that the docstrings are formatted according to the numpydoc format.