strictcli 0.17.0__tar.gz → 0.18.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- strictcli-0.18.0/.rlsbl/changes/.validated +1 -0
- strictcli-0.18.0/.rlsbl/changes/0.17.0.md +9 -0
- strictcli-0.18.0/.rlsbl/changes/0.18.0.jsonl +4 -0
- strictcli-0.18.0/.rlsbl/changes/0.18.0.md +5 -0
- strictcli-0.18.0/.rlsbl/releases/v0.18.0.toml +8 -0
- strictcli-0.18.0/.rlsbl/version +1 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/CHANGELOG.md +15 -2
- {strictcli-0.17.0 → strictcli-0.18.0}/PKG-INFO +1 -1
- {strictcli-0.17.0 → strictcli-0.18.0}/package-lock.json +2 -2
- {strictcli-0.17.0 → strictcli-0.18.0}/package.json +1 -1
- {strictcli-0.17.0 → strictcli-0.18.0}/pyproject.toml +1 -1
- {strictcli-0.17.0 → strictcli-0.18.0}/strictcli/__init__.py +78 -29
- strictcli-0.18.0/tests/test_check_public_api.py +435 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_check_runner.py +9 -9
- strictcli-0.18.0/todo/.done/public-check-runner-api.md +36 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/uv.lock +1 -1
- strictcli-0.17.0/.rlsbl/changes/.validated +0 -1
- strictcli-0.17.0/.rlsbl/version +0 -1
- {strictcli-0.17.0 → strictcli-0.18.0}/.claude/settings.json +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.github/workflows/ci.yml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.github/workflows/publish.yml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.gitignore +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.npmignore +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.claude/settings.json +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.gitignore +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.npmignore +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.rlsbl/lint/go.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.rlsbl/lint/npm.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/CHANGELOG.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/CLAUDE.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/bases/LICENSE +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.10.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.10.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.11.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.11.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.12.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.12.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.13.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.13.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.14.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.14.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.15.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.15.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.15.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.15.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.16.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.16.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.16.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.16.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.17.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.4.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.4.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.4.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.4.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.5.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.5.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.6.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.6.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.6.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.6.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.7.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.7.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.7.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.7.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.2.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.2.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.3.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.3.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.4.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.4.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.5.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.5.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.6.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.6.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.7.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.8.7.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.9.0.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.9.0.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.9.1.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/0.9.1.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/changes/unreleased.jsonl +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/config.json +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/hashes.json +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/hooks/post-release.sh +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/hooks/pre-checks.sh +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/hooks/pre-release.sh +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/lint/go.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/lint/npm.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/lint/python.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/unreleased.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.10.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.11.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.12.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.13.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.15.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.15.1.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.16.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.16.1.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.17.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.8.5.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.8.6.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.8.7.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.9.0.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.rlsbl/releases/v0.9.1.toml +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/.strictcli/schema.json +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/CLAUDE.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/LICENSE +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/README.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/index.js +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/postinstall.js +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_arg_default.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_at_prefix.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_auto_version.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_check_command.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_check_discovery.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_check_schema.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_check_types.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_choices.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_command_help_suggestion.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_config.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_config_file_path.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_config_set_bugs.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_deep_nesting.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_dependencies.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_deprecated.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_dump_schema.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_e2e.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_env.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_exit_codes.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_float_type.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_global_flags.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_help.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_int_type.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_mutex.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_nesting.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_parser.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_passthrough.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_registration.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_repeatable.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_tagdsl.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_tags.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_toml_loading.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_unique.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_utilities.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_validate.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/tests/test_variadic.py +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/todo/.defer/deferred.md +0 -0
- {strictcli-0.17.0 → strictcli-0.18.0}/todo/.done/original-idea.md +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9fe0fe3a00effc0c9e39704a0bd0cc865542da83
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## 0.17.0
|
|
2
|
+
|
|
3
|
+
### Breaking
|
|
4
|
+
|
|
5
|
+
- **Breaking.** Repeatable flag defaults are now validated at registration: must be a list, `default=[]` is rejected as redundant, and element types must match the flag type.
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- **New.** Help text now displays non-empty repeatable flag defaults as `[default: a, b, c]`.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"commits":["ab63f2e29d95b834aef6e3307d23b53e3f845afe","fc7ae2927aa12b7627c3119c818d9a7e89209e39","db1924cbd143285c857324a8fcf2110718080bfa"],"user_facing":true,"description":"**New.** Public API for running checks programmatically: `App.run_checks()`, `format_check_results()`, `format_check_results_json()`, `CheckRunResult`.","type":"feature"}
|
|
2
|
+
{"commits":["6407ea33c3a16a83dcd7c362cda8e98980074a73","edfcf45b0eb1ba4896fcff1d31ea9993c9b363a1","fcaae9bb7895805308a6b9299158ada7f6d45f3b","b6720d2dd1063bff0b49f6d5624608672c0cac33"],"user_facing":false}
|
|
3
|
+
{"commits":["9cc04830fa5b7eef0d87b249e57248415fd769a5","4e89101a5fdb8c0a6f46b62829f22e09b79ec2d1"],"user_facing":false}
|
|
4
|
+
{"commits":["67ee39ff3cdf4d09a9a29c0bdcb9853999878ee9"],"user_facing":false}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Version bump type: patch, minor, or major
|
|
2
|
+
bump = "minor"
|
|
3
|
+
# Short description of this release (required)
|
|
4
|
+
description = "Public API for running checks programmatically"
|
|
5
|
+
# Optional context explaining why these changes were made
|
|
6
|
+
context = "Adds App.run_checks(), format_check_results(), format_check_results_json(), and CheckRunResult — a stable public API replacing the private _filter_checks/_resolve_check_order/_run_checks/_check_format_human functions that consumers like rlsbl were forced to use."
|
|
7
|
+
include = ["pypi", "npm"]
|
|
8
|
+
exclude = []
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.67.1
|
|
@@ -2,9 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
-
## 0.
|
|
5
|
+
## 0.18.0
|
|
6
|
+
|
|
7
|
+
Public API for running checks programmatically
|
|
8
|
+
|
|
9
|
+
<details>
|
|
10
|
+
<summary>Context</summary>
|
|
11
|
+
|
|
12
|
+
Adds App.run_checks(), format_check_results(), format_check_results_json(), and CheckRunResult — a stable public API replacing the private _filter_checks/_resolve_check_order/_run_checks/_check_format_human functions that consumers like rlsbl were forced to use.
|
|
13
|
+
|
|
14
|
+
</details>
|
|
6
15
|
|
|
7
|
-
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
- **New.** Public API for running checks programmatically: `App.run_checks()`, `format_check_results()`, `format_check_results_json()`, `CheckRunResult`.
|
|
19
|
+
|
|
20
|
+
## 0.17.0
|
|
8
21
|
|
|
9
22
|
### Breaking
|
|
10
23
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strictcli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "strictcli",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.18.0",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT"
|
|
12
12
|
}
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
__version__ = "0.
|
|
5
|
+
__version__ = "0.18.0"
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"App", "Flag", "Arg", "Tag", "MutexGroup", "CoRequired", "Requires",
|
|
9
9
|
"Implies", "Passthrough", "DeprecatedCommand", "Result", "flag", "arg",
|
|
10
|
-
"CheckResult", "CheckContext",
|
|
10
|
+
"CheckResult", "CheckContext", "CheckRunResult",
|
|
11
|
+
"format_check_results", "format_check_results_json",
|
|
11
12
|
]
|
|
12
13
|
|
|
13
14
|
import contextlib
|
|
@@ -856,6 +857,14 @@ class CheckResult:
|
|
|
856
857
|
raise ValueError("CheckResult.message must be a non-empty string")
|
|
857
858
|
|
|
858
859
|
|
|
860
|
+
@dataclass(frozen=True)
|
|
861
|
+
class CheckRunResult:
|
|
862
|
+
"""A named check result returned by App.run_checks()."""
|
|
863
|
+
|
|
864
|
+
name: str
|
|
865
|
+
result: CheckResult
|
|
866
|
+
|
|
867
|
+
|
|
859
868
|
@runtime_checkable
|
|
860
869
|
class CheckContext(Protocol):
|
|
861
870
|
"""Minimal interface that tool-specific check contexts must satisfy."""
|
|
@@ -1001,6 +1010,38 @@ class App:
|
|
|
1001
1010
|
"""
|
|
1002
1011
|
self._check_context_factory = factory
|
|
1003
1012
|
|
|
1013
|
+
def run_checks(
|
|
1014
|
+
self,
|
|
1015
|
+
context: CheckContext,
|
|
1016
|
+
*,
|
|
1017
|
+
tag_expr: str | None = None,
|
|
1018
|
+
name_glob: str | None = None,
|
|
1019
|
+
run_all: bool = False,
|
|
1020
|
+
ignore_warnings: bool = False,
|
|
1021
|
+
) -> tuple[list[CheckRunResult], int]:
|
|
1022
|
+
"""Run checks programmatically with filtering and dependency resolution.
|
|
1023
|
+
|
|
1024
|
+
Returns (results, exit_code) where results is a list of CheckRunResult
|
|
1025
|
+
and exit_code is 0 if all pass (or all warn with ignore_warnings), else 1.
|
|
1026
|
+
"""
|
|
1027
|
+
if not self._checks_enabled:
|
|
1028
|
+
raise ValueError("checks are not enabled on this App")
|
|
1029
|
+
err = self._validate_check_registrations()
|
|
1030
|
+
if err:
|
|
1031
|
+
raise ValueError(err)
|
|
1032
|
+
selected = _filter_checks(self._check_defs, tag_expr, name_glob, run_all)
|
|
1033
|
+
if not selected:
|
|
1034
|
+
return ([], 0)
|
|
1035
|
+
order = _resolve_check_order(self._check_defs, selected)
|
|
1036
|
+
raw_results, exit_code = _run_checks(
|
|
1037
|
+
self._check_defs, order, context, ignore_warnings,
|
|
1038
|
+
)
|
|
1039
|
+
results = [
|
|
1040
|
+
CheckRunResult(name=name, result=result)
|
|
1041
|
+
for name, result in raw_results
|
|
1042
|
+
]
|
|
1043
|
+
return (results, exit_code)
|
|
1044
|
+
|
|
1004
1045
|
def _register_check_command(self) -> None:
|
|
1005
1046
|
"""Register the auto-generated 'check' command when checks.toml exists."""
|
|
1006
1047
|
app_ref = self # capture for closure
|
|
@@ -1048,14 +1089,19 @@ class App:
|
|
|
1048
1089
|
)
|
|
1049
1090
|
return 1
|
|
1050
1091
|
context = app_ref._check_context_factory()
|
|
1051
|
-
|
|
1052
|
-
app_ref, order, context, ignore_warnings,
|
|
1092
|
+
raw_results, exit_code = _run_checks(
|
|
1093
|
+
app_ref._check_defs, order, context, ignore_warnings,
|
|
1053
1094
|
)
|
|
1054
1095
|
|
|
1096
|
+
results_wrapped = [
|
|
1097
|
+
CheckRunResult(name=n, result=r) for n, r in raw_results
|
|
1098
|
+
]
|
|
1055
1099
|
if json:
|
|
1056
|
-
|
|
1100
|
+
print(format_check_results_json(results_wrapped))
|
|
1057
1101
|
else:
|
|
1058
|
-
|
|
1102
|
+
output = format_check_results(results_wrapped, verbose)
|
|
1103
|
+
if output:
|
|
1104
|
+
print(output)
|
|
1059
1105
|
|
|
1060
1106
|
return exit_code
|
|
1061
1107
|
|
|
@@ -3330,7 +3376,7 @@ def _find_cycle(
|
|
|
3330
3376
|
|
|
3331
3377
|
|
|
3332
3378
|
def _run_checks(
|
|
3333
|
-
|
|
3379
|
+
check_defs: dict,
|
|
3334
3380
|
check_names: list[str],
|
|
3335
3381
|
context: CheckContext,
|
|
3336
3382
|
ignore_warnings: bool,
|
|
@@ -3340,7 +3386,6 @@ def _run_checks(
|
|
|
3340
3386
|
Returns (results_list, exit_code). exit_code is 0 if all pass (or all
|
|
3341
3387
|
warn with ignore_warnings=True), 1 otherwise.
|
|
3342
3388
|
"""
|
|
3343
|
-
check_defs = app._check_defs
|
|
3344
3389
|
results: list[tuple[str, CheckResult]] = []
|
|
3345
3390
|
failed_checks: set[str] = set()
|
|
3346
3391
|
exit_code = 0
|
|
@@ -3440,39 +3485,43 @@ def _check_dry_run_mode(
|
|
|
3440
3485
|
print(f" {i}. {name}")
|
|
3441
3486
|
|
|
3442
3487
|
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3488
|
+
|
|
3489
|
+
def format_check_results(
|
|
3490
|
+
results: list[CheckRunResult], verbose: bool = False,
|
|
3491
|
+
) -> str:
|
|
3492
|
+
"""Format check results as a human-readable aligned string."""
|
|
3447
3493
|
if not results:
|
|
3448
|
-
return
|
|
3494
|
+
return ""
|
|
3449
3495
|
|
|
3450
|
-
name_width = max(len(name) for
|
|
3496
|
+
name_width = max(len(r.name) for r in results)
|
|
3497
|
+
lines: list[str] = []
|
|
3451
3498
|
|
|
3452
|
-
for
|
|
3453
|
-
label = _CHECK_STATUS_LABELS[result.status]
|
|
3454
|
-
|
|
3499
|
+
for r in results:
|
|
3500
|
+
label = _CHECK_STATUS_LABELS[r.result.status]
|
|
3501
|
+
lines.append(f"{label} {r.name:<{name_width}} {r.result.message}")
|
|
3455
3502
|
|
|
3456
|
-
show_details = result.details and (
|
|
3457
|
-
verbose or result.status in ("fail", "warn", "skip")
|
|
3503
|
+
show_details = r.result.details and (
|
|
3504
|
+
verbose or r.result.status in ("fail", "warn", "skip")
|
|
3458
3505
|
)
|
|
3459
3506
|
if show_details:
|
|
3460
|
-
for detail in result.details:
|
|
3461
|
-
|
|
3507
|
+
for detail in r.result.details:
|
|
3508
|
+
lines.append(f" {detail}")
|
|
3509
|
+
|
|
3510
|
+
return "\n".join(lines)
|
|
3462
3511
|
|
|
3463
3512
|
|
|
3464
|
-
def
|
|
3465
|
-
"""
|
|
3513
|
+
def format_check_results_json(results: list[CheckRunResult]) -> str:
|
|
3514
|
+
"""Format check results as a JSON string."""
|
|
3466
3515
|
items = [
|
|
3467
3516
|
{
|
|
3468
|
-
"name": name,
|
|
3469
|
-
"status": result.status,
|
|
3470
|
-
"message": result.message,
|
|
3471
|
-
"details": result.details,
|
|
3517
|
+
"name": r.name,
|
|
3518
|
+
"status": r.result.status,
|
|
3519
|
+
"message": r.result.message,
|
|
3520
|
+
"details": r.result.details if r.result.details is not None else [],
|
|
3472
3521
|
}
|
|
3473
|
-
for
|
|
3522
|
+
for r in results
|
|
3474
3523
|
]
|
|
3475
|
-
|
|
3524
|
+
return json.dumps(items, separators=(",", ":"))
|
|
3476
3525
|
|
|
3477
3526
|
|
|
3478
3527
|
# ---------------------------------------------------------------------------
|