Metadata-Version: 2.4
Name: extencli
Version: 0.3.0
Summary: A set of utilities around click, for extensible CLI
Author-email: David Pineau <dav.pineau@gmail.com>
License-Expression: BSD-3-Clause
Project-URL: Homepage, https://github.com/Joacchim/extencli
Project-URL: Source, https://github.com/Joacchim/extencli
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8
Provides-Extra: test
Requires-Dist: mypy==1.18.2; extra == "test"
Requires-Dist: ruff==0.13.2; extra == "test"
Dynamic: license-file

# extencli

A set of utilities around click, which offers extensible CLI mechanism, with little effort

## Features

### Easy third-party extensible click.group

This package offers a specialized
[click.group](https://click.palletsprojects.com/en/stable/api/#click.Group)
implementation. Using it, you can create a CLI that will be extended by
simply installing additional modules.

As an example, here is how one would define an extensible `click.group` in
their python package `core_module`:

```python
import click

from extencli import PluginAutoloaderGroup

@click.group('core', cls=PluginAutoloaderGroup, depends_on='core_module')
def core_group():
    ...
```

The `depends_on` parameter is required:
 - `depends_on` specifies the name of the package that CLI
   extensions should depend on

Now, the CLI extension package should import the `core_group` from the
`core_module` like so:

```python
from core_module.cli import core_group

@core_group.command('myext')
def cli_extension():
    ...
```

Now, by simply installing both the `core_module` and the `extension`
third-party, the `core_module` will be extended with the `myext` command:

```shell
$> core --help
Usage: core [OPTIONS] COMMAND [ARGS]...

Options:
  --help                          Show this message and exit.

Commands:
  myext
```

### Caveats

#### Silent "failure" to load extensions

If the base CLI has its extensible group declared in the `__init__.py` file,
the internal `click` initialization mechanism might use different instances of
the group when loaded by extensions, and when invoked through the CLI.

To avoid this, please refer to the tests's `tests/python_packages/test_core`
python module, which is built in a way that avoid this caveat:
 - extensible group should not be in the `__init__.py` file
 - `pyproject.toml` may refer directly to it for script entrypoints
