strictcli 0.8.2__tar.gz → 0.8.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.
Files changed (99) hide show
  1. strictcli-0.8.4/.rlsbl/changes/.validated +1 -0
  2. strictcli-0.8.4/.rlsbl/changes/0.8.3.jsonl +1 -0
  3. strictcli-0.8.4/.rlsbl/changes/0.8.3.md +3 -0
  4. strictcli-0.8.4/.rlsbl/changes/0.8.4.jsonl +3 -0
  5. strictcli-0.8.4/.rlsbl/changes/0.8.4.md +5 -0
  6. strictcli-0.8.4/.rlsbl/version +1 -0
  7. {strictcli-0.8.2 → strictcli-0.8.4}/CHANGELOG.md +10 -0
  8. {strictcli-0.8.2 → strictcli-0.8.4}/PKG-INFO +1 -1
  9. {strictcli-0.8.2 → strictcli-0.8.4}/package-lock.json +2 -2
  10. {strictcli-0.8.2 → strictcli-0.8.4}/package.json +1 -1
  11. {strictcli-0.8.2 → strictcli-0.8.4}/pyproject.toml +1 -1
  12. {strictcli-0.8.2 → strictcli-0.8.4}/strictcli/__init__.py +12 -9
  13. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_toml_loading.py +2 -2
  14. {strictcli-0.8.2 → strictcli-0.8.4}/uv.lock +1 -1
  15. strictcli-0.8.2/.rlsbl/changes/.validated +0 -1
  16. strictcli-0.8.2/.rlsbl/version +0 -1
  17. {strictcli-0.8.2 → strictcli-0.8.4}/.claude/settings.json +0 -0
  18. {strictcli-0.8.2 → strictcli-0.8.4}/.github/workflows/ci.yml +0 -0
  19. {strictcli-0.8.2 → strictcli-0.8.4}/.github/workflows/publish.yml +0 -0
  20. {strictcli-0.8.2 → strictcli-0.8.4}/.gitignore +0 -0
  21. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.claude/settings.json +0 -0
  22. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
  23. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
  24. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.gitignore +0 -0
  25. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
  26. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +0 -0
  27. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -0
  28. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.rlsbl/lint/go.toml +0 -0
  29. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.rlsbl/lint/npm.toml +0 -0
  30. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
  31. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/CHANGELOG.md +0 -0
  32. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/CLAUDE.md +0 -0
  33. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/bases/LICENSE +0 -0
  34. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.4.0.jsonl +0 -0
  35. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.4.0.md +0 -0
  36. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.4.1.jsonl +0 -0
  37. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.4.1.md +0 -0
  38. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.5.0.jsonl +0 -0
  39. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.5.0.md +0 -0
  40. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.6.0.jsonl +0 -0
  41. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.6.0.md +0 -0
  42. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.6.1.jsonl +0 -0
  43. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.6.1.md +0 -0
  44. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.7.0.jsonl +0 -0
  45. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.7.0.md +0 -0
  46. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.7.1.jsonl +0 -0
  47. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.7.1.md +0 -0
  48. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.8.0.jsonl +0 -0
  49. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.8.0.md +0 -0
  50. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.8.1.jsonl +0 -0
  51. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.8.1.md +0 -0
  52. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.8.2.jsonl +0 -0
  53. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/0.8.2.md +0 -0
  54. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/changes/unreleased.jsonl +0 -0
  55. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/config.json +0 -0
  56. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/hashes.json +0 -0
  57. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/hooks/post-release.sh +0 -0
  58. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/hooks/pre-checks.sh +0 -0
  59. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/hooks/pre-release.sh +0 -0
  60. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/lint/go.toml +0 -0
  61. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/lint/npm.toml +0 -0
  62. {strictcli-0.8.2 → strictcli-0.8.4}/.rlsbl/lint/python.toml +0 -0
  63. {strictcli-0.8.2 → strictcli-0.8.4}/CLAUDE.md +0 -0
  64. {strictcli-0.8.2 → strictcli-0.8.4}/LICENSE +0 -0
  65. {strictcli-0.8.2 → strictcli-0.8.4}/README.md +0 -0
  66. {strictcli-0.8.2 → strictcli-0.8.4}/index.js +0 -0
  67. {strictcli-0.8.2 → strictcli-0.8.4}/postinstall.js +0 -0
  68. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_arg_default.py +0 -0
  69. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_auto_version.py +0 -0
  70. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_check_command.py +0 -0
  71. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_check_discovery.py +0 -0
  72. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_check_runner.py +0 -0
  73. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_check_schema.py +0 -0
  74. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_check_types.py +0 -0
  75. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_choices.py +0 -0
  76. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_config.py +0 -0
  77. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_deep_nesting.py +0 -0
  78. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_dependencies.py +0 -0
  79. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_deprecated.py +0 -0
  80. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_dump_schema.py +0 -0
  81. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_e2e.py +0 -0
  82. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_env.py +0 -0
  83. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_exit_codes.py +0 -0
  84. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_float_type.py +0 -0
  85. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_global_flags.py +0 -0
  86. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_help.py +0 -0
  87. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_int_type.py +0 -0
  88. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_mutex.py +0 -0
  89. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_nesting.py +0 -0
  90. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_parser.py +0 -0
  91. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_passthrough.py +0 -0
  92. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_registration.py +0 -0
  93. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_repeatable.py +0 -0
  94. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_tagdsl.py +0 -0
  95. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_tags.py +0 -0
  96. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_validate.py +0 -0
  97. {strictcli-0.8.2 → strictcli-0.8.4}/tests/test_variadic.py +0 -0
  98. {strictcli-0.8.2 → strictcli-0.8.4}/todo/.defer/deferred.md +0 -0
  99. {strictcli-0.8.2 → strictcli-0.8.4}/todo/.done/original-idea.md +0 -0
