lib-cli-exit-tools 1.3.0__tar.gz → 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/CHANGELOG.md +4 -0
- lib_cli_exit_tools-1.3.1/INSTALL.md +184 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/PKG-INFO +92 -91
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/README.md +91 -90
- lib_cli_exit_tools-1.3.1/docs/system-design/module_reference.md +251 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/packaging/brew/Formula/lib-cli-exit-tools.rb +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/packaging/conda/recipe/meta.yaml +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/packaging/nix/flake.nix +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/pyproject.toml +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/src/lib_cli_exit_tools/__init__.py +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +26 -4
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/tests/test_lib_extra.py +34 -0
- lib_cli_exit_tools-1.3.0/docs/system-design/reference.md +0 -341
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/.env.example +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/.github/workflows/ci.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/.github/workflows/codeql.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/.github/workflows/release.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/.gitignore +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/AGENTS.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/CONTRIBUTING.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/DEVELOPMENT.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/LICENSE +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/Makefile +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/codecov.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/notebooks/Quickstart.ipynb +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/packaging/README.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/qlty.toml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/__init__.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/_utils.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/build.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/bump.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/bump_major.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/bump_minor.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/bump_patch.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/bump_version.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/clean.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/dev.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/generate_nix_flake.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/install.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/menu.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/push.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/release.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/run_cli.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/test.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/scripts/version_current.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/src/lib_cli_exit_tools/__init__conf__.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/src/lib_cli_exit_tools/__main__.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/src/lib_cli_exit_tools/cli.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/src/lib_cli_exit_tools/py.typed +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/tests/test_cli.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/tests/test_cli_extra.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/tests/test_exit_tools.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.3.1}/tests/test_extend_cli.py +0 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Installation Guide
|
|
2
|
+
|
|
3
|
+
This document collects every supported installation path for `lib_cli_exit_tools`, plus notes on platform quirks and troubleshooting. If you only need the standard release from PyPI, see the short "Install" section in `README.md` or run:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install lib_cli_exit_tools
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The sections below cover more specialised workflows, from editable installs to package-manager builds.
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
- [Supported Python Versions](#supported-python-versions)
|
|
13
|
+
- [Installation Flows](#installation-flows)
|
|
14
|
+
- [PyPI (latest release)](#pypi-latest-release)
|
|
15
|
+
- [Editable install in a virtual environment](#editable-install-in-a-virtual-environment)
|
|
16
|
+
- [Per-user installs (`pip --user`)](#per-user-installs-pip---user)
|
|
17
|
+
- [pipx](#pipx)
|
|
18
|
+
- [uv](#uv)
|
|
19
|
+
- [Installing from local artifacts](#installing-from-local-artifacts)
|
|
20
|
+
- [Poetry / PDM](#poetry--pdm)
|
|
21
|
+
- [Install directly from Git](#install-directly-from-git)
|
|
22
|
+
- [Conda / Mamba environments](#conda--mamba-environments)
|
|
23
|
+
- [System package managers](#system-package-managers)
|
|
24
|
+
- [Path configuration](#path-configuration)
|
|
25
|
+
- [Troubleshooting](#troubleshooting)
|
|
26
|
+
- [PEP 668 “externally managed environment” errors](#pep-668-externally-managed-environment-errors)
|
|
27
|
+
- [Missing command on PATH](#missing-command-on-path)
|
|
28
|
+
- [Colour output not appearing](#colour-output-not-appearing)
|
|
29
|
+
|
|
30
|
+
## Supported Python Versions
|
|
31
|
+
|
|
32
|
+
`lib_cli_exit_tools` targets Python 3.9 and newer. Wheels are published for CPython on Linux, macOS, and Windows. For alternative interpreters (PyPy) install from source using `pip install lib_cli_exit_tools`.
|
|
33
|
+
|
|
34
|
+
## Installation Flows
|
|
35
|
+
|
|
36
|
+
### PyPI (latest release)
|
|
37
|
+
|
|
38
|
+
The quickest path for production use:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install lib_cli_exit_tools
|
|
42
|
+
# Pin to a specific release when reproducibility matters
|
|
43
|
+
pip install "lib_cli_exit_tools==1.1.0"
|
|
44
|
+
# Upgrade later
|
|
45
|
+
pip install --upgrade lib_cli_exit_tools
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This command registers the `lib_cli_exit_tools`, `cli-exit-tools`, and `lib-cli-exit-tools` entry points on your PATH.
|
|
49
|
+
|
|
50
|
+
### Editable install in a virtual environment
|
|
51
|
+
|
|
52
|
+
Use this flow when developing the library locally:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python -m venv .venv
|
|
56
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
57
|
+
pip install -e .[dev]
|
|
58
|
+
# Alternatively, install runtime dependencies only
|
|
59
|
+
pip install .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Per-user installs (`pip --user`)
|
|
63
|
+
|
|
64
|
+
Install to the user site-packages directory without creating a virtual environment:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install --user lib_cli_exit_tools
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Ensure `~/.local/bin` (POSIX) or `%APPDATA%\Python\PythonXY\Scripts` (Windows) is on your PATH. This approach respects [PEP 668](https://peps.python.org/pep-0668/)—avoid running it in system-managed Python installs that disallow modifications.
|
|
71
|
+
|
|
72
|
+
### pipx
|
|
73
|
+
|
|
74
|
+
`pipx` isolates CLI tools in dedicated environments, making upgrades easy:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pipx install lib_cli_exit_tools
|
|
78
|
+
pipx upgrade lib_cli_exit_tools
|
|
79
|
+
# Install directly from a tagged release or commit
|
|
80
|
+
pipx install "git+https://github.com/bitranox/lib_cli_exit_tools@v1.1.0"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### uv
|
|
84
|
+
|
|
85
|
+
[uv](https://github.com/astral-sh/uv) provides fast installs and execution:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv pip install -e .[dev]
|
|
89
|
+
uv tool install lib_cli_exit_tools
|
|
90
|
+
uvx lib_cli_exit_tools --help
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Installing from local artifacts
|
|
94
|
+
|
|
95
|
+
Build a wheel or sdist locally and install it in offline environments:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
python -m build
|
|
99
|
+
pip install dist/lib_cli_exit_tools-*.whl
|
|
100
|
+
pip install dist/lib_cli_exit_tools-*.tar.gz
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Poetry / PDM
|
|
104
|
+
|
|
105
|
+
Add the library to a project managed by Poetry or PDM:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Poetry
|
|
109
|
+
poetry add lib_cli_exit_tools
|
|
110
|
+
poetry install
|
|
111
|
+
|
|
112
|
+
# PDM
|
|
113
|
+
pdm add lib_cli_exit_tools
|
|
114
|
+
pdm install
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Install directly from Git
|
|
118
|
+
|
|
119
|
+
CI systems or early adopters can install from a specific revision:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install "git+https://github.com/bitranox/lib_cli_exit_tools@v1.1.0#egg=lib_cli_exit_tools"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Conda / Mamba environments
|
|
126
|
+
|
|
127
|
+
Create a dedicated Conda environment and install via `pip` inside it:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
mamba create -n cli-exit python=3.12 pip
|
|
131
|
+
mamba activate cli-exit
|
|
132
|
+
pip install lib_cli_exit_tools
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### System package managers
|
|
136
|
+
|
|
137
|
+
Packages may be published for platform-native installers:
|
|
138
|
+
|
|
139
|
+
- **Homebrew (macOS):** `brew install lib_cli_exit_tools`
|
|
140
|
+
- **Nix:** `nix run github:bitranox/lib_cli_exit_tools` or `nix develop` with the provided flake
|
|
141
|
+
- **Deb/RPM:** build with `fpm` using the project’s `packaging/` scripts
|
|
142
|
+
|
|
143
|
+
Check the repository’s release notes for the current distribution status.
|
|
144
|
+
|
|
145
|
+
## Path configuration
|
|
146
|
+
|
|
147
|
+
After installation the following commands should resolve:
|
|
148
|
+
|
|
149
|
+
- `lib_cli_exit_tools`
|
|
150
|
+
- `cli-exit-tools`
|
|
151
|
+
- `python -m lib_cli_exit_tools`
|
|
152
|
+
|
|
153
|
+
If you installed inside a virtual environment, activate it before running the commands. For user installs, ensure the relevant `bin`/`Scripts` directory is included in your PATH:
|
|
154
|
+
|
|
155
|
+
- Linux/macOS venv: `<venv>/bin`
|
|
156
|
+
- Linux/macOS user site: `~/.local/bin`
|
|
157
|
+
- Windows venv: `<venv>\Scripts`
|
|
158
|
+
- Windows user site: `%APPDATA%\Python\PythonXY\Scripts`
|
|
159
|
+
|
|
160
|
+
## Troubleshooting
|
|
161
|
+
|
|
162
|
+
### PEP 668 “externally managed environment” errors
|
|
163
|
+
|
|
164
|
+
Some OS distributions (Ubuntu, Fedora, Debian) mark the system Python as externally managed. Running `pip install` directly into that interpreter raises an error similar to:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
error: externally-managed-environment
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Fix:**
|
|
171
|
+
- Create a virtual environment (`python -m venv .venv`) and install inside it, or
|
|
172
|
+
- Use `pipx`, `conda`, `uv`, or another isolated environment manager.
|
|
173
|
+
|
|
174
|
+
### Missing command on PATH
|
|
175
|
+
|
|
176
|
+
If `lib_cli_exit_tools --help` returns “command not found”, confirm that the installation location is on PATH. The most common fix is adding `~/.local/bin` (POSIX) or `%APPDATA%\Python\PythonXY\Scripts` (Windows) to your PATH environment variable, then re-opening the shell.
|
|
177
|
+
|
|
178
|
+
### Colour output not appearing
|
|
179
|
+
|
|
180
|
+
Set `lib_cli_exit_tools.config.traceback_force_color = True` in your application to force Rich to emit coloured tracebacks even when stderr is not detected as a TTY. Alternatively, export `RICH_FORCE_TERMINAL=1` before running the CLI.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
For additional environment automation (Conda, Nix, Homebrew formulas), consult the scripts under `packaging/` and the Makefile targets described in `README.md`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lib_cli_exit_tools
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: CLI exit handling helpers: clean signals, exit codes, and error printing
|
|
5
5
|
Project-URL: Homepage, https://github.com/bitranox/lib_cli_exit_tools
|
|
6
6
|
Project-URL: Repository, https://github.com/bitranox/lib_cli_exit_tools.git
|
|
@@ -50,93 +50,11 @@ Small helpers for robust CLI exit handling:
|
|
|
50
50
|
|
|
51
51
|
## Install
|
|
52
52
|
|
|
53
|
-
Pick one of the options below. All methods register the `lib_cli_exit_tools`, `cli-exit-tools`, and `lib-cli-exit-tools` commands on your PATH.
|
|
54
|
-
|
|
55
|
-
### 0) PyPI (latest release)
|
|
56
|
-
|
|
57
53
|
```bash
|
|
58
54
|
pip install lib_cli_exit_tools
|
|
59
|
-
# Pin to the current release if you need reproducibility
|
|
60
|
-
pip install "lib_cli_exit_tools==1.1.0"
|
|
61
|
-
# Upgrade to the newest release later
|
|
62
|
-
pip install --upgrade lib_cli_exit_tools
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 1) Standard virtualenv (pip)
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
python -m venv .venv
|
|
69
|
-
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
|
|
70
|
-
pip install -e .[dev] # dev install
|
|
71
|
-
# or for runtime only:
|
|
72
|
-
pip install .
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### 2) Per-user (no venv)
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
pip install --user .
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Note: respects PEP 668; avoid on system Python if “externally managed”. Ensure `~/.local/bin` (POSIX) is on PATH.
|
|
82
|
-
|
|
83
|
-
### 3) pipx (isolated, recommended for end users)
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
pipx install .
|
|
87
|
-
pipx upgrade lib_cli_exit_tools
|
|
88
|
-
# From Git tag/commit:
|
|
89
|
-
pipx install "git+https://github.com/bitranox/lib_cli_exit_tools@v1.1.0"
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### 4) uv (fast installer/runner)
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
uv pip install -e .[dev]
|
|
96
|
-
uv tool install .
|
|
97
|
-
uvx lib_cli_exit_tools --help
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### 5) From artifacts
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
python -m build
|
|
104
|
-
pip install dist/lib_cli_exit_tools-*.whl
|
|
105
|
-
pip install dist/lib_cli_exit_tools-*.tar.gz # sdist
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### 6) Poetry / PDM (project-managed envs)
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
# Poetry
|
|
112
|
-
poetry add lib_cli_exit_tools # as dependency
|
|
113
|
-
poetry install # for local dev
|
|
114
|
-
|
|
115
|
-
# PDM
|
|
116
|
-
pdm add lib_cli_exit_tools
|
|
117
|
-
pdm install
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### 7) From Git via pip (CI-friendly)
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
pip install "git+https://github.com/bitranox/lib_cli_exit_tools@v1.1.0#egg=lib_cli_exit_tools"
|
|
124
55
|
```
|
|
125
56
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
mamba create -n cli-exit python=3.12 pip
|
|
130
|
-
mamba activate cli-exit
|
|
131
|
-
pip install .
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 9) System package managers (optional distribution)
|
|
135
|
-
|
|
136
|
-
- Homebrew formula (macOS): `brew install lib_cli_exit_tools` (if published)
|
|
137
|
-
- Nix: flake/package for reproducible installs
|
|
138
|
-
- Deb/RPM via `fpm` for OS-native packages
|
|
139
|
-
|
|
57
|
+
See [INSTALL.md](INSTALL.md) for editable installs, pipx/uv, package-manager builds, and troubleshooting tips.
|
|
140
58
|
|
|
141
59
|
## Usage
|
|
142
60
|
|
|
@@ -225,6 +143,89 @@ Field reference:
|
|
|
225
143
|
|
|
226
144
|
Remember that `config` is module-level—if you call the library from multiple threads or embed it in another CLI, configure it once during bootstrap before handing control to user code.
|
|
227
145
|
|
|
146
|
+
## Public API Reference
|
|
147
|
+
|
|
148
|
+
The package re-exports the helpers below via `lib_cli_exit_tools.__all__`. Import them directly with `from lib_cli_exit_tools import …`.
|
|
149
|
+
|
|
150
|
+
### `config`
|
|
151
|
+
Mutable dataclass-like singleton holding process-wide settings. Configure it during CLI startup.
|
|
152
|
+
|
|
153
|
+
- `traceback` (`bool`): `True` to surface full Python tracebacks; `False` keeps short, coloured summaries.
|
|
154
|
+
- `exit_code_style` (`'errno' | 'sysexits'`): Selects POSIX/Windows errno-style exit codes or BSD `sysexits` semantics.
|
|
155
|
+
- `broken_pipe_exit_code` (`int`): Overrides the exit status for `BrokenPipeError` (default `141`).
|
|
156
|
+
- `traceback_force_color` (`bool`): Forces Rich-coloured tracebacks even when stderr is not a TTY.
|
|
157
|
+
|
|
158
|
+
### `run_cli(cli, argv=None, *, prog_name=None, signal_specs=None, install_signals=True) -> int`
|
|
159
|
+
Wrap a Click command or group so every invocation shares the same signal handling and exit-code policy. Returns the numeric exit code instead of exiting the process.
|
|
160
|
+
|
|
161
|
+
Parameters:
|
|
162
|
+
- `cli`: `click.BaseCommand` to execute.
|
|
163
|
+
- `argv`: Optional iterable of CLI arguments (excluding program name).
|
|
164
|
+
- `prog_name`: Override the program name shown in help/version output.
|
|
165
|
+
- `signal_specs`: Iterable of `SignalSpec` objects to customise signal handling; defaults to `default_signal_specs()`.
|
|
166
|
+
- `install_signals`: Set `False` when the host application already manages signal handlers.
|
|
167
|
+
|
|
168
|
+
### `handle_cli_exception(exc, *, signal_specs=None, echo=None) -> int`
|
|
169
|
+
Translate exceptions raised by Click commands into deterministic exit codes, honouring configured signal mappings and traceback policy.
|
|
170
|
+
|
|
171
|
+
Parameters:
|
|
172
|
+
- `exc`: Exception instance to classify.
|
|
173
|
+
- `signal_specs`: Optional iterable of `SignalSpec` objects for custom signal handling.
|
|
174
|
+
- `echo`: Callable matching `click.echo` signature, allowing custom stderr routing during tests or embedding.
|
|
175
|
+
|
|
176
|
+
### `get_system_exit_code(exc) -> int`
|
|
177
|
+
Compute a platform-aware exit status for arbitrary exceptions (errno mappings on POSIX/Windows or BSD `sysexits` when enabled).
|
|
178
|
+
|
|
179
|
+
Parameters:
|
|
180
|
+
- `exc`: Exception instance to classify.
|
|
181
|
+
|
|
182
|
+
### `print_exception_message(trace_back=config.traceback, length_limit=500, stream=None) -> None`
|
|
183
|
+
Emit the active exception using Rich formatting. Produces a coloured traceback when `trace_back` is `True`, otherwise prints a truncated summary in red. Respects `config.traceback_force_color`.
|
|
184
|
+
|
|
185
|
+
Parameters:
|
|
186
|
+
- `trace_back`: Toggle between full traceback rendering (`True`) and short summary (`False`).
|
|
187
|
+
- `length_limit`: Maximum characters for summary output.
|
|
188
|
+
- `stream`: Target text stream; defaults to `sys.stderr`.
|
|
189
|
+
|
|
190
|
+
### `flush_streams() -> None`
|
|
191
|
+
Best-effort flush of `sys.stdout` and `sys.stderr`, ensuring buffered output is written before exit.
|
|
192
|
+
|
|
193
|
+
### `default_signal_specs() -> list[SignalSpec]`
|
|
194
|
+
Return the default signal mapping for the current platform (always includes `SIGINT`, plus `SIGTERM`/`SIGBREAK` when available).
|
|
195
|
+
|
|
196
|
+
### `install_signal_handlers(specs=None) -> Callable[[], None]`
|
|
197
|
+
Register handlers that raise structured exceptions for the provided specs and return a restoration callback. Invoke the callback (typically in a `finally` block) to restore previous handlers.
|
|
198
|
+
|
|
199
|
+
Parameters:
|
|
200
|
+
- `specs`: Iterable of `SignalSpec` objects; defaults to `default_signal_specs()`.
|
|
201
|
+
|
|
202
|
+
### `SignalSpec(signum: int, exception: type[BaseException], message: str, exit_code: int)`
|
|
203
|
+
Lightweight dataclass describing how a signal maps to an exception, stderr message, and exit code.
|
|
204
|
+
|
|
205
|
+
Fields:
|
|
206
|
+
- `signum`: Numeric signal value passed to `signal.signal`.
|
|
207
|
+
- `exception`: Exception type raised by the handler.
|
|
208
|
+
- `message`: Human-readable text echoed when the signal fires.
|
|
209
|
+
- `exit_code`: Exit status returned to the OS.
|
|
210
|
+
|
|
211
|
+
### `CliSignalError` and subclasses
|
|
212
|
+
Hierarchy of marker exceptions raised when signal handlers trigger. Use them to differentiate signal-driven exits from other failures.
|
|
213
|
+
|
|
214
|
+
- `CliSignalError`: Base class.
|
|
215
|
+
- `SigIntInterrupt`: Raised on `SIGINT` (Ctrl+C); maps to exit code `130`.
|
|
216
|
+
- `SigTermInterrupt`: Raised on `SIGTERM`; maps to exit code `143`.
|
|
217
|
+
- `SigBreakInterrupt`: Raised on Windows `SIGBREAK`; maps to exit code `149`.
|
|
218
|
+
|
|
219
|
+
### `default_signal_specs`, `install_signal_handlers`, and `run_cli` contract summary
|
|
220
|
+
When `run_cli` executes your Click command it will:
|
|
221
|
+
1. Build a signal spec list (custom or default).
|
|
222
|
+
2. Optionally install handlers that raise the exceptions above.
|
|
223
|
+
3. Execute the command with `standalone_mode=False`.
|
|
224
|
+
4. Funnel any exception through `handle_cli_exception`.
|
|
225
|
+
5. Restore prior signal handlers and flush streams before returning.
|
|
226
|
+
|
|
227
|
+
This behaviour keeps CLI wiring consistent across projects embedding `lib_cli_exit_tools`.
|
|
228
|
+
|
|
228
229
|
### Advanced CLI wiring
|
|
229
230
|
|
|
230
231
|
For larger applications, keep module execution, console scripts, and shared helpers aligned. The snippet below shows how `__main__.py` can catch unexpected errors and map them through `lib_cli_exit_tools` before exiting:
|
|
@@ -327,11 +328,11 @@ When installed, the generated console scripts (`lib_cli_exit_tools`, `cli-exit-t
|
|
|
327
328
|
- Set `config.exit_code_style = "sysexits"` to map ValueError/TypeError → EX_USAGE(64),
|
|
328
329
|
FileNotFoundError → EX_NOINPUT(66), PermissionError → EX_NOPERM(77), generic OSError → EX_IOERR(74).
|
|
329
330
|
|
|
330
|
-
##
|
|
331
|
-
|
|
332
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md) for contributor workflows, make targets, packaging sync details, and CI/publishing guidance.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
## License
|
|
331
|
+
## Additional Documentation
|
|
336
332
|
|
|
337
|
-
|
|
333
|
+
- [INSTALL](INSTALL.md)
|
|
334
|
+
- [CHANGELOG](CHANGELOG.md)
|
|
335
|
+
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
336
|
+
- [DEVELOPMENT](DEVELOPMENT.md)
|
|
337
|
+
- [MODULE REFERENCE](docs/system-design/module_reference.md)
|
|
338
|
+
- [LICENSE](LICENSE)
|
|
@@ -19,93 +19,11 @@ Small helpers for robust CLI exit handling:
|
|
|
19
19
|
|
|
20
20
|
## Install
|
|
21
21
|
|
|
22
|
-
Pick one of the options below. All methods register the `lib_cli_exit_tools`, `cli-exit-tools`, and `lib-cli-exit-tools` commands on your PATH.
|
|
23
|
-
|
|
24
|
-
### 0) PyPI (latest release)
|
|
25
|
-
|
|
26
22
|
```bash
|
|
27
23
|
pip install lib_cli_exit_tools
|
|
28
|
-
# Pin to the current release if you need reproducibility
|
|
29
|
-
pip install "lib_cli_exit_tools==1.1.0"
|
|
30
|
-
# Upgrade to the newest release later
|
|
31
|
-
pip install --upgrade lib_cli_exit_tools
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 1) Standard virtualenv (pip)
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
python -m venv .venv
|
|
38
|
-
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
|
|
39
|
-
pip install -e .[dev] # dev install
|
|
40
|
-
# or for runtime only:
|
|
41
|
-
pip install .
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### 2) Per-user (no venv)
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
pip install --user .
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Note: respects PEP 668; avoid on system Python if “externally managed”. Ensure `~/.local/bin` (POSIX) is on PATH.
|
|
51
|
-
|
|
52
|
-
### 3) pipx (isolated, recommended for end users)
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
pipx install .
|
|
56
|
-
pipx upgrade lib_cli_exit_tools
|
|
57
|
-
# From Git tag/commit:
|
|
58
|
-
pipx install "git+https://github.com/bitranox/lib_cli_exit_tools@v1.1.0"
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### 4) uv (fast installer/runner)
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
uv pip install -e .[dev]
|
|
65
|
-
uv tool install .
|
|
66
|
-
uvx lib_cli_exit_tools --help
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### 5) From artifacts
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
python -m build
|
|
73
|
-
pip install dist/lib_cli_exit_tools-*.whl
|
|
74
|
-
pip install dist/lib_cli_exit_tools-*.tar.gz # sdist
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 6) Poetry / PDM (project-managed envs)
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# Poetry
|
|
81
|
-
poetry add lib_cli_exit_tools # as dependency
|
|
82
|
-
poetry install # for local dev
|
|
83
|
-
|
|
84
|
-
# PDM
|
|
85
|
-
pdm add lib_cli_exit_tools
|
|
86
|
-
pdm install
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### 7) From Git via pip (CI-friendly)
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
pip install "git+https://github.com/bitranox/lib_cli_exit_tools@v1.1.0#egg=lib_cli_exit_tools"
|
|
93
24
|
```
|
|
94
25
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
mamba create -n cli-exit python=3.12 pip
|
|
99
|
-
mamba activate cli-exit
|
|
100
|
-
pip install .
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### 9) System package managers (optional distribution)
|
|
104
|
-
|
|
105
|
-
- Homebrew formula (macOS): `brew install lib_cli_exit_tools` (if published)
|
|
106
|
-
- Nix: flake/package for reproducible installs
|
|
107
|
-
- Deb/RPM via `fpm` for OS-native packages
|
|
108
|
-
|
|
26
|
+
See [INSTALL.md](INSTALL.md) for editable installs, pipx/uv, package-manager builds, and troubleshooting tips.
|
|
109
27
|
|
|
110
28
|
## Usage
|
|
111
29
|
|
|
@@ -194,6 +112,89 @@ Field reference:
|
|
|
194
112
|
|
|
195
113
|
Remember that `config` is module-level—if you call the library from multiple threads or embed it in another CLI, configure it once during bootstrap before handing control to user code.
|
|
196
114
|
|
|
115
|
+
## Public API Reference
|
|
116
|
+
|
|
117
|
+
The package re-exports the helpers below via `lib_cli_exit_tools.__all__`. Import them directly with `from lib_cli_exit_tools import …`.
|
|
118
|
+
|
|
119
|
+
### `config`
|
|
120
|
+
Mutable dataclass-like singleton holding process-wide settings. Configure it during CLI startup.
|
|
121
|
+
|
|
122
|
+
- `traceback` (`bool`): `True` to surface full Python tracebacks; `False` keeps short, coloured summaries.
|
|
123
|
+
- `exit_code_style` (`'errno' | 'sysexits'`): Selects POSIX/Windows errno-style exit codes or BSD `sysexits` semantics.
|
|
124
|
+
- `broken_pipe_exit_code` (`int`): Overrides the exit status for `BrokenPipeError` (default `141`).
|
|
125
|
+
- `traceback_force_color` (`bool`): Forces Rich-coloured tracebacks even when stderr is not a TTY.
|
|
126
|
+
|
|
127
|
+
### `run_cli(cli, argv=None, *, prog_name=None, signal_specs=None, install_signals=True) -> int`
|
|
128
|
+
Wrap a Click command or group so every invocation shares the same signal handling and exit-code policy. Returns the numeric exit code instead of exiting the process.
|
|
129
|
+
|
|
130
|
+
Parameters:
|
|
131
|
+
- `cli`: `click.BaseCommand` to execute.
|
|
132
|
+
- `argv`: Optional iterable of CLI arguments (excluding program name).
|
|
133
|
+
- `prog_name`: Override the program name shown in help/version output.
|
|
134
|
+
- `signal_specs`: Iterable of `SignalSpec` objects to customise signal handling; defaults to `default_signal_specs()`.
|
|
135
|
+
- `install_signals`: Set `False` when the host application already manages signal handlers.
|
|
136
|
+
|
|
137
|
+
### `handle_cli_exception(exc, *, signal_specs=None, echo=None) -> int`
|
|
138
|
+
Translate exceptions raised by Click commands into deterministic exit codes, honouring configured signal mappings and traceback policy.
|
|
139
|
+
|
|
140
|
+
Parameters:
|
|
141
|
+
- `exc`: Exception instance to classify.
|
|
142
|
+
- `signal_specs`: Optional iterable of `SignalSpec` objects for custom signal handling.
|
|
143
|
+
- `echo`: Callable matching `click.echo` signature, allowing custom stderr routing during tests or embedding.
|
|
144
|
+
|
|
145
|
+
### `get_system_exit_code(exc) -> int`
|
|
146
|
+
Compute a platform-aware exit status for arbitrary exceptions (errno mappings on POSIX/Windows or BSD `sysexits` when enabled).
|
|
147
|
+
|
|
148
|
+
Parameters:
|
|
149
|
+
- `exc`: Exception instance to classify.
|
|
150
|
+
|
|
151
|
+
### `print_exception_message(trace_back=config.traceback, length_limit=500, stream=None) -> None`
|
|
152
|
+
Emit the active exception using Rich formatting. Produces a coloured traceback when `trace_back` is `True`, otherwise prints a truncated summary in red. Respects `config.traceback_force_color`.
|
|
153
|
+
|
|
154
|
+
Parameters:
|
|
155
|
+
- `trace_back`: Toggle between full traceback rendering (`True`) and short summary (`False`).
|
|
156
|
+
- `length_limit`: Maximum characters for summary output.
|
|
157
|
+
- `stream`: Target text stream; defaults to `sys.stderr`.
|
|
158
|
+
|
|
159
|
+
### `flush_streams() -> None`
|
|
160
|
+
Best-effort flush of `sys.stdout` and `sys.stderr`, ensuring buffered output is written before exit.
|
|
161
|
+
|
|
162
|
+
### `default_signal_specs() -> list[SignalSpec]`
|
|
163
|
+
Return the default signal mapping for the current platform (always includes `SIGINT`, plus `SIGTERM`/`SIGBREAK` when available).
|
|
164
|
+
|
|
165
|
+
### `install_signal_handlers(specs=None) -> Callable[[], None]`
|
|
166
|
+
Register handlers that raise structured exceptions for the provided specs and return a restoration callback. Invoke the callback (typically in a `finally` block) to restore previous handlers.
|
|
167
|
+
|
|
168
|
+
Parameters:
|
|
169
|
+
- `specs`: Iterable of `SignalSpec` objects; defaults to `default_signal_specs()`.
|
|
170
|
+
|
|
171
|
+
### `SignalSpec(signum: int, exception: type[BaseException], message: str, exit_code: int)`
|
|
172
|
+
Lightweight dataclass describing how a signal maps to an exception, stderr message, and exit code.
|
|
173
|
+
|
|
174
|
+
Fields:
|
|
175
|
+
- `signum`: Numeric signal value passed to `signal.signal`.
|
|
176
|
+
- `exception`: Exception type raised by the handler.
|
|
177
|
+
- `message`: Human-readable text echoed when the signal fires.
|
|
178
|
+
- `exit_code`: Exit status returned to the OS.
|
|
179
|
+
|
|
180
|
+
### `CliSignalError` and subclasses
|
|
181
|
+
Hierarchy of marker exceptions raised when signal handlers trigger. Use them to differentiate signal-driven exits from other failures.
|
|
182
|
+
|
|
183
|
+
- `CliSignalError`: Base class.
|
|
184
|
+
- `SigIntInterrupt`: Raised on `SIGINT` (Ctrl+C); maps to exit code `130`.
|
|
185
|
+
- `SigTermInterrupt`: Raised on `SIGTERM`; maps to exit code `143`.
|
|
186
|
+
- `SigBreakInterrupt`: Raised on Windows `SIGBREAK`; maps to exit code `149`.
|
|
187
|
+
|
|
188
|
+
### `default_signal_specs`, `install_signal_handlers`, and `run_cli` contract summary
|
|
189
|
+
When `run_cli` executes your Click command it will:
|
|
190
|
+
1. Build a signal spec list (custom or default).
|
|
191
|
+
2. Optionally install handlers that raise the exceptions above.
|
|
192
|
+
3. Execute the command with `standalone_mode=False`.
|
|
193
|
+
4. Funnel any exception through `handle_cli_exception`.
|
|
194
|
+
5. Restore prior signal handlers and flush streams before returning.
|
|
195
|
+
|
|
196
|
+
This behaviour keeps CLI wiring consistent across projects embedding `lib_cli_exit_tools`.
|
|
197
|
+
|
|
197
198
|
### Advanced CLI wiring
|
|
198
199
|
|
|
199
200
|
For larger applications, keep module execution, console scripts, and shared helpers aligned. The snippet below shows how `__main__.py` can catch unexpected errors and map them through `lib_cli_exit_tools` before exiting:
|
|
@@ -296,11 +297,11 @@ When installed, the generated console scripts (`lib_cli_exit_tools`, `cli-exit-t
|
|
|
296
297
|
- Set `config.exit_code_style = "sysexits"` to map ValueError/TypeError → EX_USAGE(64),
|
|
297
298
|
FileNotFoundError → EX_NOINPUT(66), PermissionError → EX_NOPERM(77), generic OSError → EX_IOERR(74).
|
|
298
299
|
|
|
299
|
-
##
|
|
300
|
-
|
|
301
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md) for contributor workflows, make targets, packaging sync details, and CI/publishing guidance.
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
## License
|
|
300
|
+
## Additional Documentation
|
|
305
301
|
|
|
306
|
-
|
|
302
|
+
- [INSTALL](INSTALL.md)
|
|
303
|
+
- [CHANGELOG](CHANGELOG.md)
|
|
304
|
+
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
305
|
+
- [DEVELOPMENT](DEVELOPMENT.md)
|
|
306
|
+
- [MODULE REFERENCE](docs/system-design/module_reference.md)
|
|
307
|
+
- [LICENSE](LICENSE)
|