lib-cli-exit-tools 1.3.0__tar.gz → 1.4.0__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.4.0}/AGENTS.md +4 -24
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/CHANGELOG.md +10 -0
- lib_cli_exit_tools-1.4.0/INSTALL.md +184 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/PKG-INFO +94 -91
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/README.md +93 -90
- lib_cli_exit_tools-1.4.0/docs/system-design/module_reference.md +242 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/packaging/brew/Formula/lib-cli-exit-tools.rb +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/packaging/conda/recipe/meta.yaml +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/packaging/nix/flake.nix +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/pyproject.toml +1 -1
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/src/lib_cli_exit_tools/__init__.py +1 -1
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/adapters/__init__.py +16 -0
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/adapters/signals.py +177 -0
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/application/__init__.py +16 -0
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/application/runner.py +323 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/src/lib_cli_exit_tools/cli.py +1 -3
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/core/__init__.py +16 -0
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/core/configuration.py +58 -0
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/core/exit_codes.py +149 -0
- lib_cli_exit_tools-1.4.0/src/lib_cli_exit_tools/lib_cli_exit_tools.py +53 -0
- lib_cli_exit_tools-1.4.0/tests/adapters/test_signals.py +75 -0
- lib_cli_exit_tools-1.4.0/tests/application/test_runner.py +233 -0
- lib_cli_exit_tools-1.4.0/tests/cli/test_cli_entrypoints.py +103 -0
- lib_cli_exit_tools-1.4.0/tests/conftest.py +36 -0
- lib_cli_exit_tools-1.4.0/tests/core/test_exit_codes.py +151 -0
- lib_cli_exit_tools-1.3.0/docs/system-design/reference.md +0 -341
- lib_cli_exit_tools-1.3.0/src/lib_cli_exit_tools/lib_cli_exit_tools.py +0 -727
- lib_cli_exit_tools-1.3.0/tests/test_cli.py +0 -85
- lib_cli_exit_tools-1.3.0/tests/test_cli_extra.py +0 -32
- lib_cli_exit_tools-1.3.0/tests/test_exit_tools.py +0 -167
- lib_cli_exit_tools-1.3.0/tests/test_extend_cli.py +0 -111
- lib_cli_exit_tools-1.3.0/tests/test_lib_extra.py +0 -76
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/.env.example +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/.github/workflows/ci.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/.github/workflows/codeql.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/.github/workflows/release.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/.gitignore +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/CONTRIBUTING.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/DEVELOPMENT.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/LICENSE +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/Makefile +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/codecov.yml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/notebooks/Quickstart.ipynb +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/packaging/README.md +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/qlty.toml +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/__init__.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/_utils.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/build.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/bump.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/bump_major.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/bump_minor.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/bump_patch.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/bump_version.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/clean.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/dev.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/generate_nix_flake.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/install.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/menu.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/push.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/release.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/run_cli.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/test.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/scripts/version_current.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/src/lib_cli_exit_tools/__init__conf__.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/src/lib_cli_exit_tools/__main__.py +0 -0
- {lib_cli_exit_tools-1.3.0 → lib_cli_exit_tools-1.4.0}/src/lib_cli_exit_tools/py.typed +0 -0
|
@@ -13,6 +13,8 @@ Review the system prompt files in `/media/srv-main/softdev/*/projects/softwarest
|
|
|
13
13
|
- python_structure_template.md
|
|
14
14
|
- self_documenting.md
|
|
15
15
|
- self_documenting_template.md
|
|
16
|
+
- python_jupyter_notebooks.md
|
|
17
|
+
- python_testing.md
|
|
16
18
|
|
|
17
19
|
always apply those Rules :
|
|
18
20
|
|
|
@@ -41,18 +43,6 @@ when writing or refracturing Python scripts, apply those Rules :
|
|
|
41
43
|
- `packaging/`: Conda, Homebrew, and Nix specs kept in sync via scripts.
|
|
42
44
|
- `tests/`: placeholder suite skipping until logging features exist.
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
## Build, Test, and Development Commands
|
|
46
|
-
|
|
47
|
-
- `make help` — list all targets with one‑line docs.
|
|
48
|
-
- `make test` — run ruff (lint + format check), pyright, pytest with coverage (enabled by default), and upload to Codecov (if configured via `.env`).
|
|
49
|
-
- Auto‑bootstrap: `make test` installs dev tools (`pip install -e .[dev]`) if linters/test deps are missing. Use `SKIP_BOOTSTRAP=1 make test` to disable.
|
|
50
|
-
- Coverage control: `COVERAGE=on|auto|off` (default `on` locally). Uses a unique `COVERAGE_FILE` each run to avoid DB locks.
|
|
51
|
-
- Before uploading to Codecov the harness creates an allow-empty commit (`test: auto commit before Codecov upload`) so the report attaches to a revision. Reset or amend if you do not want to keep it.
|
|
52
|
-
- `make build` — build Python wheel/sdist and attempt Conda/Homebrew/Nix builds (auto‑installs missing tools when needed).
|
|
53
|
-
- `make push` — runs the full `scripts/test.py` flow, prompts for/accepts a commit message (or `COMMIT_MESSAGE`), creates an allow-empty commit if needed, then pushes to the selected remote.
|
|
54
|
-
- `make clean` — remove caches, coverage, and build artifacts (includes `dist/` and `build/`).
|
|
55
|
-
|
|
56
46
|
### Versioning & Releases
|
|
57
47
|
|
|
58
48
|
- Single source of truth for the package version is `pyproject.toml` (`[project].version`).
|
|
@@ -84,13 +74,6 @@ when writing or refracturing Python scripts, apply those Rules :
|
|
|
84
74
|
|
|
85
75
|
## Coding Style & Naming Conventions
|
|
86
76
|
|
|
87
|
-
## Testing Guidelines
|
|
88
|
-
|
|
89
|
-
- Unit and integration-style tests live under `tests/`; keep them up to date when adding features.
|
|
90
|
-
- Extend coverage for new CLI or library behaviour (the suite exercises CLI commands, package metadata, and automation scripts).
|
|
91
|
-
- When adding functionality, replace or remove placeholders and ensure `make test` remains green.
|
|
92
|
-
- write good doctests which clearly show how the function works and what are the intensions. Use it as an enhancement of the inline documentation
|
|
93
|
-
|
|
94
77
|
## Commit & Pull Request Guidelines
|
|
95
78
|
|
|
96
79
|
## Architecture Overview
|
|
@@ -119,13 +102,10 @@ when writing or refracturing Python scripts, apply those Rules :
|
|
|
119
102
|
- run "make test" before any push to avoid lint/test breakage.
|
|
120
103
|
- after push, monitor errors in the github actions and try to correct the errors
|
|
121
104
|
|
|
122
|
-
## Jupyter Notebooks
|
|
123
|
-
use at least nbformat >=4.5
|
|
124
|
-
- "nbformat": 4,
|
|
125
|
-
- "nbformat_minor": 5
|
|
126
|
-
|
|
127
105
|
---
|
|
128
106
|
|
|
107
|
+
# ONLY ON USER REQEST !!!! :
|
|
108
|
+
|
|
129
109
|
# 📘 Documentation Review & Enhancement Prompt
|
|
130
110
|
|
|
131
111
|
You are a **senior software developer specializing in code documentation and system design clarity**. Your task is to review, correct, and enhance all documentation (external and inline) across the codebase with the following principles and workflow.
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.0] - 2025-09-26
|
|
4
|
+
|
|
5
|
+
- Reafracture, TestSuite
|
|
6
|
+
|
|
7
|
+
## [1.3.1] - 2025-09-26
|
|
8
|
+
|
|
9
|
+
- patch colored traceback
|
|
10
|
+
|
|
3
11
|
## [1.3.0] - 2025-09-25
|
|
4
12
|
|
|
5
13
|
- colored traceback
|
|
@@ -47,6 +55,8 @@
|
|
|
47
55
|
- Metadata lookup in `__init__conf__` resolved once and reused.
|
|
48
56
|
- Coverage gate relaxed to 80% and removed `# pragma: no cover` comments.
|
|
49
57
|
- Quickstart notebook defaults to install from GitHub; added cell IDs; last cell prints exit code example instead of exiting.
|
|
58
|
+
- Repartitioned the exit tooling into `core`, `adapters`, and `application` packages with `lib_cli_exit_tools` now acting as a facade to preserve import paths.
|
|
59
|
+
- `run_cli` accepts injectable `exception_handler` and `signal_installer` hooks; CLI rich-click configuration now runs during `main()` execution instead of at import time.
|
|
50
60
|
|
|
51
61
|
### Fixed
|
|
52
62
|
- Pyright 3.10 compatibility in `__init__conf__` by typing to a minimal metadata protocol; resolved unknown `.get` errors.
|
|
@@ -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
|
+
Version: 1.4.0
|
|
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,91 @@ 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, exception_handler=None, signal_installer=None) -> 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
|
+
- `exception_handler`: Optional callable receiving the raised exception and returning an exit code; defaults to ``handle_cli_exception``.
|
|
168
|
+
- `signal_installer`: Optional callable mirroring ``install_signal_handlers`` for embedding scenarios.
|
|
169
|
+
|
|
170
|
+
### `handle_cli_exception(exc, *, signal_specs=None, echo=None) -> int`
|
|
171
|
+
Translate exceptions raised by Click commands into deterministic exit codes, honouring configured signal mappings and traceback policy.
|
|
172
|
+
|
|
173
|
+
Parameters:
|
|
174
|
+
- `exc`: Exception instance to classify.
|
|
175
|
+
- `signal_specs`: Optional iterable of `SignalSpec` objects for custom signal handling.
|
|
176
|
+
- `echo`: Callable matching `click.echo` signature, allowing custom stderr routing during tests or embedding.
|
|
177
|
+
|
|
178
|
+
### `get_system_exit_code(exc) -> int`
|
|
179
|
+
Compute a platform-aware exit status for arbitrary exceptions (errno mappings on POSIX/Windows or BSD `sysexits` when enabled).
|
|
180
|
+
|
|
181
|
+
Parameters:
|
|
182
|
+
- `exc`: Exception instance to classify.
|
|
183
|
+
|
|
184
|
+
### `print_exception_message(trace_back=config.traceback, length_limit=500, stream=None) -> None`
|
|
185
|
+
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`.
|
|
186
|
+
|
|
187
|
+
Parameters:
|
|
188
|
+
- `trace_back`: Toggle between full traceback rendering (`True`) and short summary (`False`).
|
|
189
|
+
- `length_limit`: Maximum characters for summary output.
|
|
190
|
+
- `stream`: Target text stream; defaults to `sys.stderr`.
|
|
191
|
+
|
|
192
|
+
### `flush_streams() -> None`
|
|
193
|
+
Best-effort flush of `sys.stdout` and `sys.stderr`, ensuring buffered output is written before exit.
|
|
194
|
+
|
|
195
|
+
### `default_signal_specs() -> list[SignalSpec]`
|
|
196
|
+
Return the default signal mapping for the current platform (always includes `SIGINT`, plus `SIGTERM`/`SIGBREAK` when available).
|
|
197
|
+
|
|
198
|
+
### `install_signal_handlers(specs=None) -> Callable[[], None]`
|
|
199
|
+
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.
|
|
200
|
+
|
|
201
|
+
Parameters:
|
|
202
|
+
- `specs`: Iterable of `SignalSpec` objects; defaults to `default_signal_specs()`.
|
|
203
|
+
|
|
204
|
+
### `SignalSpec(signum: int, exception: type[BaseException], message: str, exit_code: int)`
|
|
205
|
+
Lightweight dataclass describing how a signal maps to an exception, stderr message, and exit code.
|
|
206
|
+
|
|
207
|
+
Fields:
|
|
208
|
+
- `signum`: Numeric signal value passed to `signal.signal`.
|
|
209
|
+
- `exception`: Exception type raised by the handler.
|
|
210
|
+
- `message`: Human-readable text echoed when the signal fires.
|
|
211
|
+
- `exit_code`: Exit status returned to the OS.
|
|
212
|
+
|
|
213
|
+
### `CliSignalError` and subclasses
|
|
214
|
+
Hierarchy of marker exceptions raised when signal handlers trigger. Use them to differentiate signal-driven exits from other failures.
|
|
215
|
+
|
|
216
|
+
- `CliSignalError`: Base class.
|
|
217
|
+
- `SigIntInterrupt`: Raised on `SIGINT` (Ctrl+C); maps to exit code `130`.
|
|
218
|
+
- `SigTermInterrupt`: Raised on `SIGTERM`; maps to exit code `143`.
|
|
219
|
+
- `SigBreakInterrupt`: Raised on Windows `SIGBREAK`; maps to exit code `149`.
|
|
220
|
+
|
|
221
|
+
### `default_signal_specs`, `install_signal_handlers`, and `run_cli` contract summary
|
|
222
|
+
When `run_cli` executes your Click command it will:
|
|
223
|
+
1. Build a signal spec list (custom or default).
|
|
224
|
+
2. Optionally install handlers that raise the exceptions above.
|
|
225
|
+
3. Execute the command with `standalone_mode=False`.
|
|
226
|
+
4. Funnel any exception through `handle_cli_exception`.
|
|
227
|
+
5. Restore prior signal handlers and flush streams before returning (or rely on any injected replacements).
|
|
228
|
+
|
|
229
|
+
This behaviour keeps CLI wiring consistent across projects embedding `lib_cli_exit_tools` while still allowing custom hooks when needed.
|
|
230
|
+
|
|
228
231
|
### Advanced CLI wiring
|
|
229
232
|
|
|
230
233
|
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 +330,11 @@ When installed, the generated console scripts (`lib_cli_exit_tools`, `cli-exit-t
|
|
|
327
330
|
- Set `config.exit_code_style = "sysexits"` to map ValueError/TypeError → EX_USAGE(64),
|
|
328
331
|
FileNotFoundError → EX_NOINPUT(66), PermissionError → EX_NOPERM(77), generic OSError → EX_IOERR(74).
|
|
329
332
|
|
|
330
|
-
##
|
|
331
|
-
|
|
332
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md) for contributor workflows, make targets, packaging sync details, and CI/publishing guidance.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
## License
|
|
333
|
+
## Additional Documentation
|
|
336
334
|
|
|
337
|
-
|
|
335
|
+
- [INSTALL](INSTALL.md)
|
|
336
|
+
- [CHANGELOG](CHANGELOG.md)
|
|
337
|
+
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
338
|
+
- [DEVELOPMENT](DEVELOPMENT.md)
|
|
339
|
+
- [MODULE REFERENCE](docs/system-design/module_reference.md)
|
|
340
|
+
- [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,91 @@ 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, exception_handler=None, signal_installer=None) -> 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
|
+
- `exception_handler`: Optional callable receiving the raised exception and returning an exit code; defaults to ``handle_cli_exception``.
|
|
137
|
+
- `signal_installer`: Optional callable mirroring ``install_signal_handlers`` for embedding scenarios.
|
|
138
|
+
|
|
139
|
+
### `handle_cli_exception(exc, *, signal_specs=None, echo=None) -> int`
|
|
140
|
+
Translate exceptions raised by Click commands into deterministic exit codes, honouring configured signal mappings and traceback policy.
|
|
141
|
+
|
|
142
|
+
Parameters:
|
|
143
|
+
- `exc`: Exception instance to classify.
|
|
144
|
+
- `signal_specs`: Optional iterable of `SignalSpec` objects for custom signal handling.
|
|
145
|
+
- `echo`: Callable matching `click.echo` signature, allowing custom stderr routing during tests or embedding.
|
|
146
|
+
|
|
147
|
+
### `get_system_exit_code(exc) -> int`
|
|
148
|
+
Compute a platform-aware exit status for arbitrary exceptions (errno mappings on POSIX/Windows or BSD `sysexits` when enabled).
|
|
149
|
+
|
|
150
|
+
Parameters:
|
|
151
|
+
- `exc`: Exception instance to classify.
|
|
152
|
+
|
|
153
|
+
### `print_exception_message(trace_back=config.traceback, length_limit=500, stream=None) -> None`
|
|
154
|
+
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`.
|
|
155
|
+
|
|
156
|
+
Parameters:
|
|
157
|
+
- `trace_back`: Toggle between full traceback rendering (`True`) and short summary (`False`).
|
|
158
|
+
- `length_limit`: Maximum characters for summary output.
|
|
159
|
+
- `stream`: Target text stream; defaults to `sys.stderr`.
|
|
160
|
+
|
|
161
|
+
### `flush_streams() -> None`
|
|
162
|
+
Best-effort flush of `sys.stdout` and `sys.stderr`, ensuring buffered output is written before exit.
|
|
163
|
+
|
|
164
|
+
### `default_signal_specs() -> list[SignalSpec]`
|
|
165
|
+
Return the default signal mapping for the current platform (always includes `SIGINT`, plus `SIGTERM`/`SIGBREAK` when available).
|
|
166
|
+
|
|
167
|
+
### `install_signal_handlers(specs=None) -> Callable[[], None]`
|
|
168
|
+
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.
|
|
169
|
+
|
|
170
|
+
Parameters:
|
|
171
|
+
- `specs`: Iterable of `SignalSpec` objects; defaults to `default_signal_specs()`.
|
|
172
|
+
|
|
173
|
+
### `SignalSpec(signum: int, exception: type[BaseException], message: str, exit_code: int)`
|
|
174
|
+
Lightweight dataclass describing how a signal maps to an exception, stderr message, and exit code.
|
|
175
|
+
|
|
176
|
+
Fields:
|
|
177
|
+
- `signum`: Numeric signal value passed to `signal.signal`.
|
|
178
|
+
- `exception`: Exception type raised by the handler.
|
|
179
|
+
- `message`: Human-readable text echoed when the signal fires.
|
|
180
|
+
- `exit_code`: Exit status returned to the OS.
|
|
181
|
+
|
|
182
|
+
### `CliSignalError` and subclasses
|
|
183
|
+
Hierarchy of marker exceptions raised when signal handlers trigger. Use them to differentiate signal-driven exits from other failures.
|
|
184
|
+
|
|
185
|
+
- `CliSignalError`: Base class.
|
|
186
|
+
- `SigIntInterrupt`: Raised on `SIGINT` (Ctrl+C); maps to exit code `130`.
|
|
187
|
+
- `SigTermInterrupt`: Raised on `SIGTERM`; maps to exit code `143`.
|
|
188
|
+
- `SigBreakInterrupt`: Raised on Windows `SIGBREAK`; maps to exit code `149`.
|
|
189
|
+
|
|
190
|
+
### `default_signal_specs`, `install_signal_handlers`, and `run_cli` contract summary
|
|
191
|
+
When `run_cli` executes your Click command it will:
|
|
192
|
+
1. Build a signal spec list (custom or default).
|
|
193
|
+
2. Optionally install handlers that raise the exceptions above.
|
|
194
|
+
3. Execute the command with `standalone_mode=False`.
|
|
195
|
+
4. Funnel any exception through `handle_cli_exception`.
|
|
196
|
+
5. Restore prior signal handlers and flush streams before returning (or rely on any injected replacements).
|
|
197
|
+
|
|
198
|
+
This behaviour keeps CLI wiring consistent across projects embedding `lib_cli_exit_tools` while still allowing custom hooks when needed.
|
|
199
|
+
|
|
197
200
|
### Advanced CLI wiring
|
|
198
201
|
|
|
199
202
|
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 +299,11 @@ When installed, the generated console scripts (`lib_cli_exit_tools`, `cli-exit-t
|
|
|
296
299
|
- Set `config.exit_code_style = "sysexits"` to map ValueError/TypeError → EX_USAGE(64),
|
|
297
300
|
FileNotFoundError → EX_NOINPUT(66), PermissionError → EX_NOPERM(77), generic OSError → EX_IOERR(74).
|
|
298
301
|
|
|
299
|
-
##
|
|
300
|
-
|
|
301
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md) for contributor workflows, make targets, packaging sync details, and CI/publishing guidance.
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
## License
|
|
302
|
+
## Additional Documentation
|
|
305
303
|
|
|
306
|
-
|
|
304
|
+
- [INSTALL](INSTALL.md)
|
|
305
|
+
- [CHANGELOG](CHANGELOG.md)
|
|
306
|
+
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
307
|
+
- [DEVELOPMENT](DEVELOPMENT.md)
|
|
308
|
+
- [MODULE REFERENCE](docs/system-design/module_reference.md)
|
|
309
|
+
- [LICENSE](LICENSE)
|