@@ -0,0 +1 @@
1
+ 33dcdaea5388ed23e7f3df7369bac01ae7a303e6
@@ -0,0 +1 @@
1
+ {"commits":["1bf6b917d4fef550eabde575acb491ad5dba4ee1","2d09d745566c35310c927f4337ff50a9efa82c2a","67f33abc550875ba81135b0ec9f183225168e5b2","c5b62a7030db6b350423e3efcf8f7bfa95292363","e278add8e7c5f749d7a550be8b74794543fa9c3a"],"user_facing":false}
@@ -0,0 +1,3 @@
1
+ ## 0.8.3
2
+
3
+ - No user-facing changes.
@@ -0,0 +1,3 @@
1
+ {"commits":["b9de6b57374910b3b7b41f1e28a19cee7430cdd6","2b02693caebcc47a9cf033ccff61d3816450ed4d"],"user_facing":false}
2
+ {"commits":["084096729ab0e737e9c69e57a537c25c4733e794"],"user_facing":true,"description":"**Fix.** Allow empty `tags = []` in `.strictcli/checks.toml`. Checks without tags are valid -- they are addressable by `--name` and included in `--all`.","type":"fix"}
3
+ {"commits":["8dba95c70a17eeea8ce7f6ea1b0da65c35ab7691","2b02693caebcc47a9cf033ccff61d3816450ed4d","b9de6b57374910b3b7b41f1e28a19cee7430cdd6"],"user_facing":false}
@@ -0,0 +1,5 @@
1
+ ## 0.8.4
2
+
3
+ ### Fixes
4
+
5
+ - **Fix.** Allow empty `tags = []` in `.strictcli/checks.toml`. Checks without tags are valid -- they are addressable by `--name` and included in `--all`.
@@ -0,0 +1 @@
1
+ 0.38.2
@@ -2,6 +2,16 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## 0.8.4
6
+
7
+ ### Fixes
8
+
9
+ - **Fix.** Allow empty `tags = []` in `.strictcli/checks.toml`. Checks without tags are valid -- they are addressable by `--name` and included in `--all`.
10
+
11
+ ## 0.8.3
12
+
13
+ - No user-facing changes.
14
+
5
15
  ## 0.8.2
6
16
 
7
17
  - No user-facing changes.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strictcli
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Summary: A strict, zero-dependency CLI framework for Python
5
5
  Project-URL: Homepage, https://github.com/smm-h/strictcli
6
6
  Project-URL: Repository, https://github.com/smm-h/strictcli
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "strictcli",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "strictcli",
9
- "version": "0.8.2",
9
+ "version": "0.8.4",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT"
12
12
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strictcli",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "A strict, zero-dependency CLI framework for Python (npm wrapper)",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "strictcli"
7
- version = "0.8.2"
7
+ version = "0.8.4"
8
8
  description = "A strict, zero-dependency CLI framework for Python"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "0.8.2"
