lib-cli-exit-tools 2.4.0__tar.gz → 2.4.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 (57) hide show
  1. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.github/workflows/default_cicd_public.yml +42 -6
  2. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.gitignore +0 -1
  3. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/CHANGELOG.md +13 -0
  4. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/Makefile +2 -2
  5. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/PKG-INFO +35 -4
  6. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/README.md +30 -0
  7. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/pyproject.toml +9 -6
  8. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/__init__conf__.py +1 -1
  9. lib_cli_exit_tools-2.4.1/uv.lock +1968 -0
  10. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.codacy/cli-config.yaml +0 -0
  11. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.codacy/cli.sh +0 -0
  12. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.codacy/codacy.yaml +0 -0
  13. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.codacy/tools-configs/lizard.yaml +0 -0
  14. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.codacy/tools-configs/trivy.yaml +0 -0
  15. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.data_arch_violations.json +0 -0
  16. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.devcontainer/devcontainer.json +0 -0
  17. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.devcontainer/settings.json +0 -0
  18. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.env.example +0 -0
  19. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.github/actions/extract-metadata/action.yml +0 -0
  20. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.github/dependabot.yml +0 -0
  21. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.github/workflows/codeql.yml +0 -0
  22. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.github/workflows/default_release_public.yml +0 -0
  23. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.qlty/qlty.toml +0 -0
  24. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/.snyk +0 -0
  25. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/CONTRIBUTING.md +0 -0
  26. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/DEVELOPMENT.md +0 -0
  27. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/INSTALL.md +0 -0
  28. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/LICENSE +0 -0
  29. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/codecov.yml +0 -0
  30. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/docs/system-design/module_reference.md +0 -0
  31. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/notebooks/Quickstart.ipynb +0 -0
  32. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/__init__.py +0 -0
  33. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/__main__.py +0 -0
  34. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/adapters/__init__.py +0 -0
  35. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/adapters/signals.py +0 -0
  36. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/application/__init__.py +0 -0
  37. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/application/runner.py +0 -0
  38. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/cli/__init__.py +0 -0
  39. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/cli/commands.py +0 -0
  40. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/cli/group.py +0 -0
  41. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/cli/styling.py +0 -0
  42. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/cli/typed_click.py +0 -0
  43. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/core/__init__.py +0 -0
  44. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/core/configuration.py +0 -0
  45. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/core/exit_codes.py +0 -0
  46. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +0 -0
  47. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/src/lib_cli_exit_tools/py.typed +0 -0
  48. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/conftest.py +0 -0
  49. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_adapters_signals.py +0 -0
  50. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_application_runner.py +0 -0
  51. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_behaviors.py +0 -0
  52. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_cli.py +0 -0
  53. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_core_configuration.py +0 -0
  54. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_core_exit_codes.py +0 -0
  55. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_metadata.py +0 -0
  56. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_module_entry.py +0 -0
  57. {lib_cli_exit_tools-2.4.0 → lib_cli_exit_tools-2.4.1}/tests/test_signals_integration.py +0 -0
@@ -124,9 +124,36 @@ jobs:
124
124
  print("No CI system dependencies configured for macOS.")
125
125
 
126
126
  - name: Install dev deps
127
- shell: bash
127
+ shell: python
128
128
  run: |
129
- uv pip install -e .[dev] --system
129
+ import os, subprocess, tempfile
130
+ from pathlib import Path
131
+ try:
132
+ import tomllib
133
+ except ModuleNotFoundError:
134
+ import pip._vendor.tomli as tomllib
135
+
136
+ # Push and pull_request runs install exactly the tree uv.lock pins - versions
137
+ # plus file hashes, which uv verifies - so CI tests what the lock ships and no
138
+ # release published upstream since the last lock refresh can enter the build.
139
+ # The nightly schedule run resolves afresh instead (still inside the project's
140
+ # [tool.uv] exclude-newer cooldown, which uv honours here): it is the canary
141
+ # that reports upstream breakage before a lock refresh adopts it. A project
142
+ # without a uv.lock keeps the unlocked install.
143
+ with open("pyproject.toml", "rb") as f:
144
+ data = tomllib.load(f)
145
+ # Asking uv for an extra the project does not declare is a hard error.
146
+ extra = ["--extra", "dev"] if "dev" in data.get("project", {}).get("optional-dependencies", {}) else []
147
+ target = ["--system"] # setup-python's interpreter; the job runs no venv
148
+ locked = Path("uv.lock").is_file() and os.environ["GITHUB_EVENT_NAME"] != "schedule"
149
+ if locked:
150
+ req = Path(tempfile.mkdtemp()) / "locked-requirements.txt"
151
+ # --locked fails when pyproject.toml changed without a lock refresh.
152
+ subprocess.check_call(["uv", "export", "--locked", "--no-emit-project", *extra, "-o", str(req), "--quiet"])
153
+ subprocess.check_call(["uv", "pip", "install", *target, "-r", str(req)])
154
+ subprocess.check_call(["uv", "pip", "install", *target, "--no-deps", "-e", "."])
155
+ else:
156
+ subprocess.check_call(["uv", "pip", "install", *target, "-e", ".[dev]" if extra else "."])
130
157
 
