Metadata-Version: 2.4
Name: rn-forge-cli
Version: 0.1.2
Summary: The shared command-line layer for rn-forge applications: Typer app factory, standard options, console and exit codes
Author: Rohit Narayanan
Author-email: Rohit Narayanan <rohit.nn@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Dist: rn-forge-commons>=0.8.0,<0.9
Requires-Dist: rich>=15.0.0
Requires-Dist: typer>=0.26.8
Requires-Dist: assertpy>=1.1 ; extra == 'testing'
Requires-Dist: pytest>=9.1.1 ; extra == 'testing'
Requires-Python: >=3.14
Project-URL: Documentation, https://rn-forge.github.io/pykit/packages/rn-forge-cli/latest/
Project-URL: Source, https://github.com/rn-forge/pykit/tree/main/packages/rn-forge-cli
Project-URL: Changelog, https://github.com/rn-forge/pykit/blob/main/packages/rn-forge-cli/CHANGELOG.md
Project-URL: Issues, https://github.com/rn-forge/pykit/issues
Provides-Extra: testing
Description-Content-Type: text/markdown

# rn-forge-cli

[Documentation](https://rn-forge.github.io/pykit/packages/rn-forge-cli/latest/)
·
[Changelog](https://github.com/rn-forge/pykit/blob/main/packages/rn-forge-cli/CHANGELOG.md)
· [Source](https://github.com/rn-forge/pykit/tree/main/packages/rn-forge-cli) ·
[All pykit packages](https://rn-forge.github.io/pykit/)

The shared command-line layer for `rn-forge-*` applications: the Typer
application class, the standard option set and the error-to-exit-code mapping.

Where
[`rn-forge-commons`](https://github.com/rn-forge/pykit/tree/main/packages/rn-forge-commons)
is runtime-neutral — safe in a web server, a worker or a container — this
package is the *command-line shape*. An ordinary batch application wants it just
as much as a developer tool does, which is why it is separate from
[`rn-forge-tooling`](https://github.com/rn-forge/pykit/tree/main/packages/rn-forge-tooling),
the package that owns files, installs and rendering. It owns:

- `app` — `CliApp`, a `typer.Typer` subclass wiring the standard options into
  logging and the console; `ExitCode`; and `run`, which applies the mapping to
  any Typer app. Calling a `CliApp` returns an exit code, so
  `[project.scripts]` points straight at the app object.
- `options` — `--log-level`, `--log-file`, `--quiet`, `--json`, `--dry-run`,
  `--yes`, `--set`, `CliOptions` and `parse_overrides`.
- `surface` — `CliSurface`/`CommandSurface`, the records behind a `[cli]` table
  in a config file, from which `CliApp.from_config` builds the app. Validated
  on load: a wrong type names the offending key.

Console output is **not** here — `AppConsole` lives in `rn-forge-commons`,
because it is a property of the process rather than of the command-line parser,
and `rn_forge.django` may not import this package to reach one. This package
drives it: `--quiet`/`--json` set its mode.

`rn_forge.cli` may import `rn_forge.commons`. It must never import
`rn_forge.tooling`, and `rn_forge.commons` must never import either —
`.importlinter` proves all three.

## Installation

Require the package by version range:

```toml
dependencies = ["rn-forge-cli>=0.1,<0.2"]
```

## Usage

```python
from rn_forge.cli import CliApp
from rn_forge.commons import console

app = CliApp("golden-app", "Do the thing.")


@app.command()
def greet(name: str) -> None:
    """Greet someone."""
    console.success("Hello, {}", name)
```

```toml
[project.scripts]
golden-app = "golden_app.cli:app"
```

There is no `main()`: a generated console script is `sys.exit(app())`, and
`CliApp.__call__` returns the mapped exit code.

Or declare the commands in a `[cli]` table and build the app from it:

```python
app = CliApp.from_config("cli.toml")
```
