lib-cli-exit-tools 2.2.2__tar.gz → 2.2.4__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-2.2.2/.github/workflows/ci.yml → lib_cli_exit_tools-2.2.4/.github/workflows/ci.yml_backup +2 -2
- lib_cli_exit_tools-2.2.4/.github/workflows/default_cicd_public.yml +303 -0
- lib_cli_exit_tools-2.2.4/.github/workflows/default_release_public.yml +69 -0
- lib_cli_exit_tools-2.2.2/.github/workflows/release.yml → lib_cli_exit_tools-2.2.4/.github/workflows/release.yml_backup +1 -1
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/CHANGELOG.md +23 -0
- lib_cli_exit_tools-2.2.4/CLAUDE.md +164 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/INSTALL.md +3 -2
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/PKG-INFO +49 -42
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/README.md +40 -33
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/docs/system-design/module_reference.md +2 -2
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/pyproject.toml +24 -10
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/__init__conf__.py +1 -1
- lib_cli_exit_tools-2.2.2/AGENTS.md +0 -208
- lib_cli_exit_tools-2.2.2/AGENTS_README.md +0 -176
- lib_cli_exit_tools-2.2.2/tests/test_scripts.py +0 -233
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.codacy/cli-config.yaml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.codacy/cli.sh +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.codacy/codacy.yaml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.codacy/tools-configs/lizard.yaml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.codacy/tools-configs/trivy.yaml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.devcontainer/devcontainer.json +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.devcontainer/settings.json +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.env.example +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.github/dependabot.yml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.github/workflows/codeql.yml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.gitignore +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.qlty/qlty.toml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/.snyk +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/CONTRIBUTING.md +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/DEVELOPMENT.md +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/LICENSE +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/Makefile +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/codecov.yml +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/notebooks/Quickstart.ipynb +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/__init__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/__main__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/_utils.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/build.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/bump.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/bump_major.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/bump_minor.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/bump_patch.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/bump_version.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/clean.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/cli.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/dependencies.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/dev.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/help.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/install.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/menu.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/push.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/release.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/run_cli.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/target_metadata.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/test.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/toml_config.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/scripts/version_current.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/__init__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/__main__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/adapters/__init__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/adapters/signals.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/application/__init__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/application/runner.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/cli.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/core/__init__.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/core/configuration.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/core/exit_codes.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/src/lib_cli_exit_tools/py.typed +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/conftest.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_adapters_signals.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_application_runner.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_behaviors.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_cli.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_core_configuration.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_core_exit_codes.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_metadata.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_module_entry.py +0 -0
- {lib_cli_exit_tools-2.2.2 → lib_cli_exit_tools-2.2.4}/tests/test_signals_integration.py +0 -0
|
@@ -83,14 +83,14 @@ jobs:
|
|
|
83
83
|
run: |
|
|
84
84
|
uv pip install pywin32 --system
|
|
85
85
|
- name: Cache ruff
|
|
86
|
-
uses: actions/cache@
|
|
86
|
+
uses: actions/cache@v5
|
|
87
87
|
with:
|
|
88
88
|
path: .ruff_cache
|
|
89
89
|
key: ruff-${{ runner.os }}-${{ github.sha }}
|
|
90
90
|
restore-keys: |
|
|
91
91
|
ruff-${{ runner.os }}-
|
|
92
92
|
- name: Cache pyright
|
|
93
|
-
uses: actions/cache@
|
|
93
|
+
uses: actions/cache@v5
|
|
94
94
|
with:
|
|
95
95
|
path: .pyright
|
|
96
96
|
key: pyright-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ]
|
|
6
|
+
pull_request:
|
|
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 * * *'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Tests (Python ${{ matrix.python }}, ${{ matrix.os }})
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
20
|
+
# Test against all supported Python versions (3.10+)
|
|
21
|
+
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
22
|
+
env:
|
|
23
|
+
PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"
|
|
24
|
+
PYTHONIOENCODING: "utf-8"
|
|
25
|
+
UV_LINK_MODE: "copy"
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
- uses: actions/setup-python@v6
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python }}
|
|
31
|
+
- name: Install uv
|
|
32
|
+
uses: astral-sh/setup-uv@v7
|
|
33
|
+
with:
|
|
34
|
+
enable-cache: true
|
|
35
|
+
prune-cache: false
|
|
36
|
+
|
|
37
|
+
- name: Install tomli (Python < 3.11)
|
|
38
|
+
shell: bash
|
|
39
|
+
run: python -c "import tomllib" 2>/dev/null || uv pip install tomli --system
|
|
40
|
+
|
|
41
|
+
- name: Extract project metadata
|
|
42
|
+
shell: python
|
|
43
|
+
run: |
|
|
44
|
+
import os
|
|
45
|
+
try:
|
|
46
|
+
import tomllib
|
|
47
|
+
except ModuleNotFoundError:
|
|
48
|
+
import tomli as tomllib
|
|
49
|
+
|
|
50
|
+
with open('pyproject.toml', 'rb') as f:
|
|
51
|
+
data = tomllib.load(f)
|
|
52
|
+
project = data['project']['name']
|
|
53
|
+
module = project.replace('-', '_')
|
|
54
|
+
dash = project.replace('_', '-')
|
|
55
|
+
scripts = list(data['project'].get('scripts', {}).keys())
|
|
56
|
+
cli_bin = scripts[0] if scripts else dash
|
|
57
|
+
|
|
58
|
+
with open(os.environ['GITHUB_ENV'], 'a', encoding='utf-8') as env:
|
|
59
|
+
env.write(f"PROJECT_NAME={project}\n")
|
|
60
|
+
env.write(f"PACKAGE_MODULE={module}\n")
|
|
61
|
+
env.write(f"CLI_BIN={cli_bin}\n")
|
|
62
|
+
|
|
63
|
+
- name: Install journald prerequisites
|
|
64
|
+
if: runner.os == 'Linux'
|
|
65
|
+
shell: bash
|
|
66
|
+
run: |
|
|
67
|
+
sudo apt-get update
|
|
68
|
+
sudo apt-get install -y python3-systemd
|
|
69
|
+
|
|
70
|
+
- name: Install dev deps
|
|
71
|
+
shell: bash
|
|
72
|
+
run: |
|
|
73
|
+
uv pip install -e .[dev] --system
|
|
74
|
+
|
|
75
|
+
- name: Install Windows Event Log prerequisites
|
|
76
|
+
if: runner.os == 'Windows'
|
|
77
|
+
shell: bash
|
|
78
|
+
run: |
|
|
79
|
+
uv pip install pywin32 --system
|
|
80
|
+
|
|
81
|
+
- name: Restore ruff cache
|
|
82
|
+
id: ruff-cache
|
|
83
|
+
uses: actions/cache/restore@v5
|
|
84
|
+
with:
|
|
85
|
+
path: .ruff_cache
|
|
86
|
+
key: ruff-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
|
|
87
|
+
restore-keys: |
|
|
88
|
+
ruff-${{ runner.os }}-py${{ matrix.python }}-
|
|
89
|
+
ruff-${{ runner.os }}-
|
|
90
|
+
|
|
91
|
+
- name: Run ruff (lint + format)
|
|
92
|
+
id: ruff
|
|
93
|
+
continue-on-error: true
|
|
94
|
+
shell: bash
|
|
95
|
+
run: |
|
|
96
|
+
ruff check src tests notebooks
|
|
97
|
+
ruff format --check src tests notebooks
|
|
98
|
+
|
|
99
|
+
- name: Run pyright (type check)
|
|
100
|
+
id: pyright
|
|
101
|
+
continue-on-error: true
|
|
102
|
+
shell: bash
|
|
103
|
+
run: pyright
|
|
104
|
+
|
|
105
|
+
- name: Run pytest (tests + coverage)
|
|
106
|
+
id: pytest
|
|
107
|
+
continue-on-error: true
|
|
108
|
+
shell: bash
|
|
109
|
+
env:
|
|
110
|
+
TEST_VERBOSE: "1"
|
|
111
|
+
run: pytest --cov=src --cov-report=term-missing --cov-report=xml
|
|
112
|
+
|
|
113
|
+
- name: Run import-linter (architecture)
|
|
114
|
+
id: importlinter
|
|
115
|
+
continue-on-error: true
|
|
116
|
+
shell: bash
|
|
117
|
+
run: lint-imports
|
|
118
|
+
|
|
119
|
+
- name: Run bandit (security scan)
|
|
120
|
+
id: bandit
|
|
121
|
+
continue-on-error: true
|
|
122
|
+
shell: bash
|
|
123
|
+
run: bandit -q -r src/${{ env.PACKAGE_MODULE }}
|
|
124
|
+
|
|
125
|
+
- name: Run pip-audit (vulnerability scan)
|
|
126
|
+
id: pipaudit
|
|
127
|
+
continue-on-error: true
|
|
128
|
+
shell: python
|
|
129
|
+
run: |
|
|
130
|
+
import subprocess, sys
|
|
131
|
+
try:
|
|
132
|
+
import tomllib
|
|
133
|
+
except ModuleNotFoundError:
|
|
134
|
+
import tomli as tomllib
|
|
135
|
+
with open("pyproject.toml", "rb") as f:
|
|
136
|
+
data = tomllib.load(f)
|
|
137
|
+
vulns = data.get("tool", {}).get("pip-audit", {}).get("ignore-vulns", [])
|
|
138
|
+
cmd = ["pip-audit", "--skip-editable"]
|
|
139
|
+
for v in vulns:
|
|
140
|
+
cmd.extend(["--ignore-vuln", v])
|
|
141
|
+
sys.exit(subprocess.call(cmd))
|
|
142
|
+
|
|
143
|
+
- name: Check all steps passed
|
|
144
|
+
shell: bash
|
|
145
|
+
run: |
|
|
146
|
+
if [[ "${{ steps.ruff.outcome }}" != "success" ]]; then
|
|
147
|
+
echo "::error::Ruff check failed"
|
|
148
|
+
exit 1
|
|
149
|
+
fi
|
|
150
|
+
if [[ "${{ steps.pyright.outcome }}" != "success" ]]; then
|
|
151
|
+
echo "::error::Pyright check failed"
|
|
152
|
+
exit 1
|
|
153
|
+
fi
|
|
154
|
+
if [[ "${{ steps.pytest.outcome }}" != "success" ]]; then
|
|
155
|
+
echo "::error::Pytest failed"
|
|
156
|
+
exit 1
|
|
157
|
+
fi
|
|
158
|
+
if [[ "${{ steps.importlinter.outcome }}" != "success" ]]; then
|
|
159
|
+
echo "::error::Import-linter check failed"
|
|
160
|
+
exit 1
|
|
161
|
+
fi
|
|
162
|
+
if [[ "${{ steps.bandit.outcome }}" != "success" ]]; then
|
|
163
|
+
echo "::error::Bandit security scan failed"
|
|
164
|
+
exit 1
|
|
165
|
+
fi
|
|
166
|
+
if [[ "${{ steps.pipaudit.outcome }}" != "success" ]]; then
|
|
167
|
+
echo "::error::pip-audit vulnerability scan failed"
|
|
168
|
+
exit 1
|
|
169
|
+
fi
|
|
170
|
+
echo "All checks passed!"
|
|
171
|
+
|
|
172
|
+
- name: Build wheel/sdist
|
|
173
|
+
shell: bash
|
|
174
|
+
run: uv build
|
|
175
|
+
|
|
176
|
+
- name: Verify wheel install in clean env
|
|
177
|
+
shell: bash
|
|
178
|
+
run: |
|
|
179
|
+
uv venv .venv_wheel
|
|
180
|
+
. .venv_wheel/bin/activate 2>/dev/null || . .venv_wheel/Scripts/activate 2>/dev/null
|
|
181
|
+
uv pip install dist/*.whl
|
|
182
|
+
"$CLI_BIN" --version 2>/dev/null || python -m "$PACKAGE_MODULE" --version
|
|
183
|
+
|
|
184
|
+
- name: Prune uv cache
|
|
185
|
+
continue-on-error: true
|
|
186
|
+
shell: bash
|
|
187
|
+
run: uv cache prune --ci
|
|
188
|
+
|
|
189
|
+
- name: Save ruff cache
|
|
190
|
+
if: always() && steps.ruff-cache.outputs.cache-hit != 'true'
|
|
191
|
+
uses: actions/cache/save@v5
|
|
192
|
+
with:
|
|
193
|
+
path: .ruff_cache
|
|
194
|
+
key: ruff-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
|
|
195
|
+
|
|
196
|
+
pipx-uv:
|
|
197
|
+
name: pipx/uv verification (ubuntu)
|
|
198
|
+
runs-on: ubuntu-latest
|
|
199
|
+
steps:
|
|
200
|
+
- uses: actions/checkout@v6
|
|
201
|
+
- uses: actions/setup-python@v6
|
|
202
|
+
with:
|
|
203
|
+
python-version: "3.14"
|
|
204
|
+
|
|
205
|
+
- name: Install uv
|
|
206
|
+
uses: astral-sh/setup-uv@v7
|
|
207
|
+
with:
|
|
208
|
+
enable-cache: true
|
|
209
|
+
prune-cache: false
|
|
210
|
+
|
|
211
|
+
- name: Install tomli (Python < 3.11)
|
|
212
|
+
shell: bash
|
|
213
|
+
run: python -c "import tomllib" 2>/dev/null || uv pip install tomli --system
|
|
214
|
+
|
|
215
|
+
- name: Extract project metadata
|
|
216
|
+
shell: python
|
|
217
|
+
run: |
|
|
218
|
+
import os
|
|
219
|
+
try:
|
|
220
|
+
import tomllib
|
|
221
|
+
except ModuleNotFoundError:
|
|
222
|
+
import tomli as tomllib
|
|
223
|
+
|
|
224
|
+
with open('pyproject.toml', 'rb') as f:
|
|
225
|
+
data = tomllib.load(f)
|
|
226
|
+
project = data['project']['name']
|
|
227
|
+
module = project.replace('-', '_')
|
|
228
|
+
dash = project.replace('_', '-')
|
|
229
|
+
scripts = list(data['project'].get('scripts', {}).keys())
|
|
230
|
+
cli_bin = scripts[0] if scripts else dash
|
|
231
|
+
|
|
232
|
+
with open(os.environ['GITHUB_ENV'], 'a', encoding='utf-8') as env:
|
|
233
|
+
env.write(f"PROJECT_NAME={project}\n")
|
|
234
|
+
env.write(f"PACKAGE_MODULE={module}\n")
|
|
235
|
+
env.write(f"CLI_BIN={cli_bin}\n")
|
|
236
|
+
|
|
237
|
+
- name: Build wheel
|
|
238
|
+
run: uv build
|
|
239
|
+
- name: pipx install from wheel
|
|
240
|
+
run: |
|
|
241
|
+
uv pip install --system pipx
|
|
242
|
+
pipx ensurepath
|
|
243
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
244
|
+
pipx install dist/*.whl
|
|
245
|
+
"$CLI_BIN" --version
|
|
246
|
+
|
|
247
|
+
- name: uv tool install
|
|
248
|
+
run: |
|
|
249
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
250
|
+
uv tool install --force .
|
|
251
|
+
"$CLI_BIN" --version
|
|
252
|
+
|
|
253
|
+
- name: Prune uv cache
|
|
254
|
+
continue-on-error: true
|
|
255
|
+
run: uv cache prune --ci
|
|
256
|
+
|
|
257
|
+
notebooks:
|
|
258
|
+
name: Execute notebooks (ubuntu, Python 3.14)
|
|
259
|
+
runs-on: ubuntu-latest
|
|
260
|
+
steps:
|
|
261
|
+
- uses: actions/checkout@v6
|
|
262
|
+
- uses: actions/setup-python@v6
|
|
263
|
+
with:
|
|
264
|
+
python-version: "3.14"
|
|
265
|
+
|
|
266
|
+
- name: Install uv
|
|
267
|
+
uses: astral-sh/setup-uv@v7
|
|
268
|
+
with:
|
|
269
|
+
enable-cache: true
|
|
270
|
+
prune-cache: false
|
|
271
|
+
|
|
272
|
+
- name: Install notebook runner deps
|
|
273
|
+
run: |
|
|
274
|
+
uv pip install --system nbclient nbformat ipykernel jupyter_client
|
|
275
|
+
python -m ipykernel install --user --name python3 --display-name "Python 3"
|
|
276
|
+
- name: Execute Quickstart notebook
|
|
277
|
+
env:
|
|
278
|
+
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
|
279
|
+
PIP_NO_INPUT: "1"
|
|
280
|
+
run: |
|
|
281
|
+
python - << 'PY'
|
|
282
|
+
from pathlib import Path
|
|
283
|
+
|
|
284
|
+
import nbformat
|
|
285
|
+
from nbclient import NotebookClient
|
|
286
|
+
|
|
287
|
+
nb_path = Path('notebooks/Quickstart.ipynb')
|
|
288
|
+
if not nb_path.exists():
|
|
289
|
+
raise SystemExit(f"Notebook not found: {nb_path}")
|
|
290
|
+
|
|
291
|
+
notebook = nbformat.read(nb_path, as_version=4)
|
|
292
|
+
client = NotebookClient(
|
|
293
|
+
notebook,
|
|
294
|
+
timeout=900,
|
|
295
|
+
kernel_name='python3',
|
|
296
|
+
allow_errors=False,
|
|
297
|
+
)
|
|
298
|
+
client.execute()
|
|
299
|
+
|
|
300
|
+
out_path = Path('notebooks/Quickstart-executed.ipynb')
|
|
301
|
+
nbformat.write(notebook, out_path)
|
|
302
|
+
print(f"Executed notebook written to: {out_path}")
|
|
303
|
+
PY
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- 'v*'
|
|
9
|
+
workflow_dispatch: {}
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
env:
|
|
17
|
+
UV_LINK_MODE: "copy"
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
|
+
- uses: actions/setup-python@v6
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.14'
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v7
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
prune-cache: false
|
|
29
|
+
|
|
30
|
+
- name: Build artifacts
|
|
31
|
+
run: uv build
|
|
32
|
+
|
|
33
|
+
- name: Upload artifacts
|
|
34
|
+
uses: actions/upload-artifact@v6
|
|
35
|
+
with:
|
|
36
|
+
name: dist
|
|
37
|
+
path: dist/*
|
|
38
|
+
|
|
39
|
+
- name: Prune uv cache
|
|
40
|
+
continue-on-error: true
|
|
41
|
+
run: uv cache prune --ci
|
|
42
|
+
|
|
43
|
+
publish:
|
|
44
|
+
needs: build
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
environment: pypi
|
|
47
|
+
permissions:
|
|
48
|
+
contents: read
|
|
49
|
+
steps:
|
|
50
|
+
- name: Verify PyPI token is set
|
|
51
|
+
run: |
|
|
52
|
+
if [ -z "${{ secrets.PYPI_API_TOKEN }}" ]; then
|
|
53
|
+
echo "::error title=Missing PyPI token::Set the PYPI_API_TOKEN secret in GitHub repository settings to enable PyPI publishing on releases."
|
|
54
|
+
echo "See: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
- name: Download artifacts
|
|
59
|
+
uses: actions/download-artifact@v6
|
|
60
|
+
with:
|
|
61
|
+
name: dist
|
|
62
|
+
path: dist/
|
|
63
|
+
|
|
64
|
+
- name: Publish to PyPI
|
|
65
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
66
|
+
with:
|
|
67
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
68
|
+
attestations: false
|
|
69
|
+
skip-existing: true
|
|
@@ -3,6 +3,29 @@
|
|
|
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.2.4] - 2026-01-26
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Updated dependencies.
|
|
10
|
+
- Excluded `scripts/` from pyright, pytest, and CI/CD test collection.
|
|
11
|
+
|
|
12
|
+
## [2.2.3] - 2025-12-17
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- Corrected README examples to use `rich_click` instead of plain `click` for consistency with library internals.
|
|
16
|
+
- Fixed Example 2 (cli_session) to avoid nested `run_cli` calls.
|
|
17
|
+
- Fixed Example 3 (multi-command CLI) so `--traceback` flag actually controls traceback display.
|
|
18
|
+
- Added missing blank line in Example 4 (custom signal handlers).
|
|
19
|
+
- Updated `print_exception_message` API reference signature to show `trace_back=None` default.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Updated CLAUDE.md with correct `docs/system-design/` path and added missing `python_data_architecture_enforcement.md` guideline.
|
|
23
|
+
- Removed irrelevant Documentation & Translations section from CLAUDE.md.
|
|
24
|
+
- Updated INSTALL.md to list all three console script entry points consistently.
|
|
25
|
+
|
|
26
|
+
### Security
|
|
27
|
+
- Added filelock CVE-2025-68146 to pip-audit ignore list (transitive dev dependency, fix pending upstream).
|
|
28
|
+
|
|
6
29
|
## [2.2.2] - 2025-12-12
|
|
7
30
|
|
|
8
31
|
### Changed
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Claude Code Guidelines for lib_cli_exit_tools
|
|
2
|
+
|
|
3
|
+
## Session Initialization
|
|
4
|
+
|
|
5
|
+
When starting a new session, read and apply the following system prompt files from `/media/srv-main-softdev/projects/softwarestack/systemprompts`:
|
|
6
|
+
|
|
7
|
+
### Core Guidelines (Always Apply)
|
|
8
|
+
- `core_programming_solid.md`
|
|
9
|
+
|
|
10
|
+
### Bash-Specific Guidelines
|
|
11
|
+
When working with Bash scripts:
|
|
12
|
+
- `core_programming_solid.md`
|
|
13
|
+
- `bash_clean_architecture.md`
|
|
14
|
+
- `bash_clean_code.md`
|
|
15
|
+
- `bash_small_functions.md`
|
|
16
|
+
|
|
17
|
+
### Python-Specific Guidelines
|
|
18
|
+
When working with Python code:
|
|
19
|
+
- `core_programming_solid.md`
|
|
20
|
+
- `python_solid_architecture_enforcer.md`
|
|
21
|
+
- `python_clean_architecture.md`
|
|
22
|
+
- `python_clean_code.md`
|
|
23
|
+
- `python_small_functions_style.md`
|
|
24
|
+
- `python_libraries_to_use.md`
|
|
25
|
+
- `python_data_architecture_enforcement.md`
|
|
26
|
+
|
|
27
|
+
### Additional Guidelines
|
|
28
|
+
- `self_documenting.md`
|
|
29
|
+
- `self_documenting_template.md`
|
|
30
|
+
- `python_jupyter_notebooks.md`
|
|
31
|
+
- `python_testing.md`
|
|
32
|
+
|
|
33
|
+
## Project Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
lib_cli_exit_tools/
|
|
37
|
+
├── .github/
|
|
38
|
+
│ └── workflows/ # GitHub Actions CI/CD workflows
|
|
39
|
+
├── .devcontainer/ # Dev container configuration
|
|
40
|
+
├── docs/ # Project documentation
|
|
41
|
+
│ └── system-design/ # System design documents
|
|
42
|
+
├── notebooks/ # Jupyter notebooks for experiments
|
|
43
|
+
├── scripts/ # Build and automation scripts
|
|
44
|
+
│ ├── __init__.py # Package marker
|
|
45
|
+
│ ├── __main__.py # Module entry point
|
|
46
|
+
│ ├── _utils.py # Shared utilities
|
|
47
|
+
│ ├── build.py # Build wheel/sdist
|
|
48
|
+
│ ├── bump.py # Version bump (generic)
|
|
49
|
+
│ ├── bump_major.py # Bump major version
|
|
50
|
+
│ ├── bump_minor.py # Bump minor version
|
|
51
|
+
│ ├── bump_patch.py # Bump patch version
|
|
52
|
+
│ ├── bump_version.py # Version bump utilities
|
|
53
|
+
│ ├── clean.py # Clean build artifacts
|
|
54
|
+
│ ├── cli.py # CLI for scripts
|
|
55
|
+
│ ├── dependencies.py # Dependency management
|
|
56
|
+
│ ├── dev.py # Development install
|
|
57
|
+
│ ├── help.py # Show help
|
|
58
|
+
│ ├── install.py # Install package
|
|
59
|
+
│ ├── menu.py # Interactive TUI menu
|
|
60
|
+
│ ├── push.py # Git push
|
|
61
|
+
│ ├── release.py # Create releases
|
|
62
|
+
│ ├── run_cli.py # Run CLI
|
|
63
|
+
│ ├── target_metadata.py # Metadata generation
|
|
64
|
+
│ ├── test.py # Run tests with coverage
|
|
65
|
+
│ ├── toml_config.py # TOML configuration utilities
|
|
66
|
+
│ └── version_current.py # Print current version
|
|
67
|
+
├── src/
|
|
68
|
+
│ └── lib_cli_exit_tools/ # Main Python package
|
|
69
|
+
│ ├── __init__.py # Package initialization
|
|
70
|
+
│ ├── __init__conf__.py # Configuration constants
|
|
71
|
+
│ ├── __main__.py # CLI entry point
|
|
72
|
+
│ ├── cli.py # CLI implementation
|
|
73
|
+
│ ├── lib_cli_exit_tools.py # Core library functions
|
|
74
|
+
│ ├── py.typed # PEP 561 marker
|
|
75
|
+
│ ├── adapters/ # Adapter layer
|
|
76
|
+
│ │ └── signals.py # Signal handling adapters
|
|
77
|
+
│ ├── application/ # Application layer
|
|
78
|
+
│ │ └── runner.py # Application runner
|
|
79
|
+
│ └── core/ # Core domain layer
|
|
80
|
+
│ ├── configuration.py # Configuration management
|
|
81
|
+
│ └── exit_codes.py # Exit code definitions
|
|
82
|
+
├── tests/ # Test suite
|
|
83
|
+
├── .env.example # Example environment variables
|
|
84
|
+
├── CLAUDE.md # Claude Code guidelines (this file)
|
|
85
|
+
├── CHANGELOG.md # Version history
|
|
86
|
+
├── CONTRIBUTING.md # Contribution guidelines
|
|
87
|
+
├── DEVELOPMENT.md # Development setup guide
|
|
88
|
+
├── INSTALL.md # Installation instructions
|
|
89
|
+
├── LICENSE # MIT License
|
|
90
|
+
├── Makefile # Make targets for common tasks
|
|
91
|
+
├── pyproject.toml # Project metadata & dependencies
|
|
92
|
+
├── codecov.yml # Codecov configuration
|
|
93
|
+
└── README.md # Project overview
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Versioning & Releases
|
|
97
|
+
|
|
98
|
+
- **Single Source of Truth**: Package version is in `pyproject.toml` (`[project].version`)
|
|
99
|
+
- **Version Bumps**: update `pyproject.toml`, `CHANGELOG.md` and update the constants in `src/lib_cli_exit_tools/__init__conf__.py` according to `pyproject.toml`
|
|
100
|
+
- Automation rewrites `src/lib_cli_exit_tools/__init__conf__.py` from `pyproject.toml`, so runtime code imports generated constants instead of querying `importlib.metadata`.
|
|
101
|
+
- After updating project metadata (version, summary, URLs, authors) run `make test` (or `python -m scripts.test`) to regenerate the metadata module before committing.
|
|
102
|
+
- **Release Tags**: Format is `vX.Y.Z` (push tags for CI to build and publish)
|
|
103
|
+
|
|
104
|
+
## Common Make Targets
|
|
105
|
+
|
|
106
|
+
| Target | Description |
|
|
107
|
+
|-------------------|---------------------------------------------------------------------------------|
|
|
108
|
+
| `build` | Build wheel/sdist artifacts |
|
|
109
|
+
| `bump` | Bump version (VERSION=X.Y.Z or PART=major\|minor\|patch) and update changelog |
|
|
110
|
+
| `bump-major` | Increment major version ((X+1).0.0) |
|
|
111
|
+
| `bump-minor` | Increment minor version (X.Y.Z → X.(Y+1).0) |
|
|
112
|
+
| `bump-patch` | Increment patch version (X.Y.Z → X.Y.(Z+1)) |
|
|
113
|
+
| `clean` | Remove caches, coverage, and build artifacts (includes `dist/` and `build/`) |
|
|
114
|
+
| `dev` | Install package with dev extras |
|
|
115
|
+
| `help` | Show make targets |
|
|
116
|
+
| `install` | Editable install |
|
|
117
|
+
| `menu` | Interactive TUI menu |
|
|
118
|
+
| `push` | Commit changes and push to GitHub (no CI monitoring) |
|
|
119
|
+
| `release` | Tag vX.Y.Z, push, sync packaging, run gh release if available |
|
|
120
|
+
| `run` | Run module entry (`python -m ... --help`) |
|
|
121
|
+
| `test` | Lint, format, type-check, run tests with coverage, upload to Codecov |
|
|
122
|
+
| `version-current` | Print current version from `pyproject.toml` |
|
|
123
|
+
|
|
124
|
+
## Coding Style & Naming Conventions
|
|
125
|
+
|
|
126
|
+
Follow the guidelines in `python_clean_code.md` for all Python code.
|
|
127
|
+
|
|
128
|
+
## Architecture Overview
|
|
129
|
+
|
|
130
|
+
This library follows Clean Architecture with three layers:
|
|
131
|
+
- **core/**: Domain layer with exit codes and configuration (no external dependencies)
|
|
132
|
+
- **application/**: Application services and runners
|
|
133
|
+
- **adapters/**: External interfaces (signal handling)
|
|
134
|
+
|
|
135
|
+
Import rules (enforced by import-linter):
|
|
136
|
+
- `core` cannot import from `application`, `adapters`, or `cli`
|
|
137
|
+
- `application` cannot import from `cli`
|
|
138
|
+
|
|
139
|
+
Apply principles from `python_clean_architecture.md` when designing and implementing features.
|
|
140
|
+
|
|
141
|
+
## Security & Configuration
|
|
142
|
+
|
|
143
|
+
- `.env` files are for local tooling only (CodeCov tokens, etc.)
|
|
144
|
+
- **NEVER** commit secrets to version control
|
|
145
|
+
- Rich logging should sanitize payloads before rendering
|
|
146
|
+
|
|
147
|
+
## Commit & Push Policy
|
|
148
|
+
|
|
149
|
+
### Pre-Push Requirements
|
|
150
|
+
- **Always run `make test` before pushing** to avoid lint/test breakage
|
|
151
|
+
- Ensure all tests pass and code is properly formatted
|
|
152
|
+
|
|
153
|
+
### Post-Push Monitoring
|
|
154
|
+
- Monitor GitHub Actions for errors after pushing
|
|
155
|
+
- Attempt to correct any CI/CD errors that appear
|
|
156
|
+
|
|
157
|
+
## Claude Code Workflow
|
|
158
|
+
|
|
159
|
+
When working on this project:
|
|
160
|
+
1. Read relevant system prompts at session start
|
|
161
|
+
2. Apply appropriate coding guidelines based on file type
|
|
162
|
+
3. Run `make test` before commits
|
|
163
|
+
4. Follow versioning guidelines for releases
|
|
164
|
+
5. Monitor CI after pushing changes
|
|
@@ -126,8 +126,9 @@ We distribute via PyPI only. If you prefer isolated CLI installs, use tools such
|
|
|
126
126
|
|
|
127
127
|
After installation the following commands should resolve:
|
|
128
128
|
|
|
129
|
-
- `
|
|
130
|
-
- `
|
|
129
|
+
- `lib-cli-exit-tools` (default console script)
|
|
130
|
+
- `lib_cli_exit_tools` (alias)
|
|
131
|
+
- `cli-exit-tools` (alias)
|
|
131
132
|
- `python -m lib_cli_exit_tools`
|
|
132
133
|
|
|
133
134
|
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:
|