131
158
  - name: Install CI system dependencies (Windows/choco)
132
159
  if: runner.os == 'Windows'
@@ -236,7 +263,7 @@ jobs:
236
263
  continue-on-error: true
237
264
  shell: python
238
265
  run: |
239
- import subprocess, sys, tempfile
266
+ import os, subprocess, sys, tempfile
240
267
  import rtoml
241
268
  from pathlib import Path
242
269
 
@@ -263,9 +290,18 @@ jobs:
263
290
 
264
291
  tmp = Path(tempfile.mkdtemp())
265
292
  req = tmp / "compiled-requirements.txt"
266
- subprocess.check_call(
267
- ["uv", "pip", "compile", *selector, "pyproject.toml", "-o", str(req), "--quiet"]
268
- )
293
+ # With a uv.lock the install step put exactly the locked tree on the
294
+ # runner, so audit that tree; the schedule canary and lock-less
295
+ # projects resolve pyproject.toml afresh, as their install did.
296
+ if Path("uv.lock").is_file() and os.environ["GITHUB_EVENT_NAME"] != "schedule":
297
+ subprocess.check_call(
298
+ ["uv", "export", "--locked", "--no-emit-project", "--no-hashes", *selector,
299
+ "-o", str(req), "--quiet"]
300
+ )
301
+ else:
302
+ subprocess.check_call(
303
+ ["uv", "pip", "compile", *selector, "pyproject.toml", "-o", str(req), "--quiet"]
304
+ )
269
305
 
270
306
  # Drop direct URL references ("pkg @ git+https://...") before auditing.
271
307
  # pip-audit cannot audit those (they are not on PyPI) but, given a
@@ -181,7 +181,6 @@ result
181
181
  # Optional lockfiles (for alternative managers)
182
182
  poetry.lock
183
183
  pdm.lock
184
- uv.lock
185
184
  /.github_bak/
186
185
  prompts.md
187
186
  CLAUDE.md
@@ -4,6 +4,19 @@ All notable changes to this project are documented here. The format follows [Kee
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.4.1] 2026-10-12 22:22:57
8
+
9
+ ### Added
10
+ - Python 3.15 is a supported version: declared in the classifiers, so CI and `make test-all` run it.
11
+ - `uv.lock` is committed, and `[tool.uv] exclude-newer` sets a cooldown that keeps releases younger
12
+ than it out of the lock. CI installs exactly the locked tree on push and pull request; the nightly
13
+ scheduled run still resolves afresh to catch upstream breakage early.
14
+
15
+ ### Changed
16
+ - The install section explains why installing with uv protects against supply-chain attacks and why
17
+ a plain `pip install` from PyPI does not.
18
+ - `rtoml` floor raised to 0.14.0 (dev extra), the first release with Python 3.15 wheels.
19
+
7
20
  ## [2.4.0] 2026-10-05 20:48:53
8
21
 
9
22
  ### Fixed
@@ -1,4 +1,4 @@
1
- # BMK MAKEFILE 3.18.0
1
+ # BMK MAKEFILE 3.21.0
2
2
  # do not alter this file - it might be overwritten on new versions of BMK
3
3
  # if You want to alter it, remove the first line # BMK MAKEFILE 1.0 - then it is a custom makefile and will not be overwritten
4
4
  # bmk Makefile - thin wrapper using `uv tool upgrade` for persistent bmk
@@ -186,7 +186,7 @@ endif
186
186
  # BMK_MIN floors the FALLBACK install. The upgrade path does not consult it: uv re-resolves
187
187
  # the requirement recorded at install time, which is itself a `bmk>=...`, so it always lands
188
188
  # on the newest release and clears the floor anyway.
189
- BMK_MIN := 3.18.0
189
+ BMK_MIN := 3.21.0
190
190
 
191
191
  # Absent env, missing check, or damaged env - all three mean "do not upgrade, rebuild".
