lib-detect-testenv 3.0.2__tar.gz → 3.0.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_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.devcontainer/devcontainer.json +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.devcontainer/settings.json +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.env.example +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.github/actions/extract-metadata/action.yml +16 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.github/dependabot.yml +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.github/workflows/codeql.yml +1 -1
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.github/workflows/default_cicd_public.yml +63 -13
- lib_detect_testenv-3.0.4/.github/workflows/default_release_public.yml +95 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.gitignore +6 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.qlty/qlty.toml +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.snyk +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/CHANGELOG.md +35 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/CLAUDE.md +5 -5
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/CONTRIBUTING.md +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/DEVELOPMENT.md +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/INSTALL.md +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/LICENSE +0 -0
- lib_detect_testenv-3.0.4/Makefile +453 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/PKG-INFO +21 -21
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/README.md +12 -12
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/codecov.yml +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/concept.md +9 -9
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/docs/systemdesign/module_reference.md +1 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/notebooks/Quickstart.ipynb +4 -4
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/pyproject.toml +51 -9
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/__init__.py +10 -10
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/__init__conf__.py +4 -2
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/__main__.py +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/behaviors.py +5 -7
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/cli.py +33 -30
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/lib_detect_testenv.py +5 -12
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/src/lib_detect_testenv/py.typed +0 -0
- lib_detect_testenv-3.0.4/src/lib_detect_testenv/safe_console.py +213 -0
- lib_detect_testenv-3.0.4/src/lib_detect_testenv/typed_click.py +51 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/tests/conftest.py +4 -1
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/tests/test_behaviors.py +0 -0
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/tests/test_cli.py +7 -3
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/tests/test_lib_detect_testenv.py +1 -1
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/tests/test_metadata.py +12 -12
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/tests/test_module_entry.py +4 -1
- lib_detect_testenv-3.0.4/tests/test_safe_console.py +113 -0
- lib_detect_testenv-3.0.2/.github/workflows/default_release_public.yml +0 -69
- lib_detect_testenv-3.0.2/Makefile +0 -260
- lib_detect_testenv-3.0.2/src/lib_detect_testenv/typed_click.py +0 -37
- {lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/reset_git_history.sh +0 -0
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.github/actions/extract-metadata/action.yml
RENAMED
|
@@ -29,6 +29,11 @@ outputs:
|
|
|
29
29
|
BANDIT_SKIP_FLAG:
|
|
30
30
|
description: Bandit skip flag string (e.g. "-s B101,B601") or empty
|
|
31
31
|
value: ${{ steps.meta.outputs.BANDIT_SKIP_FLAG }}
|
|
32
|
+
PYTEST_MARKER_EXPR:
|
|
33
|
+
description: >-
|
|
34
|
+
Marker expression for the CI test run (e.g. "not local_only and not integration"),
|
|
35
|
+
built from tool.ci.pytest-exclude-markers
|
|
36
|
+
value: ${{ steps.meta.outputs.PYTEST_MARKER_EXPR }}
|
|
32
37
|
|
|
33
38
|
runs:
|
|
34
39
|
using: composite
|
|
@@ -69,6 +74,15 @@ runs:
|
|
|
69
74
|
bandit_skips = data.get('tool', {}).get('bandit', {}).get('skips', [])
|
|
70
75
|
bandit_skip_flag = f"-s {','.join(bandit_skips)}" if bandit_skips else ""
|
|
71
76
|
|
|
77
|
+
# --- [tool.ci] section ---
|
|
78
|
+
# CI always skips local_only (those tests need a dev box). A project whose
|
|
79
|
+
# suite also carries markers CI cannot satisfy - integration tests needing a
|
|
80
|
+
# container that a separate workflow starts - names them here, rather than
|
|
81
|
+
# every such repo forking this workflow to edit one -m expression.
|
|
82
|
+
ci_config = data.get('tool', {}).get('ci', {})
|
|
83
|
+
exclude_markers = ['local_only', *ci_config.get('pytest-exclude-markers', [])]
|
|
84
|
+
pytest_marker_expr = ' and '.join(f'not {m}' for m in exclude_markers)
|
|
85
|
+
|
|
72
86
|
# Write to GITHUB_OUTPUT for composite action outputs
|
|
73
87
|
with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as out:
|
|
74
88
|
out.write(f"PROJECT_NAME={project}\n")
|
|
@@ -79,6 +93,7 @@ runs:
|
|
|
79
93
|
out.write(f"COV_REPORT_FILE={cov_report_file}\n")
|
|
80
94
|
out.write(f"COV_FAIL_UNDER={cov_fail_under}\n")
|
|
81
95
|
out.write(f"BANDIT_SKIP_FLAG={bandit_skip_flag}\n")
|
|
96
|
+
out.write(f"PYTEST_MARKER_EXPR={pytest_marker_expr}\n")
|
|
82
97
|
|
|
83
98
|
# Also write to GITHUB_ENV so subsequent steps can use ${{ env.VAR }}
|
|
84
99
|
with open(os.environ['GITHUB_ENV'], 'a', encoding='utf-8') as env:
|
|
@@ -90,3 +105,4 @@ runs:
|
|
|
90
105
|
env.write(f"COV_REPORT_FILE={cov_report_file}\n")
|
|
91
106
|
env.write(f"COV_FAIL_UNDER={cov_fail_under}\n")
|
|
92
107
|
env.write(f"BANDIT_SKIP_FLAG={bandit_skip_flag}\n")
|
|
108
|
+
env.write(f"PYTEST_MARKER_EXPR={pytest_marker_expr}\n")
|
|
File without changes
|
{lib_detect_testenv-3.0.2 → lib_detect_testenv-3.0.4}/.github/workflows/default_cicd_public.yml
RENAMED
|
@@ -18,8 +18,8 @@ jobs:
|
|
|
18
18
|
python-latest: ${{ steps.metadata.outputs.python-latest }}
|
|
19
19
|
os-matrix: ${{ steps.metadata.outputs.os-matrix }}
|
|
20
20
|
steps:
|
|
21
|
-
- uses: actions/checkout@
|
|
22
|
-
- uses: actions/setup-python@
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
- uses: actions/setup-python@v7
|
|
23
23
|
with:
|
|
24
24
|
python-version: "3.x"
|
|
25
25
|
- name: Parse pyproject.toml for Python versions and OS matrix
|
|
@@ -66,8 +66,8 @@ jobs:
|
|
|
66
66
|
UV_LINK_MODE: "copy"
|
|
67
67
|
UV_BREAK_SYSTEM_PACKAGES: "1"
|
|
68
68
|
steps:
|
|
69
|
-
- uses: actions/checkout@
|
|
70
|
-
- uses: actions/setup-python@
|
|
69
|
+
- uses: actions/checkout@v7
|
|
70
|
+
- uses: actions/setup-python@v7
|
|
71
71
|
with:
|
|
72
72
|
python-version: ${{ matrix.python }}
|
|
73
73
|
- name: Install uv
|
|
@@ -169,7 +169,7 @@ jobs:
|
|
|
169
169
|
- name: Restore ruff cache
|
|
170
170
|
if: runner.environment == 'github-hosted'
|
|
171
171
|
id: ruff-cache
|
|
172
|
-
uses: actions/cache/restore@
|
|
172
|
+
uses: actions/cache/restore@v6
|
|
173
173
|
with:
|
|
174
174
|
path: .ruff_cache
|
|
175
175
|
key: ruff-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
|
|
@@ -201,7 +201,7 @@ jobs:
|
|
|
201
201
|
# and stale journal files cause "database is locked" errors.
|
|
202
202
|
COVERAGE_FILE: "${{ runner.temp }}/.coverage"
|
|
203
203
|
run: >-
|
|
204
|
-
pytest -m "
|
|
204
|
+
pytest -m "${{ env.PYTEST_MARKER_EXPR }}"
|
|
205
205
|
--cov=${{ env.SRC_PATH }}/${{ env.PACKAGE_MODULE }}
|
|
206
206
|
--cov-report=term-missing
|
|
207
207
|
--cov-report=xml:${{ env.COV_REPORT_FILE }}
|
|
@@ -236,12 +236,62 @@ jobs:
|
|
|
236
236
|
continue-on-error: true
|
|
237
237
|
shell: python
|
|
238
238
|
run: |
|
|
239
|
-
import subprocess, sys
|
|
239
|
+
import subprocess, sys, tempfile
|
|
240
240
|
import rtoml
|
|
241
241
|
from pathlib import Path
|
|
242
|
+
|
|
243
|
+
# Audit the project's OWN resolved dependency tree, not the ambient
|
|
244
|
+
# environment. "Install dev deps" uses --system, so the interpreter
|
|
245
|
+
# being audited is the runner image's, and that image ships packages
|
|
246
|
+
# this project neither declares nor distributes (setuptools, pip,
|
|
247
|
+
# wheel). Auditing those reported CVEs no consumer of this project is
|
|
248
|
+
# exposed to, and a scan that is permanently yellow is a scan everyone
|
|
249
|
+
# learns to ignore. Resolving pyproject.toml here keeps the result
|
|
250
|
+
# identical on every OS/python and dependent only on what we declare.
|
|
242
251
|
data = rtoml.load(Path("pyproject.toml"))
|
|
252
|
+
|
|
253
|
+
# Not every project declares dev dependencies, and those that do may use
|
|
254
|
+
# either an extra or a PEP 735 group. Asking uv for one that does not
|
|
255
|
+
# exist is a hard error ("Requested extra not found"), which would leave
|
|
256
|
+
# the audit permanently broken here rather than merely noisy, so select
|
|
257
|
+
# the flag from what this project actually declares.
|
|
258
|
+
selector = []
|
|
259
|
+
if "dev" in data.get("project", {}).get("optional-dependencies", {}):
|
|
260
|
+
selector = ["--extra", "dev"]
|
|
261
|
+
elif "dev" in data.get("dependency-groups", {}):
|
|
262
|
+
selector = ["--group", "dev"]
|
|
263
|
+
|
|
264
|
+
tmp = Path(tempfile.mkdtemp())
|
|
265
|
+
req = tmp / "compiled-requirements.txt"
|
|
266
|
+
subprocess.check_call(
|
|
267
|
+
["uv", "pip", "compile", *selector, "pyproject.toml", "-o", str(req), "--quiet"]
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
# Drop direct URL references ("pkg @ git+https://...") before auditing.
|
|
271
|
+
# pip-audit cannot audit those (they are not on PyPI) but, given a
|
|
272
|
+
# requirements file, first tries to `git clone` each one to resolve a
|
|
273
|
+
# version - a slow, credential-dependent fetch. No public project here
|
|
274
|
+
# uses one today, yet "allow-direct-references" is enabled, so this
|
|
275
|
+
# guards the day one appears and keeps this step identical to the
|
|
276
|
+
# default_cicd_private template's.
|
|
277
|
+
audit_req = tmp / "audit-requirements.txt"
|
|
278
|
+
kept, dropped = [], []
|
|
279
|
+
for line in req.read_text(encoding="utf-8").splitlines():
|
|
280
|
+
if " @ " in line and not line.lstrip().startswith("#"):
|
|
281
|
+
dropped.append(line.split(" @ ", 1)[0].strip())
|
|
282
|
+
else:
|
|
283
|
+
kept.append(line)
|
|
284
|
+
audit_req.write_text("\n".join(kept) + "\n", encoding="utf-8")
|
|
285
|
+
if dropped:
|
|
286
|
+
# Never drop coverage silently: name what is not being audited here.
|
|
287
|
+
print(f"::notice::pip-audit: not auditing {len(dropped)} direct-URL dependency/ies "
|
|
288
|
+
f"(audited in their own repo): {', '.join(sorted(dropped))}")
|
|
289
|
+
|
|
290
|
+
req = audit_req
|
|
243
291
|
vulns = data.get("tool", {}).get("pip-audit", {}).get("ignore-vulns", [])
|
|
244
|
-
|
|
292
|
+
# --no-deps: the compiled file is already a complete pinned resolution,
|
|
293
|
+
# so pip-audit must audit it verbatim rather than re-resolving it.
|
|
294
|
+
cmd = ["pip-audit", "--no-deps", "-r", str(req)]
|
|
245
295
|
for v in vulns:
|
|
246
296
|
cmd.extend(["--ignore-vuln", v])
|
|
247
297
|
sys.exit(subprocess.call(cmd))
|
|
@@ -293,7 +343,7 @@ jobs:
|
|
|
293
343
|
|
|
294
344
|
- name: Save ruff cache
|
|
295
345
|
if: always() && runner.environment == 'github-hosted' && steps.ruff-cache.outputs.cache-hit != 'true'
|
|
296
|
-
uses: actions/cache/save@
|
|
346
|
+
uses: actions/cache/save@v6
|
|
297
347
|
with:
|
|
298
348
|
path: .ruff_cache
|
|
299
349
|
key: ruff-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
|
|
@@ -302,8 +352,8 @@ jobs:
|
|
|
302
352
|
name: pipx/uv verification (ubuntu)
|
|
303
353
|
runs-on: ubuntu-latest
|
|
304
354
|
steps:
|
|
305
|
-
- uses: actions/checkout@
|
|
306
|
-
- uses: actions/setup-python@
|
|
355
|
+
- uses: actions/checkout@v7
|
|
356
|
+
- uses: actions/setup-python@v7
|
|
307
357
|
with:
|
|
308
358
|
python-version: "3.14"
|
|
309
359
|
|
|
@@ -341,8 +391,8 @@ jobs:
|
|
|
341
391
|
name: Execute notebooks (ubuntu, Python 3.14)
|
|
342
392
|
runs-on: ubuntu-latest
|
|
343
393
|
steps:
|
|
344
|
-
- uses: actions/checkout@
|
|
345
|
-
- uses: actions/setup-python@
|
|
394
|
+
- uses: actions/checkout@v7
|
|
395
|
+
- uses: actions/setup-python@v7
|
|
346
396
|
with:
|
|
347
397
|
python-version: "3.14"
|
|
348
398
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# The tag push is the only release event bmk guarantees: it runs
|
|
4
|
+
# `git push <remote> <tag>` unconditionally, whereas `gh release create` sits
|
|
5
|
+
# behind a gh-availability check and runs with check=False, so a missing or
|
|
6
|
+
# failing gh would leave nothing to publish. Listening for `release: published`
|
|
7
|
+
# as well fired a second, redundant run that raced the first to the upload and
|
|
8
|
+
# only ever logged "Skipping ... already exists".
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
tags:
|
|
12
|
+
- 'v*'
|
|
13
|
+
workflow_dispatch: {}
|
|
14
|
+
|
|
15
|
+
# One publish at a time per tag, so a workflow_dispatch re-run cannot overlap
|
|
16
|
+
# the run the tag push started.
|
|
17
|
+
concurrency:
|
|
18
|
+
group: release-${{ github.ref_name }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
env:
|
|
27
|
+
UV_LINK_MODE: "copy"
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v7
|
|
30
|
+
- uses: actions/setup-python@v7
|
|
31
|
+
with:
|
|
32
|
+
python-version: '3.14'
|
|
33
|
+
|
|
34
|
+
- name: Install uv
|
|
35
|
+
uses: astral-sh/setup-uv@v7
|
|
36
|
+
with:
|
|
37
|
+
enable-cache: true
|
|
38
|
+
prune-cache: false
|
|
39
|
+
|
|
40
|
+
- name: Build artifacts
|
|
41
|
+
run: uv build
|
|
42
|
+
|
|
43
|
+
- name: Upload artifacts
|
|
44
|
+
uses: actions/upload-artifact@v7
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/*
|
|
48
|
+
|
|
49
|
+
- name: Prune uv cache
|
|
50
|
+
continue-on-error: true
|
|
51
|
+
run: uv cache prune --ci
|
|
52
|
+
|
|
53
|
+
publish:
|
|
54
|
+
needs: build
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
environment: pypi
|
|
57
|
+
permissions:
|
|
58
|
+
contents: read
|
|
59
|
+
# id-token is required for OIDC / PyPI Trusted Publisher. It is harmless when
|
|
60
|
+
# a PYPI_API_TOKEN secret is configured, in which case the token path runs.
|
|
61
|
+
id-token: write
|
|
62
|
+
steps:
|
|
63
|
+
- name: Select PyPI auth method
|
|
64
|
+
id: auth
|
|
65
|
+
env:
|
|
66
|
+
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
67
|
+
run: |
|
|
68
|
+
if [ -n "$PYPI_API_TOKEN" ]; then
|
|
69
|
+
echo "PYPI_API_TOKEN is set; publishing with the API token."
|
|
70
|
+
echo "method=token" >> "$GITHUB_OUTPUT"
|
|
71
|
+
else
|
|
72
|
+
echo "No PYPI_API_TOKEN; publishing via OIDC Trusted Publisher."
|
|
73
|
+
echo "method=oidc" >> "$GITHUB_OUTPUT"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
- name: Download artifacts
|
|
77
|
+
uses: actions/download-artifact@v8
|
|
78
|
+
with:
|
|
79
|
+
name: dist
|
|
80
|
+
path: dist/
|
|
81
|
+
|
|
82
|
+
- name: Publish to PyPI (API token)
|
|
83
|
+
if: steps.auth.outputs.method == 'token'
|
|
84
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
85
|
+
with:
|
|
86
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
87
|
+
attestations: false
|
|
88
|
+
skip-existing: true
|
|
89
|
+
|
|
90
|
+
- name: Publish to PyPI (Trusted Publisher / OIDC)
|
|
91
|
+
if: steps.auth.outputs.method == 'oidc'
|
|
92
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
93
|
+
with:
|
|
94
|
+
attestations: true
|
|
95
|
+
skip-existing: true
|
|
File without changes
|
|
File without changes
|
|
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.0.4] 2026-08-01 00:14:59
|
|
11
|
+
### Fixed
|
|
12
|
+
- **Console output no longer crashes on a legacy codepage.** A Windows console at codepage 1252
|
|
13
|
+
hands Python an `errors="strict"` stream, so writing a non-ASCII character such as a check mark
|
|
14
|
+
raised `UnicodeEncodeError: 'charmap' codec can't encode character` and the command exited
|
|
15
|
+
non-zero *after* its work had already succeeded. Click does not protect against this, and Rich
|
|
16
|
+
raises the same way through its own writer. The new `safe_console` module degrades at the sink:
|
|
17
|
+
a UTF-8 terminal still receives the character, and only a stream that cannot encode it sees
|
|
18
|
+
`[OK]` / `[X]` / `[!]`. Every `click.echo` call site routes through it, and a test fails if a
|
|
19
|
+
module reaches for `click.echo` or builds an unwrapped `Console(file=sys.stdout)` again.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [3.0.3] 2026-07-24 16:01:54
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- Fixed CI going red under the latest ruff (0.16 widened its default rule set to ~920 rules on a
|
|
26
|
+
repo with no explicit `[tool.ruff.lint].select`): pinned the curated bitranox rule select instead
|
|
27
|
+
of chasing the exploded default set.
|
|
28
|
+
- `raise SystemExit(2)` in the CLI's error handlers now uses `from e` so tracebacks show the
|
|
29
|
+
original cause (B904).
|
|
30
|
+
- `print_info()` and the `__main__` guard now write via `sys.stdout`/`sys.stderr` instead of `print`,
|
|
31
|
+
fixing a latent bug where the guard printed a `bytes` literal's repr instead of the plain message.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- Added the curated `[tool.ruff.lint].select` (matching `bitranox_template_py_cli`) plus
|
|
35
|
+
`pydocstyle` Google convention and a `tests/*.py` per-file-ignore list, replacing the previous
|
|
36
|
+
no-`select` config that inherited ruff's entire default rule set.
|
|
37
|
+
- Made the Click CLI callback parameters keyword-only (`*,`) so ruff's `PLR0917` no longer fires;
|
|
38
|
+
Click already invokes command callbacks by keyword, so this is not a call-site change.
|
|
39
|
+
- Simplified boolean-returning `if/return True/False` branches in `lib_detect_testenv.py` to direct
|
|
40
|
+
`return <condition>` expressions (SIM103).
|
|
41
|
+
- Moved two deferred, no-reason `import sys`/`from rich.style import Style` statements in `cli.py`
|
|
42
|
+
to the module top (PLC0415).
|
|
43
|
+
- Replaced `Optional[X]` with `X | None` throughout `cli.py` (UP045).
|
|
44
|
+
|
|
10
45
|
## [3.0.2] 2026-06-14
|
|
11
46
|
|
|
12
47
|
### Changed
|
|
@@ -9,9 +9,9 @@ When starting a new session, read and apply the following system prompt files fr
|
|
|
9
9
|
|
|
10
10
|
### Bash-Specific Guidelines
|
|
11
11
|
When working with Bash scripts:
|
|
12
|
-
- use skill `
|
|
12
|
+
- use skill `bitranox:bash-reference` when in doubt of bash features or syntax
|
|
13
13
|
- `core_programming_solid.md`
|
|
14
|
-
- use skill `
|
|
14
|
+
- use skill `bitranox:bash-clean-architecture`
|
|
15
15
|
- `bash_clean_code.md`
|
|
16
16
|
- `bash_small_functions.md`
|
|
17
17
|
|
|
@@ -19,10 +19,10 @@ When working with Bash scripts:
|
|
|
19
19
|
When working with Python code:
|
|
20
20
|
- `core_programming_solid.md`
|
|
21
21
|
- `python_solid_architecture_enforcer.md`
|
|
22
|
-
- use skill `
|
|
22
|
+
- use skill `bitranox:python-clean-architecture`
|
|
23
23
|
- `python_clean_code.md`
|
|
24
24
|
- `python_small_functions_style.md`
|
|
25
|
-
- use skill `
|
|
25
|
+
- use skill `bitranox:python-use-modern-libraries`
|
|
26
26
|
- `python_structure_template.md`
|
|
27
27
|
|
|
28
28
|
### Additional Guidelines
|
|
@@ -137,7 +137,7 @@ Import rules (enforced by import-linter):
|
|
|
137
137
|
- `cli` depends on `lib_detect_testenv` and `behaviors`
|
|
138
138
|
- Core detection functions have no internal dependencies
|
|
139
139
|
|
|
140
|
-
Apply principles use skill `
|
|
140
|
+
Apply principles use skill `bitranox:python-clean-architecture` when designing and implementing features.
|
|
141
141
|
|
|
142
142
|
## Security & Configuration
|
|
143
143
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|