lib-cli-exit-tools 2.0.0__tar.gz → 2.1.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.
Files changed (91) hide show
  1. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.github/workflows/ci.yml +43 -5
  2. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.github/workflows/codeql.yml +1 -1
  3. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.github/workflows/release.yml +13 -5
  4. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.gitignore +1 -0
  5. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/AGENTS.md +2 -2
  6. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/CHANGELOG.md +22 -0
  7. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/DEVELOPMENT.md +4 -4
  8. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/INSTALL.md +2 -2
  9. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/Makefile +7 -1
  10. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/PKG-INFO +23 -21
  11. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/README.md +10 -8
  12. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/docs/system-design/module_reference.md +5 -5
  13. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/notebooks/Quickstart.ipynb +1 -1
  14. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/pyproject.toml +54 -14
  15. lib_cli_exit_tools-2.1.1/scripts/_utils.py +802 -0
  16. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/build.py +14 -1
  17. lib_cli_exit_tools-2.1.1/scripts/clean.py +75 -0
  18. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/cli.py +20 -1
  19. lib_cli_exit_tools-2.1.1/scripts/dependencies.py +590 -0
  20. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/menu.py +33 -19
  21. lib_cli_exit_tools-2.1.1/scripts/push.py +309 -0
  22. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/release.py +3 -1
  23. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/target_metadata.py +32 -4
  24. lib_cli_exit_tools-2.1.1/scripts/test.py +1004 -0
  25. lib_cli_exit_tools-2.1.1/scripts/toml_config.py +455 -0
  26. lib_cli_exit_tools-2.1.1/src/lib_cli_exit_tools/__init__conf__.py +74 -0
  27. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/application/runner.py +48 -8
  28. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/cli.py +70 -16
  29. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/core/configuration.py +43 -11
  30. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/core/exit_codes.py +18 -1
  31. lib_cli_exit_tools-2.1.1/tests/conftest.py +110 -0
  32. lib_cli_exit_tools-2.1.1/tests/test_adapters_signals.py +198 -0
  33. lib_cli_exit_tools-2.1.1/tests/test_application_runner.py +476 -0
  34. lib_cli_exit_tools-2.1.1/tests/test_behaviors.py +226 -0
  35. lib_cli_exit_tools-2.1.1/tests/test_cli.py +307 -0
  36. lib_cli_exit_tools-2.1.1/tests/test_core_configuration.py +164 -0
  37. lib_cli_exit_tools-2.1.1/tests/test_core_exit_codes.py +358 -0
  38. lib_cli_exit_tools-2.1.1/tests/test_metadata.py +218 -0
  39. lib_cli_exit_tools-2.1.1/tests/test_module_entry.py +262 -0
  40. lib_cli_exit_tools-2.1.1/tests/test_signals_integration.py +219 -0
  41. lib_cli_exit_tools-2.0.0/scripts/_utils.py +0 -439
  42. lib_cli_exit_tools-2.0.0/scripts/clean.py +0 -48
  43. lib_cli_exit_tools-2.0.0/scripts/push.py +0 -70
  44. lib_cli_exit_tools-2.0.0/scripts/test.py +0 -541
  45. lib_cli_exit_tools-2.0.0/src/lib_cli_exit_tools/__init__conf__.py +0 -220
  46. lib_cli_exit_tools-2.0.0/tests/conftest.py +0 -57
  47. lib_cli_exit_tools-2.0.0/tests/test_adapters_signals.py +0 -65
  48. lib_cli_exit_tools-2.0.0/tests/test_application_runner.py +0 -385
  49. lib_cli_exit_tools-2.0.0/tests/test_behaviors.py +0 -99
  50. lib_cli_exit_tools-2.0.0/tests/test_cli.py +0 -152
  51. lib_cli_exit_tools-2.0.0/tests/test_core_configuration.py +0 -47
  52. lib_cli_exit_tools-2.0.0/tests/test_core_exit_codes.py +0 -265
  53. lib_cli_exit_tools-2.0.0/tests/test_metadata.py +0 -101
  54. lib_cli_exit_tools-2.0.0/tests/test_module_entry.py +0 -137
  55. lib_cli_exit_tools-2.0.0/tests/test_signals_integration.py +0 -122
  56. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.codacy/cli-config.yaml +0 -0
  57. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.codacy/cli.sh +0 -0
  58. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.codacy/codacy.yaml +0 -0
  59. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.codacy/tools-configs/lizard.yaml +0 -0
  60. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.codacy/tools-configs/trivy.yaml +0 -0
  61. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.devcontainer/devcontainer.json +0 -0
  62. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.devcontainer/settings.json +0 -0
  63. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.env.example +0 -0
  64. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.github/dependabot.yml +0 -0
  65. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.qlty/qlty.toml +0 -0
  66. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/.snyk +0 -0
  67. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/AGENTS_README.md +0 -0
  68. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/CONTRIBUTING.md +0 -0
  69. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/LICENSE +0 -0
  70. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/codecov.yml +0 -0
  71. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/__init__.py +0 -0
  72. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/__main__.py +0 -0
  73. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/bump.py +0 -0
  74. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/bump_major.py +0 -0
  75. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/bump_minor.py +0 -0
  76. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/bump_patch.py +0 -0
  77. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/bump_version.py +0 -0
  78. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/dev.py +0 -0
  79. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/help.py +0 -0
  80. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/install.py +0 -0
  81. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/run_cli.py +0 -0
  82. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/scripts/version_current.py +0 -0
  83. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/__init__.py +0 -0
  84. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/__main__.py +0 -0
  85. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/adapters/__init__.py +0 -0
  86. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/adapters/signals.py +0 -0
  87. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/application/__init__.py +0 -0
  88. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/core/__init__.py +0 -0
  89. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +0 -0
  90. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/src/lib_cli_exit_tools/py.typed +0 -0
  91. {lib_cli_exit_tools-2.0.0 → lib_cli_exit_tools-2.1.1}/tests/test_scripts.py +0 -0