192
192
  # `test -x` keeps a fresh machine quiet: there is no interpreter to run yet.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: lib_cli_exit_tools
3
- Version: 2.4.0
3
+ Version: 2.4.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
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Programming Language :: Python :: 3.15
22
23
  Classifier: Typing :: Typed
23
24
  Requires-Python: >=3.10
24
25
  Requires-Dist: rich-click>=1.9.9
@@ -27,15 +28,15 @@ Requires-Dist: bandit>=1.9.4; extra == 'dev'
27
28
  Requires-Dist: build>=1.6.1; extra == 'dev'
28
29
  Requires-Dist: click>=8.5.0; extra == 'dev'
29
30
  Requires-Dist: coverage[toml]>=7.16.2; extra == 'dev'
30
- Requires-Dist: hypothesis>=6.168.4; extra == 'dev'
31
+ Requires-Dist: hypothesis>=6.168.5; extra == 'dev'
31
32
  Requires-Dist: import-linter>=2.15; extra == 'dev'
32
33
  Requires-Dist: pip-audit>=2.10.1; extra == 'dev'
33
34
  Requires-Dist: pyright[nodejs]>=1.1.414; extra == 'dev'
34
35
  Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
35
36
  Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
36
37
  Requires-Dist: pytest>=9.1.1; extra == 'dev'
37
- Requires-Dist: rtoml>=0.13.0; extra == 'dev'
38
- Requires-Dist: ruff>=0.16.10; extra == 'dev'
38
+ Requires-Dist: rtoml>=0.14.0; extra == 'dev'
39
+ Requires-Dist: ruff>=0.17.0; extra == 'dev'
39
40
  Requires-Dist: textual>=8.2.8; extra == 'dev'
40
41
  Requires-Dist: twine>=7.0.0; extra == 'dev'
41
42
  Description-Content-Type: text/markdown
@@ -83,6 +84,36 @@ pip install lib_cli_exit_tools
83
84
 
84
85
  See [INSTALL.md](INSTALL.md) for editable installs, pipx/uv usage, and troubleshooting tips.
85
86
 
87
+ ### Why we recommend uv: supply-chain protection
88
+
89
+ This repository commits a `uv.lock`. It pins every package the project needs, transitive
90
+ dependencies included, to an exact version and to the hashes of that version's files. The
91
+ `exclude-newer` setting under `[tool.uv]` in `pyproject.toml` adds a cooldown: uv leaves any
92
+ release younger than that out of the lock. CI installs from the lock, so a hijacked release that
93
+ gets pulled again within the cooldown never reaches our builds, and a file whose hash does not
94
+ match is refused.
95
+
96
+ That protection stays in this repository. The installable package declares only lower bounds
97
+ (`>=`) for its dependencies, so a plain `pip install` takes the newest release of every transitive
98
+ dependency at the moment you run it. If one of them was hijacked an hour earlier, you get the
99
+ hijacked version. `pipx install` and `uv tool install` without options do the same.
100
+
101
+ To install the command line tool with a cooldown of your own (uv then skips any release younger
102
+ than 7 days, transitive ones included), or to run the exact tree our CI tests:
103
+
104
+ ```bash
105
+ uv tool install --exclude-newer "7 days" lib_cli_exit_tools
106
+ git clone https://github.com/bitranox/lib_cli_exit_tools.git && cd lib_cli_exit_tools && uv sync --locked && uv run lib_cli_exit_tools --help
107
+ ```
108
+
109
+ If you depend on lib_cli_exit_tools in your own project, give that project the same cooldown (7 days here, as
110
+ an example) and commit the `uv.lock` that `uv add lib_cli_exit_tools` writes:
111
+
112
+ ```toml
113
+ [tool.uv]
114
+ exclude-newer = "7 days"
115
+ ```
116
+
86
117
  ## Usage
87
118
 
88
119
  Console script (all commands map to ``lib_cli_exit_tools.cli:main``):
@@ -41,6 +41,36 @@ pip install lib_cli_exit_tools
41
41
 
42
42
  See [INSTALL.md](INSTALL.md) for editable installs, pipx/uv usage, and troubleshooting tips.
43
43
 
