strictcli 0.32.0__tar.gz → 0.32.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.
- {strictcli-0.32.0 → strictcli-0.32.1}/PKG-INFO +1 -1
- {strictcli-0.32.0 → strictcli-0.32.1}/pyproject.toml +1 -1
- {strictcli-0.32.0 → strictcli-0.32.1}/strictcli/__init__.py +22 -1
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_coverage.py +26 -6
- {strictcli-0.32.0 → strictcli-0.32.1}/uv.lock +1 -1
- {strictcli-0.32.0 → strictcli-0.32.1}/.claude/settings.json +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.github/workflows/ci.yml +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.github/workflows/publish.yml +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.gitignore +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/bases/.gitignore +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/config.json +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/lint/python.toml +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/managed-files.json +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.rlsbl/version +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/.strictcli/schema.json +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/CLAUDE.md +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/LICENSE +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/README.md +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/strictcli/py.typed +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/conftest.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_arg_default.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_arg_default_validation.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_at_prefix.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_auto_version.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_call.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_command.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_discovery.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_provider.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_public_api.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_runner.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_schema.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_check_types.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_choices.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_choices_none.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_command_help_suggestion.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_command_tags.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_compound_types.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_config.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_config_fields.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_config_file_path.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_config_set_bugs.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_context.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_deep_nesting.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_dependencies.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_deprecated.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_dump_schema.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_e2e.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_env.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_exit_codes.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_flag_sets.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_float_format.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_float_type.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_float_vectors.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_global_flag_conflict_position.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_global_flags.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_help.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_hermetic.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_infra_env.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_int_type.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_invoke.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_keyword_flags.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_mcp.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_mutex.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_nesting.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_parser.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_passthrough.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_provenance.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_provenance_phase2.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_registration.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_repeatable.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_reserved_global_flags.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_tagdsl.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_toml_loading.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_tool_export.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_typed_args.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_unique.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_utilities.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_validate.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_variadic.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/tests/test_visibility.py +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/todo/.defer/deferred.md +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/todo/.done/keyword-collision-in-flag-param-name.md +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/todo/.done/original-idea.md +0 -0
- {strictcli-0.32.0 → strictcli-0.32.1}/todo/.done/public-check-runner-api.md +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
__version__ = "0.32.
|
|
5
|
+
__version__ = "0.32.1"
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"App", "Flag", "Arg", "FlagSet", "MutexGroup", "CoRequired", "Requires",
|
|
@@ -2905,6 +2905,27 @@ class App:
|
|
|
2905
2905
|
coverage_dir = self._coverage_dir
|
|
2906
2906
|
manifest_path = self._coverage_manifest_path
|
|
2907
2907
|
|
|
2908
|
+
# Subject-matter gating (the sanctioned skip class, mirroring
|
|
2909
|
+
# project-type gating): when the anchored coverage root holds NEITHER
|
|
2910
|
+
# a committed manifest NOR any shard files, this is not the app's own
|
|
2911
|
+
# development tree -- e.g. an installed app running its checks from a
|
|
2912
|
+
# foreign project's cwd, where the construction-anchored root points
|
|
2913
|
+
# at a directory with no coverage state. Report a visible SKIP instead
|
|
2914
|
+
# of failing with the app's entire command surface listed as
|
|
2915
|
+
# uncovered. When EITHER exists, behavior is unchanged: a partial
|
|
2916
|
+
# manifest still fails honestly, and an empty-manifest file present
|
|
2917
|
+
# still means "coverage configured but empty" = fail listing all.
|
|
2918
|
+
manifest_exists = bool(manifest_path) and os.path.isfile(manifest_path)
|
|
2919
|
+
shards_exist = bool(coverage_dir) and os.path.isdir(coverage_dir) and any(
|
|
2920
|
+
fname.endswith(".jsonl") for fname in os.listdir(coverage_dir)
|
|
2921
|
+
)
|
|
2922
|
+
if not manifest_exists and not shards_exist:
|
|
2923
|
+
anchor = os.path.dirname(manifest_path) if manifest_path else coverage_dir
|
|
2924
|
+
return reporter.skipped(
|
|
2925
|
+
f"no coverage state at {anchor} -- cli-test-coverage applies "
|
|
2926
|
+
"to the app's own development tree"
|
|
2927
|
+
)
|
|
2928
|
+
|
|
2908
2929
|
covered: set[str] = set()
|
|
2909
2930
|
|
|
2910
2931
|
# Seed from the committed manifest -- this is what makes the verdict
|
|
@@ -175,16 +175,36 @@ class TestCoverageCheck:
|
|
|
175
175
|
cov_result = next(r for r in results if r.name == "cli-test-coverage")
|
|
176
176
|
assert cov_result.status == "pass"
|
|
177
177
|
|
|
178
|
-
def
|
|
179
|
-
"""No shards and no manifest ->
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
def test_zero_coverage_state_skips(self, tmp_path):
|
|
179
|
+
"""No shards and no manifest -> SKIP with a subject-matter reason.
|
|
180
|
+
|
|
181
|
+
Subject-matter gating: when the anchored coverage root holds NEITHER a
|
|
182
|
+
committed manifest NOR any shard files, this is not the app's own
|
|
183
|
+
development tree (e.g. an installed app running its checks from a foreign
|
|
184
|
+
project's cwd). The check reports a visible SKIP naming the anchored path
|
|
185
|
+
rather than failing with the whole command surface listed as uncovered.
|
|
184
186
|
"""
|
|
185
187
|
app = _make_app(tmp_path)
|
|
186
188
|
# Don't run any test() or call() -- no shards, no manifest
|
|
187
189
|
|
|
190
|
+
results, _, code = app.run_checks(
|
|
191
|
+
SimpleCtx(project_root=tmp_path),
|
|
192
|
+
run_all=True,
|
|
193
|
+
)
|
|
194
|
+
cov_result = next(r for r in results if r.name == "cli-test-coverage")
|
|
195
|
+
assert cov_result.status == "skip"
|
|
196
|
+
assert "development tree" in cov_result.message
|
|
197
|
+
# Reason names the anchored .strictcli path, not the foreign cwd.
|
|
198
|
+
assert str(tmp_path / ".strictcli") in cov_result.message
|
|
199
|
+
|
|
200
|
+
def test_empty_manifest_file_present_fails_listing_all(self, tmp_path):
|
|
201
|
+
"""An empty-manifest file present means "coverage configured but empty"
|
|
202
|
+
-> FAIL listing every command, NOT a skip. The skip class only triggers
|
|
203
|
+
when NEITHER a manifest NOR any shards exist."""
|
|
204
|
+
app = _make_app(tmp_path)
|
|
205
|
+
manifest_path = tmp_path / ".strictcli" / "test-coverage.json"
|
|
206
|
+
manifest_path.write_text("[]\n")
|
|
207
|
+
|
|
188
208
|
results, _, code = app.run_checks(
|
|
189
209
|
SimpleCtx(project_root=tmp_path),
|
|
190
210
|
run_all=True,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|