5
+ __version__ = "0.8.4"
6
6
 
7
7
  __all__ = [
8
8
  "App", "Flag", "Arg", "Tag", "MutexGroup", "CoRequired", "Requires",
@@ -143,9 +143,9 @@ def _load_checks_toml(path: str | Path) -> dict[str, _CheckDef]:
143
143
 
144
144
  # Validate tags
145
145
  tags = fields["tags"]
146
- if not isinstance(tags, list) or len(tags) == 0:
146
+ if not isinstance(tags, list):
147
147
  raise ValueError(
148
- f'checks.toml: check "{name}": "tags" must be a non-empty list of strings'
148
+ f'checks.toml: check "{name}": "tags" must be a list of strings'
149
149
  )
150
150
  for tag in tags:
151
151
  if not isinstance(tag, str) or not tag.strip():
@@ -2666,12 +2666,15 @@ _CHECK_STATUS_LABELS = {"pass": "PASS", "fail": "FAIL", "warn": "WARN", "skip":
2666
2666
 
2667
2667
  def _check_list_mode(check_defs: dict[str, _CheckDef], json_mode: bool) -> None:
2668
2668
  """Print check listing in human or JSON format."""
2669
+ # Sort alphabetically for deterministic output matching Go
2670
+ sorted_defs = sorted(check_defs.values(), key=lambda c: c.name)
2671
+
2669
2672
  if json_mode:
2670
2673
  items = [
2671
2674
  {"name": cdef.name, "tags": cdef.tags, "severity": cdef.severity}
2672
- for cdef in check_defs.values()
2675
+ for cdef in sorted_defs
2673
2676
  ]
2674
- print(json.dumps(items))
2677
+ print(json.dumps(items, separators=(",", ":")))
2675
2678
  return
2676
2679
 
2677
2680
  if not check_defs:
@@ -2679,14 +2682,14 @@ def _check_list_mode(check_defs: dict[str, _CheckDef], json_mode: bool) -> None:
2679
2682
  return
2680
2683
 
2681
2684
  # Compute column widths
2682
- name_width = max(len(cdef.name) for cdef in check_defs.values())
2685
+ name_width = max(len(cdef.name) for cdef in sorted_defs)
2683
2686
  name_width = max(name_width, len("NAME"))
2684
- tags_width = max(len(", ".join(cdef.tags)) for cdef in check_defs.values())
2687
+ tags_width = max(len(", ".join(cdef.tags)) for cdef in sorted_defs)
2685
2688
  tags_width = max(tags_width, len("TAGS"))
2686
2689
 
2687
2690
  header = f"{'NAME':<{name_width}} {'TAGS':<{tags_width}} SEVERITY"
2688
2691
  print(header)
2689
- for cdef in check_defs.values():
2692
+ for cdef in sorted_defs:
2690
2693
  tags_str = ", ".join(cdef.tags)
2691
2694
  print(f"{cdef.name:<{name_width}} {tags_str:<{tags_width}} {cdef.severity}")
2692
2695
 
@@ -2737,7 +2740,7 @@ def _check_format_json(results: list[tuple[str, CheckResult]]) -> None:
2737
2740
  }
2738
2741
  for name, result in results
2739
2742
  ]
2740
- print(json.dumps(items))
2743
+ print(json.dumps(items, separators=(",", ":")))
2741
2744
 
2742
2745
 
2743
2746
  # ---------------------------------------------------------------------------
@@ -211,8 +211,8 @@ depends_on = []
211
211
  """
212
212
  f = tmp_path / "checks.toml"
213
213
  f.write_text(toml)
214
- with pytest.raises(ValueError, match='"tags" must be a non-empty list'):
215
- _load_checks_toml(f)
214
+ defs = _load_checks_toml(f)
215
+ assert defs["my-check"].tags == []
216
216
 
217
217
  def test_tags_with_empty_string(self, tmp_path):
218
218
  toml = """\
@@ -232,7 +232,7 @@ wheels = [
232
232
 
233
233
  [[package]]
234
234
  name = "strictcli"
235
- version = "0.8.2"
235
+ version = "0.8.4"
236
236
  source = { editable = "." }
237
237
 
238
238
  [package.dev-dependencies]
@@ -1 +0,0 @@
1
- 61aec1f6ac50be6991dd46eff282317bad7487fd
@@ -1 +0,0 @@
1
- 0.38.0
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