44
+ ### Why we recommend uv: supply-chain protection
45
+
46
+ This repository commits a `uv.lock`. It pins every package the project needs, transitive
47
+ dependencies included, to an exact version and to the hashes of that version's files. The
48
+ `exclude-newer` setting under `[tool.uv]` in `pyproject.toml` adds a cooldown: uv leaves any
49
+ release younger than that out of the lock. CI installs from the lock, so a hijacked release that
50
+ gets pulled again within the cooldown never reaches our builds, and a file whose hash does not
51
+ match is refused.
52
+
53
+ That protection stays in this repository. The installable package declares only lower bounds
54
+ (`>=`) for its dependencies, so a plain `pip install` takes the newest release of every transitive
55
+ dependency at the moment you run it. If one of them was hijacked an hour earlier, you get the
56
+ hijacked version. `pipx install` and `uv tool install` without options do the same.
57
+
58
+ To install the command line tool with a cooldown of your own (uv then skips any release younger
59
+ than 7 days, transitive ones included), or to run the exact tree our CI tests:
60
+
61
+ ```bash
62
+ uv tool install --exclude-newer "7 days" lib_cli_exit_tools
63
+ git clone https://github.com/bitranox/lib_cli_exit_tools.git && cd lib_cli_exit_tools && uv sync --locked && uv run lib_cli_exit_tools --help
64
+ ```
65
+
66
+ If you depend on lib_cli_exit_tools in your own project, give that project the same cooldown (7 days here, as
67
+ an example) and commit the `uv.lock` that `uv add lib_cli_exit_tools` writes:
68
+
69
+ ```toml
70
+ [tool.uv]
71
+ exclude-newer = "7 days"
72
+ ```
73
+
44
74
  ## Usage
45
75
 
46
76
  Console script (all commands map to ``lib_cli_exit_tools.cli:main``):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lib_cli_exit_tools"
3
- version = "2.4.0"
3
+ version = "2.4.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.10"
@@ -20,6 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.12",
21
21
  "Programming Language :: Python :: 3.13",
22
22
  "Programming Language :: Python :: 3.14",
23
+ "Programming Language :: Python :: 3.15",
23
24
  ]
24
25
 
25
26
  # System packages required for CI runners (read by GitHub Actions workflow template)
@@ -38,8 +39,6 @@ Issues = "https://github.com/bitranox/lib_cli_exit_tools/issues"
38
39
 
39
40
  [project.optional-dependencies]
40
41
  dev = [
41
- # 1.5.1 was yanked upstream (unintended breaking changes), so 1.5.0 is the newest usable
42
- # release; a >=1.5.1 floor has ZERO candidates and makes this extra unresolvable.
43
42
  "build>=1.6.1",
44
43
  # codecov-cli is disabled, not dropped: it requires click<8.3.0, which drags click back to
45
44
  # 8.2.1 - the version with CVE-2026-7246 (command injection in click.edit(), fixed in 8.3.3).
@@ -51,7 +50,7 @@ dev = [
51
50
  # Transitive CVE pins
52
51
  "click>=8.5.0", # CVE-2026-7246
53
52
  "coverage[toml]>=7.16.2",
54
- "hypothesis>=6.168.4",
53
+ "hypothesis>=6.168.5",
55
54
  "import-linter>=2.15",
56
55
  "bandit>=1.9.4",
57
56
  "pip-audit>=2.10.1",
@@ -59,9 +58,9 @@ dev = [
59
58
  "pytest>=9.1.1",
60
59
  "pytest-asyncio>=1.4.0",
61
60
  "pytest-cov>=7.1.0",
62
- "ruff>=0.16.10",
61
+ "ruff>=0.17.0",
63
62
  "textual>=8.2.8",
64
- "rtoml>=0.13.0",
63
+ "rtoml>=0.14.0",
65
64
  "twine>=7.0.0"
66
65
  ]
67
66
 
@@ -244,3 +243,7 @@ ignore-vulns = [
244
243
  "GHSA-mj87-hwqh-73pj", # alias of CVE-2026-40347
245
244
  "GHSA-pjjw-68hj-v9mw", # uv <0.11.6 wheel RECORD path traversal on uninstall, dev tooling
246
245
  ]
246
+
247
+ [tool.uv]
248
+ exclude-newer = "1 day"
249
+ exclude-newer-package = {rtoml = "2026-10-12T00:17:16Z"}
@@ -26,7 +26,7 @@ name = "lib_cli_exit_tools"
26
26
  #: Human-readable summary shown in CLI help output.
27
27
  title = "CLI exit handling helpers: clean signals, exit codes, and error printing"
28
28
  #: Current release version pulled from ``pyproject.toml`` by automation.
29
- version = "2.4.0"
29
+ version = "2.4.1"
30
30
  #: Repository homepage presented to users.
31
31
  homepage = "https://github.com/bitranox/lib_cli_exit_tools"
32
32
  #: Author attribution surfaced in CLI output.