@@ -5,6 +5,9 @@ on:
5
5
  branches: [ main, master ]
6
6
  pull_request:
7
7
  branches: [ main, master ]
8
+ schedule:
9
+ # Run daily at 3:17 AM UTC (off-peak hours, odd minute to avoid congestion)
10
+ - cron: '17 3 * * *'
8
11
 
9
12
  jobs:
10
13
  test:
@@ -16,11 +19,20 @@ jobs:
16
19
  os: [ubuntu-latest, macos-latest, windows-latest]
17
20
  # Test against Python 3.13 and the latest 3.x available on Actions runners
18
21
  python: ["3.13", "3.x"]
22
+ env:
23
+ PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"
24
+ PYTHONIOENCODING: "utf-8"
19
25
  steps:
20
- - uses: actions/checkout@v5
26
+ - uses: actions/checkout@v6
21
27
  - uses: actions/setup-python@v6
22
28
  with:
23
29
  python-version: ${{ matrix.python }}
30
+ cache: 'pip'
31
+ cache-dependency-path: 'pyproject.toml'
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@v7
34
+ with:
35
+ enable-cache: true
24
36
  - name: Extract project metadata
25
37
  shell: python
26
38
  run: |
@@ -45,6 +57,13 @@ jobs:
45
57
  run: |
46
58
  choco install -y make
47
59
  echo "C:\\ProgramData\\chocolatey\\bin" >> $env:GITHUB_PATH
60
+ - name: Install journald prerequisites
61
+ if: runner.os == 'Linux'
62
+ shell: bash
63
+ run: |
64
+ sudo apt-get update
65
+ sudo apt-get install -y python3-systemd
66
+
48
67
  - name: Upgrade pip
49
68
  shell: bash
50
69
  run: python -m pip install --upgrade pip
@@ -52,13 +71,28 @@ jobs:
52
71
  - name: Install dev deps
53
72
  shell: bash
54
73
  run: |
55
- pip install -e .[dev]
74
+ uv pip install -e .[dev] --system
56
75
 
57
76
  - name: Install Windows Event Log prerequisites
58
77
  if: runner.os == 'Windows'
59
78
  shell: bash
60
79
  run: |
61
- pip install pywin32
80
+ uv pip install pywin32 --system
81
+ - name: Cache ruff
82
+ uses: actions/cache@v4
83
+ with:
84
+ path: .ruff_cache
85
+ key: ruff-${{ runner.os }}-${{ github.sha }}
86
+ restore-keys: |
87
+ ruff-${{ runner.os }}-
88
+ - name: Cache pyright
89
+ uses: actions/cache@v4
90
+ with:
91
+ path: .pyright
92
+ key: pyright-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
93
+ restore-keys: |
94
+ pyright-${{ runner.os }}-py${{ matrix.python }}-
95
+ pyright-${{ runner.os }}-
62
96
  - name: Run full test suite (lint, types, tests, coverage, codecov)
63
97
  shell: bash
64
98
  env:
@@ -79,10 +113,12 @@ jobs:
79
113
  name: pipx/uv verification (ubuntu)
80
114
  runs-on: ubuntu-latest
81
115
  steps:
82
- - uses: actions/checkout@v5
116
+ - uses: actions/checkout@v6
83
117
  - uses: actions/setup-python@v6
84
118
  with:
85
119
  python-version: "3.13"
120
+ cache: 'pip'
121
+ cache-dependency-path: 'pyproject.toml'
86
122
  - name: Extract project metadata
87
123
  shell: python
88
124
  run: |
@@ -123,10 +159,12 @@ jobs:
123
159
  name: Execute notebooks (ubuntu, Python 3.13)
124
160
  runs-on: ubuntu-latest
125
161
  steps:
126
- - uses: actions/checkout@v5
162
+ - uses: actions/checkout@v6
127
163
  - uses: actions/setup-python@v6
128
164
  with:
129
165
  python-version: "3.13"
166
+ cache: 'pip'
167
+ cache-dependency-path: 'pyproject.toml'
130
168
  - name: Install notebook runner deps
131
169
  run: |
132
170
  python -m pip install --upgrade pip
@@ -23,7 +23,7 @@ jobs:
23
23
 
24
24
  steps:
25
25
  - name: Checkout repository
26
- uses: actions/checkout@v5
26
+ uses: actions/checkout@v6
27
27
 
28
28
  - name: Initialize CodeQL
29
29
  uses: github/codeql-action/init@v4
@@ -14,29 +14,37 @@ jobs:
14
14
  permissions:
15
15
  contents: read
16
16
  steps:
17
- - uses: actions/checkout@v5
17
+ - uses: actions/checkout@v6
18
18
  - name: Verify PyPI token is set
19
19
  run: |
20
20
  if [ -z "${{ secrets.PYPI_API_TOKEN }}" ]; then
21
- echo "::error title=Missing PyPI token::Set the PYPI_API_TOKEN secret in GitHub repository settings to enable PyPI publishing on releases."
22
- echo "See: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions"
21
+ echo "::error title=Missing PyPI token::Set the PYPI_API_TOKEN secret in GitHub repository settings to enable PyPI publishing on releases."
22
+ echo "See: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions"
23
23
  exit 1
24
24
  fi
25
25
  - uses: actions/setup-python@v6
26
26
  with:
27
27
  python-version: '3.13'
28
+ cache: 'pip'
29
+ cache-dependency-path: 'pyproject.toml'
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v7
32
+ with:
33
+ enable-cache: true
28
34
  - name: Build artifacts
29
35
  run: |
30
- python -m pip install --upgrade pip build
36
+ python -m pip install --upgrade pip
37
+ uv pip install build --system
31
38
  python -m build
32
39
  - name: Publish to PyPI
33
40
  # Use the rolling major tag to get latest Twine/standards support (e.g., Core Metadata 2.4)
34
41
  uses: pypa/gh-action-pypi-publish@release/v1
35
42
  with:
36
43
  password: ${{ secrets.PYPI_API_TOKEN }}
44
+ attestations: false
37
45
  skip-existing: true
38
46
  - name: Upload artifacts
39
- uses: actions/upload-artifact@v4
47
+ uses: actions/upload-artifact@v5
40
48
  with:
41
49
  name: dist
42
50
  path: dist/*
@@ -178,3 +178,4 @@ result
178
178
  poetry.lock
179
179
  pdm.lock
180
180
  uv.lock
181
+ /.github_bak/
@@ -50,8 +50,8 @@ when writing or refracturing Python scripts, apply those Rules :
50
50
  ### Versioning & Releases
51
51
 
52
52
  - Single source of truth for the package version is `pyproject.toml` (`[project].version`).
53
- - Runtime code reads metadata via `importlib.metadata`; do not duplicate the version in code files.
54
- - On a version bump, update only `pyproject.toml` and the `CHANGELOG.md` entry; runtime code should continue to read the version via `importlib.metadata` (no separate `__init__conf__` file).
53
+ - Automation rewrites `src/lib_cli_exit_tools/__init__conf__.py` from `pyproject.toml`, so runtime code imports generated constants instead of querying `importlib.metadata`.
54
+ - After updating project metadata (version, summary, URLs, authors) run `make test` (or `python -m scripts.test`) to regenerate the metadata module before committing.
55
55
  - Tag releases `vX.Y.Z` and push tags; CI will build artifacts and publish when configured.
56
56
 
57
57
  ### Common Make Targets (Alphabetical)
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
5
 
6
+ ## [2.1.1] - 2025-12-08
7
+
8
+ ### Changed
9
+ - Enforced strict data architecture by introducing TypedDict classes (`RichClickSnapshot`, `CliContextState`, `ConfigSnapshot`, `SessionOverrides`) to eliminate raw dictionary access patterns.
10
+ - Added `_is_posix_platform()` helper function to centralise platform detection and avoid string literal comparisons.
11
+ - Replaced assert-based type guards with explicit conditional checks to satisfy Bandit security scanning.
12
+
13
+ ### Refactored
14
+ - Comprehensive test suite refactoring following clean architecture principles:
15
+ - Each test now verifies exactly one behaviour with descriptive naming.
16
+ - Added OS-specific markers (`@pytest.mark.posix_only`, `@pytest.mark.windows_only`, `@pytest.mark.os_agnostic`) for platform-aware test execution.
17
+ - Centralised shared fixtures in `conftest.py` including `cli_runner`, `strip_ansi`, `reset_config`, and `sysexits_mode`.
18
+ - Prefer real behaviour tests over mocks where possible, particularly for signal handling.
19
+ - Organised tests into logical sections with clear header comments.
20
+
21
+ ## [2.1.0] - 2025-10-13
22
+
23
+ ### Changed
24
+ - `scripts.build` now calls `sync_metadata_module()` before invoking `python -m build`, ensuring wheels and sdists ship freshly generated metadata.
25
+ - Added an explicit CLI test covering the `--version` flag so console-script aliases stay aligned with generated constants.
26
+ - Updated README, INSTALL instructions, and the Quickstart notebook to document `lib-cli-exit-tools` as the canonical console entry point alongside its aliases.
27
+
6
28
  ## [2.0.0] - 2025-10-12
7
29
 
8
30
  ### Changed
@@ -118,10 +118,10 @@ keep the signal-handling guarantees honest.
118
118
 
119
119
  ## Versioning & Metadata
120
120
 
121
- - Single source of truth for package metadata is `pyproject.toml` (`[project]`).
122
- - The library reads its own installed metadata at runtime via `importlib.metadata` (see `src/lib_cli_exit_tools/__init__conf__.py`).
123
- - Do not duplicate the version in code; bump only `pyproject.toml` and update `CHANGELOG.md`.
124
- - Console script name is discovered from entry points; defaults to `lib_cli_exit_tools`.
121
+ - `pyproject.toml` (`[project]`) remains the single source of truth for name, version, homepage, and authors.
122
+ - `scripts._utils.sync_metadata_module()` rewrites `src/lib_cli_exit_tools/__init__conf__.py` so runtime code consumes generated constants instead of `importlib.metadata`.
123
+ - After editing project metadata (name, version, description, URLs, authors), run `make test` or `python -m scripts.test` to regenerate the module before committing.
124
+ - Console script name is still discovered from entry points; automation falls back to `lib_cli_exit_tools` when no explicit alias exists.
125
125
 
126
126
  ## CI & Publishing
127
127
 
@@ -85,7 +85,7 @@ pipx install "git+https://github.com/bitranox/lib_cli_exit_tools@vX.Y.Z"
85
85
  ```bash
86
86
  uv pip install -e .[dev]
87
87
  uv tool install lib_cli_exit_tools
88
- uvx lib_cli_exit_tools --help
88
+ uvx lib-cli-exit-tools --help # aliases: cli-exit-tools, lib_cli_exit_tools
89
89
  ```
90
90
 
91
91
  ### Installing from local artifacts
@@ -153,7 +153,7 @@ error: externally-managed-environment
153
153
 
154
154
  ### Missing command on PATH
155
155
 
156
- 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.
156
+ If `lib-cli-exit-tools --help` (or the aliases `cli-exit-tools` / `lib_cli_exit_tools`) 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.
157
157
 
158
158
  ### Colour output not appearing
159
159
 
@@ -3,7 +3,7 @@ SHELL := /bin/bash
3
3
  PYTHON ?= python3
4
4
  SCRIPTS ?= $(PYTHON) -m scripts
5
5
 
6
- .PHONY: help install dev test run clean build push release coverage version-current bump bump-patch bump-minor bump-major menu
6
+ .PHONY: help install dev test run clean build push release coverage version-current bump bump-patch bump-minor bump-major dependencies dependencies-update menu
7
7
 
8
8
  help:
9
9
  $(SCRIPTS) help
@@ -50,5 +50,11 @@ build:
50
50
  release:
51
51
  $(SCRIPTS) release
52
52
 
53
+ dependencies:
54
+ $(SCRIPTS) dependencies
55
+
56
+ dependencies-update:
57
+ $(SCRIPTS) dependencies-update
58
+
53
59
  menu:
54
60
  $(SCRIPTS) menu
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lib_cli_exit_tools
3
- Version: 2.0.0
3
+ Version: 2.1.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
@@ -16,21 +16,21 @@ Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
17
  Classifier: Typing :: Typed
18
18
  Requires-Python: >=3.13
19
- Requires-Dist: rich-click>=1.9.3
19
+ Requires-Dist: rich-click>=1.9.4
20
20
  Provides-Extra: dev
21
- Requires-Dist: bandit>=1.8.6; extra == 'dev'
21
+ Requires-Dist: bandit>=1.9.2; extra == 'dev'
22
22
  Requires-Dist: build>=1.3.0; extra == 'dev'
23
- Requires-Dist: codecov-cli>=11.2.3; extra == 'dev'
24
- Requires-Dist: coverage[toml]>=7.10.7; extra == 'dev'
25
- Requires-Dist: hypothesis>=6.140.3; extra == 'dev'
26
- Requires-Dist: import-linter>=2.5.2; extra == 'dev'
27
- Requires-Dist: pip-audit>=2.9.0; extra == 'dev'
28
- Requires-Dist: pyright>=1.1.406; extra == 'dev'
29
- Requires-Dist: pytest-asyncio>=1.2.0; extra == 'dev'
23
+ Requires-Dist: codecov-cli>=11.2.6; extra == 'dev'
24
+ Requires-Dist: coverage[toml]>=7.13.0; extra == 'dev'
25
+ Requires-Dist: hypothesis>=6.148.7; extra == 'dev'
26
+ Requires-Dist: import-linter>=2.7; extra == 'dev'
27
+ Requires-Dist: pip-audit>=2.10.0; extra == 'dev'
28
+ Requires-Dist: pyright>=1.1.407; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
30
30
  Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
31
- Requires-Dist: pytest>=8.4.2; extra == 'dev'
32
- Requires-Dist: ruff>=0.14.0; extra == 'dev'
33
- Requires-Dist: textual>=6.3.0; extra == 'dev'
31
+ Requires-Dist: pytest>=9.0.2; extra == 'dev'
32
+ Requires-Dist: ruff>=0.14.8; extra == 'dev'
33
+ Requires-Dist: textual>=6.8.0; extra == 'dev'
34
34
  Requires-Dist: twine>=6.2.0; extra == 'dev'
35
35
  Description-Content-Type: text/markdown
36
36
 
@@ -47,6 +47,7 @@ Description-Content-Type: text/markdown
47
47
  [![codecov](https://codecov.io/gh/bitranox/lib_cli_exit_tools/graph/badge.svg?token=z1D8JSjWEH)](https://codecov.io/gh/bitranox/lib_cli_exit_tools)
48
48
  [![Maintainability](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools/maintainability.svg)](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools)
49
49
  [![Known Vulnerabilities](https://snyk.io/test/github/bitranox/lib_cli_exit_tools/badge.svg)](https://snyk.io/test/github/bitranox/lib_cli_exit_tools)
50
+ [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
50
51
 
51
52
  Small helpers for robust CLI exit handling:
52
53
  - Portable signal handling (SIGINT, SIGTERM/SIGBREAK)
@@ -65,14 +66,14 @@ See [INSTALL.md](INSTALL.md) for editable installs, pipx/uv usage, and troublesh
65
66
 
66
67
  ## Usage
67
68
 
68
- Console script:
69
+ Console script (all commands map to ``lib_cli_exit_tools.cli:main``):
69
70
 
70
71
  ```bash
71
72
  # After install (pip/pipx/uv tool)
72
- lib_cli_exit_tools --help
73
- cli-exit-tools --help # alias
74
- lib_cli_exit_tools info
75
- lib_cli_exit_tools fail # intentionally trigger RuntimeError to test error paths
73
+ lib-cli-exit-tools --help
74
+ lib-cli-exit-tools info
75
+ lib-cli-exit-tools fail # intentionally trigger RuntimeError to test error paths
76
+ # Aliases are also generated: `cli-exit-tools`, `lib_cli_exit_tools`
76
77
  ```
77
78
 
78
79
  ### Examples
@@ -280,9 +281,10 @@ except Exception as e:
280
281
  raise SystemExit(code)
281
282
  ```
282
283
 
283
- Command names registered on install
284
- - lib_cli_exit_tools (default)
284
+ Command names registered on install (all invoke ``lib_cli_exit_tools.cli:main``)
285
+ - lib-cli-exit-tools (default console script)
285
286
  - cli-exit-tools (alias)
287
+ - lib_cli_exit_tools (alias)
286
288
  - python -m lib_cli_exit_tools (module entry)
287
289
 
288
290
  If you installed with --user or in a venv, make sure the corresponding bin directory is on PATH:
@@ -562,7 +564,7 @@ def main(argv: Sequence[str] | None = None) -> int:
562
564
  )
563
565
  ```
564
566
 
565
- When installed, the generated console scripts (`lib_cli_exit_tools`, `cli-exit-tools`, `lib-cli-exit-tools`) will import `your_package.cli:main`, and `python -m your_package` will follow the same code path via `__main__.py`.
567
+ When installed, the generated console scripts (`lib-cli-exit-tools`, `cli-exit-tools`, `lib_cli_exit_tools`) will import `your_package.cli:main`, and `python -m your_package` will follow the same code path via `__main__.py`.
566
568
 
567
569
  ## Exit Codes
568
570
 
@@ -11,6 +11,7 @@
11
11
  [![codecov](https://codecov.io/gh/bitranox/lib_cli_exit_tools/graph/badge.svg?token=z1D8JSjWEH)](https://codecov.io/gh/bitranox/lib_cli_exit_tools)
12
12
  [![Maintainability](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools/maintainability.svg)](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools)
13
13
  [![Known Vulnerabilities](https://snyk.io/test/github/bitranox/lib_cli_exit_tools/badge.svg)](https://snyk.io/test/github/bitranox/lib_cli_exit_tools)
14
+ [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
14
15
 
15
16
  Small helpers for robust CLI exit handling:
16
17
  - Portable signal handling (SIGINT, SIGTERM/SIGBREAK)
@@ -29,14 +30,14 @@ See [INSTALL.md](INSTALL.md) for editable installs, pipx/uv usage, and troublesh
29
30
 
30
31
  ## Usage
31
32
 
32
- Console script:
33
+ Console script (all commands map to ``lib_cli_exit_tools.cli:main``):
33
34
 
34
35
  ```bash
35
36
  # After install (pip/pipx/uv tool)
36
- lib_cli_exit_tools --help
37
- cli-exit-tools --help # alias
38
- lib_cli_exit_tools info
39
- lib_cli_exit_tools fail # intentionally trigger RuntimeError to test error paths
37
+ lib-cli-exit-tools --help
38
+ lib-cli-exit-tools info
39
+ lib-cli-exit-tools fail # intentionally trigger RuntimeError to test error paths
40
+ # Aliases are also generated: `cli-exit-tools`, `lib_cli_exit_tools`
40
41
  ```
41
42
 
42
43
  ### Examples
@@ -244,9 +245,10 @@ except Exception as e:
244
245
  raise SystemExit(code)
245
246
  ```
246
247
 
247
- Command names registered on install
248
- - lib_cli_exit_tools (default)
248
+ Command names registered on install (all invoke ``lib_cli_exit_tools.cli:main``)
249
+ - lib-cli-exit-tools (default console script)
249
250
  - cli-exit-tools (alias)
251
+ - lib_cli_exit_tools (alias)
250
252
  - python -m lib_cli_exit_tools (module entry)
251
253
 
252
254
  If you installed with --user or in a venv, make sure the corresponding bin directory is on PATH:
@@ -526,7 +528,7 @@ def main(argv: Sequence[str] | None = None) -> int:
526
528
  )
527
529
  ```
528
530
 
529
- When installed, the generated console scripts (`lib_cli_exit_tools`, `cli-exit-tools`, `lib-cli-exit-tools`) will import `your_package.cli:main`, and `python -m your_package` will follow the same code path via `__main__.py`.
531
+ When installed, the generated console scripts (`lib-cli-exit-tools`, `cli-exit-tools`, `lib_cli_exit_tools`) will import `your_package.cli:main`, and `python -m your_package` will follow the same code path via `__main__.py`.
530
532
 
531
533
  ## Exit Codes
532
534
 
@@ -38,7 +38,7 @@ Downstream CLIs and automation pipelines need deterministic exit codes, signal h
38
38
  * Split runtime responsibilities into well-documented modules (`core`, `application`, `adapters`, `cli`) that mirror clean-architecture prompts.
39
39
  * Provide a lightweight metadata façade (`__init__conf__.py`) so CLI commands expose provenance without heavy packaging dependencies.
40
40
  * Funnel all exit handling through `application.runner` and `core.exit_codes`, documenting each resolver path and configuration hook.
41
- * Publish behaviour-driven tests that read like specifications and explicitly cover CLI surfaces, metadata fallbacks, module entry balance, and automation scripts.
41
+ * Publish behaviour-driven tests that read like specifications and explicitly cover CLI surfaces, metadata exports, module entry balance, and automation scripts.
42
42
  * Align system documentation with inline docstrings and testing strategy to create a single source of truth for maintainers.
43
43
 
44
44
  ---
@@ -56,7 +56,7 @@ Downstream CLIs and automation pipelines need deterministic exit codes, signal h
56
56
  5. `core.exit_codes` resolves exit codes via ordered strategies (subprocess return codes, signals, errno/winerror, sysexits, platform tables).
57
57
  6. `__init__conf__.py` supplies metadata for `info` commands and documentation output.
58
58
 
59
- **System Dependencies:** Standard library (`signal`, `sys`, `subprocess`, `importlib.metadata`, `contextlib`, `dataclasses`), `click`, `rich`, `rich-click`.
59
+ **System Dependencies:** Standard library (`signal`, `sys`, `subprocess`, `contextlib`, `dataclasses`), `click`, `rich`, `rich-click`.
60
60
 
61
61
  ---
62
62
 
@@ -78,9 +78,9 @@ Downstream CLIs and automation pipelines need deterministic exit codes, signal h
78
78
 
79
79
  ### Module: lib_cli_exit_tools/__init__conf__.py
80
80
 
81
- * **Purpose:** Provide metadata helpers and `print_info()` for CLI provenance.
82
- * **Input:** Distribution metadata via `importlib.metadata`; fallback defaults.
83
- * **Output:** Constants (`name`, `title`, `version`, `homepage`, `author`, `shell_command`) and metadata helpers (`_meta`, `_version`, `_home_page`, `_author`, `_summary`).
81
+ * **Purpose:** Publish static metadata constants and `print_info()` for CLI provenance.
82
+ * **Input:** Generated from `pyproject.toml` by `scripts._utils.sync_metadata_module`; no runtime metadata lookups.
83
+ * **Output:** Constants (`name`, `title`, `version`, `homepage`, `author`, `author_email`, `shell_command`) and the formatted `print_info()` helper.
84
84
  * **Location:** `src/lib_cli_exit_tools/__init__conf__.py`
85
85
 
86
86
  ### Module: lib_cli_exit_tools/core/configuration.py
@@ -70,7 +70,7 @@
70
70
  "outputs": [],
71
71
  "source": [
72
72
  "!lib_cli_exit_tools --version\n",
73
- "!lib_cli_exit_tools --help\n",
73
+ "!lib-cli-exit-tools --help\n",
74
74
  "!lib_cli_exit_tools info"
75
75
  ]
76
76
  },
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "lib_cli_exit_tools"
3
- version = "2.0.0"
3
+ version = "2.1.1"
4
4
  description = "CLI exit handling helpers: clean signals, exit codes, and error printing"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
7
- dependencies = ["rich-click>=1.9.3"]
7
+ dependencies = ["rich-click>=1.9.4"]
8
8
  license = { text = "MIT" }
9
9
  authors = [{ name = "bitranox", email = "bitranox@gmail.com" }]
10
10
  keywords = ["cli", "exit", "signals", "errors", "click"]
@@ -25,18 +25,18 @@ Issues = "https://github.com/bitranox/lib_cli_exit_tools/issues"
25
25
  [project.optional-dependencies]
26
26
  dev = [
27
27
  "build>=1.3.0",
28
- "codecov-cli>=11.2.3",
29
- "coverage[toml]>=7.10.7",
30
- "hypothesis>=6.140.3",
31
- "import-linter>=2.5.2",
32
- "bandit>=1.8.6",
33
- "pip-audit>=2.9.0",
34
- "pyright>=1.1.406",
35
- "pytest>=8.4.2",
36
- "pytest-asyncio>=1.2.0",
28
+ "codecov-cli>=11.2.6",
29
+ "coverage[toml]>=7.13.0",
30
+ "hypothesis>=6.148.7",
31
+ "import-linter>=2.7",
32
+ "bandit>=1.9.2",
33
+ "pip-audit>=2.10.0",
34
+ "pyright>=1.1.407",
35
+ "pytest>=9.0.2",
36
+ "pytest-asyncio>=1.3.0",
37
37
  "pytest-cov>=7.0.0",
38
- "ruff>=0.14.0",
39
- "textual>=6.3.0",
38
+ "ruff>=0.14.8",
39
+ "textual>=6.8.0",
40
40
  "twine>=6.2.0"
41
41
  ]
42
42
 
@@ -47,7 +47,7 @@ cli-exit-tools = "lib_cli_exit_tools.cli:main"
47
47
  lib-cli-exit-tools = "lib_cli_exit_tools.cli:main"
48
48
 
49
49
  [build-system]
50
- requires = ["hatchling>=1.27.0"]
50
+ requires = ["hatchling>=1.28.0"]
51
51
  build-backend = "hatchling.build"
52
52
 
53
53
  [tool.hatch.build.targets.wheel]
@@ -70,6 +70,7 @@ exclude = [
70
70
 
71
71
  [tool.pytest.ini_options]
72
72
  addopts = ["--doctest-modules"]
73
+ pythonpath = ["src"]
73
74
  doctest_optionflags = ["ELLIPSIS", "NORMALIZE_WHITESPACE"]
74
75
  markers = [
75
76
  "os_agnostic: test exercises behavior that is the same on every operating system",
@@ -91,6 +92,39 @@ omit = [
91
92
  fail_under = 85
92
93
  show_missing = true
93
94
 
95
+ [tool.clean]
96
+ # Patterns to remove when running `make clean` or `python -m scripts clean`
97
+ patterns = [
98
+ ".hypothesis",
99
+ ".import_linter_cache",
100
+ ".pytest_cache",
101
+ ".ruff_cache",
102
+ ".pyright",
103
+ ".mypy_cache",
104
+ ".tox",
105
+ ".nox",
106
+ ".eggs",
107
+ "*.egg-info",
108
+ "build",
109
+ "dist",
110
+ "htmlcov",
111
+ ".coverage",
112
+ "coverage.xml",
113
+ "codecov.sh",
114
+ ".cache",
115
+ "result",
116
+ ]
117
+
118
+ [tool.git]
119
+ # Default git remote for push/release commands
120
+ default-remote = "origin"
121
+
122
+
123
+ [tool.scripts.test]
124
+ # Configuration for scripts/test.py test runner
125
+ pytest-verbosity = "-vv"
126
+ coverage-report-file = "coverage.xml"
127
+ src-path = "src"
94
128
  [tool.importlinter]
95
129
  root_package = "lib_cli_exit_tools"
96
130
 
@@ -116,3 +150,9 @@ source_modules = [
116
150
  forbidden_modules = [
117
151
  "lib_cli_exit_tools.cli",
118
152
  ]
153
+
154
+ [tool.pip-audit]
155
+ # Known vulnerabilities to ignore (unfixable or accepted risk)
156
+ # GHSA-4xh5-x5gv-qwph: py library ReDoS (no fix available, low risk)
157
+ # PYSEC-2022-42969: same as above (alias)
158
+ ignore-vulns = ["GHSA-4xh5-x5gv-qwph", "PYSEC-2022-42969"]