strictcli 0.1.0__tar.gz → 0.4.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.
Files changed (71) hide show
  1. strictcli-0.4.1/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +5 -0
  2. strictcli-0.4.1/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +8 -0
  3. strictcli-0.4.1/.rlsbl/bases/.rlsbl/lint/go.toml +17 -0
  4. strictcli-0.4.1/.rlsbl/bases/.rlsbl/lint/npm.toml +19 -0
  5. strictcli-0.4.1/.rlsbl/bases/.rlsbl/lint/python.toml +25 -0
  6. strictcli-0.4.1/.rlsbl/changes/.validated +1 -0
  7. strictcli-0.4.1/.rlsbl/changes/0.4.0.jsonl +29 -0
  8. strictcli-0.4.1/.rlsbl/changes/0.4.0.md +16 -0
  9. strictcli-0.4.1/.rlsbl/changes/0.4.1.jsonl +4 -0
  10. strictcli-0.4.1/.rlsbl/changes/0.4.1.md +5 -0
  11. strictcli-0.4.1/.rlsbl/changes/unreleased.jsonl +0 -0
  12. strictcli-0.4.1/.rlsbl/hashes.json +15 -0
  13. strictcli-0.4.1/.rlsbl/hooks/pre-checks.sh +5 -0
  14. strictcli-0.4.1/.rlsbl/hooks/pre-release.sh +8 -0
  15. strictcli-0.4.1/.rlsbl/lint/go.toml +17 -0
  16. strictcli-0.4.1/.rlsbl/lint/npm.toml +19 -0
  17. strictcli-0.4.1/.rlsbl/lint/python.toml +25 -0
  18. strictcli-0.4.1/.rlsbl/version +1 -0
  19. strictcli-0.4.1/CHANGELOG.md +26 -0
  20. {strictcli-0.1.0 → strictcli-0.4.1}/PKG-INFO +94 -1
  21. {strictcli-0.1.0 → strictcli-0.4.1}/README.md +93 -0
  22. {strictcli-0.1.0 → strictcli-0.4.1}/package-lock.json +2 -2
  23. {strictcli-0.1.0 → strictcli-0.4.1}/package.json +1 -1
  24. {strictcli-0.1.0 → strictcli-0.4.1}/pyproject.toml +2 -2
  25. strictcli-0.4.1/strictcli/__init__.py +1424 -0
  26. strictcli-0.4.1/tests/test_arg_default.py +168 -0
  27. strictcli-0.4.1/tests/test_choices.py +140 -0
  28. strictcli-0.4.1/tests/test_dependencies.py +400 -0
  29. strictcli-0.4.1/tests/test_exit_codes.py +56 -0
  30. strictcli-0.4.1/tests/test_global_flags.py +346 -0
  31. strictcli-0.4.1/tests/test_int_type.py +154 -0
  32. strictcli-0.4.1/tests/test_mutex.py +444 -0
  33. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_parser.py +20 -0
  34. strictcli-0.4.1/tests/test_passthrough.py +290 -0
  35. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_registration.py +2 -2
  36. strictcli-0.4.1/tests/test_repeatable.py +179 -0
  37. strictcli-0.4.1/tests/test_validate.py +135 -0
  38. strictcli-0.4.1/tests/test_variadic.py +189 -0
  39. strictcli-0.4.1/uv.lock +261 -0
  40. strictcli-0.1.0/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -31
  41. strictcli-0.1.0/.rlsbl/hashes.json +0 -11
  42. strictcli-0.1.0/.rlsbl/hooks/pre-release.sh +0 -31
  43. strictcli-0.1.0/.rlsbl/version +0 -1
  44. strictcli-0.1.0/CHANGELOG.md +0 -17
  45. strictcli-0.1.0/strictcli/__init__.py +0 -738
  46. strictcli-0.1.0/uv.lock +0 -79
  47. {strictcli-0.1.0 → strictcli-0.4.1}/.claude/settings.json +0 -0
  48. {strictcli-0.1.0 → strictcli-0.4.1}/.github/workflows/ci.yml +0 -0
  49. {strictcli-0.1.0 → strictcli-0.4.1}/.github/workflows/publish.yml +0 -0
  50. {strictcli-0.1.0 → strictcli-0.4.1}/.gitignore +0 -0
  51. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/.claude/settings.json +0 -0
  52. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
  53. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
  54. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/.gitignore +0 -0
  55. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
  56. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/CHANGELOG.md +0 -0
  57. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/CLAUDE.md +0 -0
  58. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/bases/LICENSE +0 -0
  59. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/config.json +0 -0
  60. {strictcli-0.1.0 → strictcli-0.4.1}/.rlsbl/hooks/post-release.sh +0 -0
  61. {strictcli-0.1.0 → strictcli-0.4.1}/CLAUDE.md +0 -0
  62. {strictcli-0.1.0 → strictcli-0.4.1}/LICENSE +0 -0
  63. {strictcli-0.1.0 → strictcli-0.4.1}/index.js +0 -0
  64. {strictcli-0.1.0 → strictcli-0.4.1}/postinstall.js +0 -0
  65. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_e2e.py +0 -0
  66. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_env.py +0 -0
  67. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_help.py +0 -0
  68. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_nesting.py +0 -0
  69. {strictcli-0.1.0 → strictcli-0.4.1}/tests/test_tags.py +0 -0
  70. {strictcli-0.1.0/todo → strictcli-0.4.1/todo/.defer}/deferred.md +0 -0
  71. {strictcli-0.1.0 → strictcli-0.4.1}/todo/.done/original-idea.md +0 -0
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ # This hook runs BEFORE built-in pre-release checks (tests, lint).
4
+ # Use it for setup tasks: starting services, setting env vars, etc.
5
+ # Built-in checks run after this hook. Custom validation goes in pre-release.sh.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ # Project-specific pre-release checks.
4
+ # Built-in checks (tests, lint) run automatically before this hook.
5
+ # Add custom validation here, e.g.:
6
+ # - Check for uncommitted documentation
7
+ # - Verify external service connectivity
8
+ # - Run integration tests not covered by the test suite
@@ -0,0 +1,17 @@
1
+ [forbidden-imports]
2
+ modules = [
3
+ "net/http",
4
+ "github.com/spf13/cobra",
5
+ "github.com/urfave/cli",
6
+ ]
7
+
8
+ [stdout]
9
+ enabled = true
10
+ ignore = []
11
+
12
+ [entry-point]
13
+ enabled = true
14
+ ignore = []
15
+
16
+ [files]
17
+ exclude = []
@@ -0,0 +1,19 @@
1
+ [forbidden-imports]
2
+ modules = [
3
+ "express",
4
+ "koa",
5
+ "hono",
6
+ "commander",
7
+ "yargs",
8
+ ]
9
+
10
+ [stdout]
11
+ enabled = true
12
+ ignore = []
13
+
14
+ [entry-point]
15
+ enabled = true
16
+ ignore = []
17
+
18
+ [files]
19
+ exclude = []
@@ -0,0 +1,25 @@
1
+ [forbidden-imports]
2
+ modules = [
3
+ "argparse",
4
+ "click",
5
+ "typer",
6
+ "flask",
7
+ "fastapi",
8
+ "django",
9
+ "uvicorn",
10
+ "granian",
11
+ "starlette",
12
+ "tornado",
13
+ "bottle",
14
+ ]
15
+
16
+ [stdout]
17
+ enabled = true
18
+ ignore = []
19
+
20
+ [entry-point]
21
+ enabled = true
22
+ ignore = []
23
+
24
+ [files]
25
+ exclude = []
@@ -0,0 +1 @@
1
+ 9f2ad6a550f949c15aeb8301b16a999601dd3a79
@@ -0,0 +1,29 @@
1
+ {"commits":["e0a6df151c905b3c76eeb316a3fd7ac5b6a089b0"],"user_facing":true,"description":"**Flag dependencies.** New `CoRequired` and `Requires` types for declaring flags that must appear together.","type":"feature"}
2
+ {"commits":["7f6271e85cbc114492ce93ddea99a429dfb9013f"],"user_facing":true,"description":"**Breaking: mutex groups always required.** Removed the `required` parameter from `MutexGroup`. All mutex groups now require exactly one flag to be provided.","type":"breaking"}
3
+ {"commits":["e10a387f59671585724eaf2dd1aaf821972f6535"],"user_facing":true,"description":"**Choices on global flags.** Global flags now validate choices correctly.","type":"fix"}
4
+ {"commits":["b22a3151e500f2ea222b3725d9e48788612b1dae"],"user_facing":true,"description":"**Repeatable global flags.** Global flags with `repeatable=True` now work correctly.","type":"fix"}
5
+ {"commits":["e466ca5a31eb36c36510648a1925c65ae8413d41"],"user_facing":true,"description":"**Strict int parsing.** Integer flags now enforce 64-bit signed range to match Go behavior.","type":"fix"}
6
+ {"commits":["0609e094510cdaab595e7739a610ffc2fc185c29"],"user_facing":true,"description":"**Strict int env parsing.** Integer environment variables reject leading/trailing whitespace.","type":"fix"}
7
+ {"commits":["5cd4e00ad971986972ea1a57e7c6e215736c95d0"],"user_facing":false}
8
+ {"commits":["375298bace19f63b02007830b4653b27d754bc2b"],"user_facing":false}
9
+ {"commits":["bdb6635975c3ee823a693992cb14cb3499feef01"],"user_facing":false}
10
+ {"commits":["ed0556d19196bacbe0ea06fd95055f36343fa1fe"],"user_facing":false}
11
+ {"commits":["21f89d9d6eae47a5d3a514be079ce781f74212fc"],"user_facing":false}
12
+ {"commits":["fdb5d5d1fe4b98d8477a8006f18ec2ea2548b4f0"],"user_facing":false}
13
+ {"commits":["0629fff5c56bcb5c853463b8c698b457abbd4448"],"user_facing":false}
14
+ {"commits":["aa6c1b18d05c998ced865efe0b012f808e656496"],"user_facing":false}
15
+ {"commits":["f7fae2f5bf16a495c049ae6d6e2e59d937502ef2"],"user_facing":false}
16
+ {"commits":["0e19e83e1c131064f213f9e3fb18d921d670d7b2","1189d6e0d4da96e3b0b2852ce9d6a21d538b43df","20dc0c0d94b7ad0ff37a2ce8dd8f4c26c3a07548","21b5554f5cd84f6f9d5eac72c3f0ae9ed845afff","226d01c195b637fa0fe4edd23a75a07fe1147a36","25f0796809e4205493801185dc1c9219c8b068ee","268bf54fde7ae45cea102a9fef0c0c3fcbdbf9b8","289e6b3f34f661b49b39f7d0d073ea2ae9d8c378","2b15ee2e74d92233423b80a6cb55b7fa7c47e549","2cbb123244025699dd3b0cf25cfff0aff16c4529","31a0e72913b545fec5aa507fd49a1893536d477e","328ae4e7e9f150afc19e9d1b8277553eb34eb64a","3867ffbdc9acbe41a3409d939174468290352988","3aef9cf2cd3236c0c9c10d97d54db9a902a40ed2","40bb93bab11d0d5c2dd1d98562e2359008467650","4218e8b593e820838445cc03e2e2749997cba323","4659be9bcda81789619e3e022220a91eff457542","49342b045dd3d01d56e6ef9e0a0a8965d18433b6","4b7a14bd0c4165eabfd8b16ced610924708db8e5","5023e27f9f0b966a2a1161286633667e9dfd35cf","55b94860aeab8434b0e2ac30ca5c882c91d4cce4","5b5d607839a3c0ad7b331090e926cff8f2ace6d9","5c5567868c7c1d480beda30aed15e7e1a78ee388","6cef2792a57ea909837001c3db9d28f814a79e4b","6f62a78ddd37ec10b12cd905d0dd485d0c685aa2","74f756f16ce39f5fe0af3f861daa39f18d3bd16b","79976b6181be3470ff1b735dfc6779fd576b1e25","87aedf0c193e5f1ce51ae608bbc01fb7d1f630db","95e062923e5dd46c87a2288fa4f6a2ca868fe18d","98b668367ae60906dc9a2d4d06e02bef9e8f87e7","98f62669f3d50b6318c7baefa443d673015e7947","a20d8d2b216575c5c6e560b2bc63de7ee7c16025","a6d2b866e1eca3396567edac6642fbbb11762ec4","a7bdec219a125413f2fbafe52bc9b25c13e19acd","a7eefcd43dbc990e6fa766014aabd2194d97d65c","a8b2fc22a0db5b5d73055acfdf37bbef22f2b4a6","af42e9e737e2e94a364418150453dca80174df47","af4661b3f8e73b31725817c2a315bdd6c71371e3","b1cd26b7e6fa6876bdab26cb84933d116f7375fe","b3d8d3a12716a3c8766478229d360b218d983193","b69001ce7cd9aa3f28ee41dcd4443c8d1f42a741","b6acb151fe21a6b2dda59401bb2c64666fc2fa06","b71309a870ffb4ab4b54a3c456cc03b461d6f8cf","b7bba07dc3e0844120ed45078dcd201e6aa99c1a","bb60c46c280314c75cdffd00efed03094e917b77","c0594a9c59260fa248248da6506122d102ccaa0f","c3d45c9df83749e02906ba204f5aba375aec2954","cddca60955874c28aea55c5fbd8fbbc7226757d1","cf62244db14493836965f40e90cd1899591ccf89","d0dad3b5b1005e399b79adfec813b630693eb50b","d122ed66d8027d365eea0ed1bd86bfdb3c94c1cf","d46cce43ba9691205013afe56647c4af31c1421c","d6916886e0fcb45f28d87fd5d9e48443d702002d","d6bd8e29e247cb3bd8bc3af9b3ce6a2baca19a32","d8b321f88d133814cf192386362200518e903624","daa861b2f2602379fd2904290f1738b6fd9dd85e","e3c4ace588a5af0313efd461d10a0776e739fb49","ed864c4afc0061f5b2dda2798b6c21ee3b831401","eeee6c3adc8814e656388fc2349bc8aa647099cc","ef215a20ecab6f7bdb42ffc7493dd37249630ec3","ef6a13bd8461cd1c6c00588e6429e06d94caa76a","ef83affdbd1a407b5ab585eb623a8ae61f337b67","ef93d7596919a012df5df9d23e2cb3f6e09db469","f44b05cbc2f1a314ce4a4139dcb4fa2eaf25b8e0","fb3d6aff6ec25cb70b662384b2af6a794a6c89ae"],"user_facing":false}
17
+ {"commits":["6234d6998039a796840f0c09331f10b6e331cbee"],"user_facing":false}
18
+ {"commits":["3407ab2f9b0a29cf14ade34969a2999f361c2a48","115e8b9a1628809ab45b727061012e34c730d6ae","1447ca50e48a7f444a2903f2f570dcdb3d838265","cef14219838b7a6b2c33e3568531ff6a689c73cb","08d2c54a392574eb29d7c39ffe40659100177e54","cfd0bf0e5109fa88526a4e576cb1afad6a5b2caf"],"user_facing":false}
19
+ {"commits":["02989af222b0ef454fb5f23c346909b454cc4a58","057e0650428fe3a94708775da6c2b496e3ec242a","06965deb7cfb651dec1d93a96b946c9fde72a425","06d07c3b92460036e75ea45056525d60df66bf2b","09e04cc1361417ce44b3de61fd04f8042e93acd2","0c189e587c6bfe1dedf7b4d94d749c522264d528","100cff7404034083b009b3c515a220f298033afa","10b203ba1c7b14136c9de6cab610a9178402f5f5","157be0dbd76c9f5df4dc82fa1b4086a79c12b677","1697195d4f392538754d94de2d1e4e4b32ce44bb","1c604b2653a4542da46a1d10e3ca436e5ac5af1c","22b4a29bd56f53ee07cf3f25efd3ecdfe45499ea","25477098827788b81f22da31ac182cc3ae1ae901","25d158d0b6b8c31d68e39ca2025469fc1cd0bcd3","325d7498db0c2b062c9b3095a500f0432724ae1c","32ba2ca2fe658812259301ba0b74ea488851e0c0","3f31bf5a43c2f1f5f6902bf0be89d38ed08fc4e0","43aa215fe38953afb3fd5978215a2e98791a9ed6","47bc9738a6c497108b9d4babadbf0c0a3e682041","47d7fb7d95d075c9e2f239b18678e5cfbd3068bd","4d7237a40ed75a94f1fb93f5cac97d468438a661","5b2990274865134a7bc9d0fb526b3effc078bcdb","60d75b6141e6369d99ad7100422387ad0bc6a938","6737ea79092428908c4636601ea15d3a98b199cb","69a93bd944c3ccf214759fa63ac2a033fe76a744","6d5b7cb04c2cfbaa281ba19c1d3925af5255712b","73e003abd21a7dfe3595960553d4dd7cb1c621c2","73f7a4fcdb981b512e32bfa7536f9aaf77362f7f","7e809c9d6fdf9482fe9ce3a90cfc0929bf30a8e1","8001ccf027053c6e2667c787f96949f56d08d111","822de144b38a8fd27a58d5317f2657d0e952aad4","83b42928ead62a7f5995bf314ed9648fff6d334d","83b847cf8be21180f9b8997ec0b83769741526b1","84d9171156e378592955565773105edf3c6c0f1d","884de6dbaa9b89a59a503b688e01c5a18d17cf09","8c0d6b6468dda685671b9a9b9729402e4e452942","9b0d4c9be1dfa3b6aef111250d2d8b1c1ed317b4","9b83cc0623e8a148c17c74acb34d34cbf17bf698","a45899cfaa3d29efdfefd286af11e5003abb6ac1","a71d8f6caa71f1c1dec9aee3cddf45fe02735017","ab9efef242c1e93f1b61fea1ea0c516e2044c329","b29406f7e55f00f081ff7167adcddd0817b6dd9e","b4c9a4d3835903c81c5f2cb4f864a36812365aed","bb6a4865330363a9bb85e2d610e1dceed94cdecc","bcf8262f1e3988789d7b520d22220ca2bcea85fe","c35c9799bc72b8e3c93223d2c5d6d8077298408a","c4748bca53a01a368a0cd6ff81e0643ced23df4f","c4797e7f03fd6d1f148fcda137ba838b2d77482c","c97cc754003935c96b5aac11d4dafbfed920e543","cee26601f6da8b8ce66834ba3f829031b9a6d869","cf35016fb4e2c3b6599ad8edbeec6e20d252a160","e490ab483da7bd5ba5be45d036bddd1225376ac0","ed2ce990e0db0a0d53c34ccedb7e384974dfdbc6","f3199dce3a8b53e08c689058c02fc21c530fea23","fb9c770686794b1c5e9998ddd581262fed1f849e"],"user_facing":false}
20
+ {"commits":["1b0d3803ca748658bf28cec5eae9926be6ea107d","377fb2dfe625c5b17949c57a983c94906aa10791"],"user_facing":false}
21
+ {"commits":["b52bc8020ca59efc3496a6ef5ce507531fbbaadc"],"user_facing":false}
22
+ {"commits":["4ab7d471f96e2580756aba4912c38ccf15afbbc7"],"user_facing":false}
23
+ {"commits":["80b72eacbc6ff0b8cfc78f832859f7ae19ebc930"],"user_facing":false}
24
+ {"commits":["2b11bc91db40f9a6d92ac233c678f5ec2549edbb","4ab7d471f96e2580756aba4912c38ccf15afbbc7","b52bc8020ca59efc3496a6ef5ce507531fbbaadc","1b0d3803ca748658bf28cec5eae9926be6ea107d","73f7a4fcdb981b512e32bfa7536f9aaf77362f7f","c97cc754003935c96b5aac11d4dafbfed920e543","3407ab2f9b0a29cf14ade34969a2999f361c2a48","115e8b9a1628809ab45b727061012e34c730d6ae","08d2c54a392574eb29d7c39ffe40659100177e54","0c189e587c6bfe1dedf7b4d94d749c522264d528","73e003abd21a7dfe3595960553d4dd7cb1c621c2","10b203ba1c7b14136c9de6cab610a9178402f5f5","47d7fb7d95d075c9e2f239b18678e5cfbd3068bd","60d75b6141e6369d99ad7100422387ad0bc6a938","cf35016fb4e2c3b6599ad8edbeec6e20d252a160","9b0d4c9be1dfa3b6aef111250d2d8b1c1ed317b4","fb9c770686794b1c5e9998ddd581262fed1f849e","02989af222b0ef454fb5f23c346909b454cc4a58","5b2990274865134a7bc9d0fb526b3effc078bcdb","100cff7404034083b009b3c515a220f298033afa"],"user_facing":false}
25
+ {"commits":["bb6a4865330363a9bb85e2d610e1dceed94cdecc","057e0650428fe3a94708775da6c2b496e3ec242a","6d5b7cb04c2cfbaa281ba19c1d3925af5255712b","b29406f7e55f00f081ff7167adcddd0817b6dd9e","7e809c9d6fdf9482fe9ce3a90cfc0929bf30a8e1","25d158d0b6b8c31d68e39ca2025469fc1cd0bcd3","884de6dbaa9b89a59a503b688e01c5a18d17cf09","822de144b38a8fd27a58d5317f2657d0e952aad4","f3199dce3a8b53e08c689058c02fc21c530fea23","157be0dbd76c9f5df4dc82fa1b4086a79c12b677","cee26601f6da8b8ce66834ba3f829031b9a6d869","06965deb7cfb651dec1d93a96b946c9fde72a425","69a93bd944c3ccf214759fa63ac2a033fe76a744","83b847cf8be21180f9b8997ec0b83769741526b1","06d07c3b92460036e75ea45056525d60df66bf2b","9b83cc0623e8a148c17c74acb34d34cbf17bf698","b4c9a4d3835903c81c5f2cb4f864a36812365aed"],"user_facing":false}
26
+ {"commits":["c35c9799bc72b8e3c93223d2c5d6d8077298408a","8001ccf027053c6e2667c787f96949f56d08d111","3f31bf5a43c2f1f5f6902bf0be89d38ed08fc4e0","32ba2ca2fe658812259301ba0b74ea488851e0c0","25477098827788b81f22da31ac182cc3ae1ae901","c4748bca53a01a368a0cd6ff81e0643ced23df4f","8c0d6b6468dda685671b9a9b9729402e4e452942","ed2ce990e0db0a0d53c34ccedb7e384974dfdbc6","ab9efef242c1e93f1b61fea1ea0c516e2044c329","09e04cc1361417ce44b3de61fd04f8042e93acd2","c4797e7f03fd6d1f148fcda137ba838b2d77482c","80b72eacbc6ff0b8cfc78f832859f7ae19ebc930"],"user_facing":false}
27
+ {"commits":["137b53f5a8c191171b59e84428d0b12ae686f7ab"],"user_facing":false}
28
+ {"commits":["bc4433771ee3b77eaae4360ce2ab9169cc04e27f"],"user_facing":false}
29
+ {"commits":["fc32e72c050e5119d073b82ea7ad12fb62da343c"],"user_facing":false}
@@ -0,0 +1,16 @@
1
+ ## 0.4.0
2
+
3
+ ### Breaking
4
+
5
+ - **Breaking: mutex groups always required.** Removed the `required` parameter from `MutexGroup`. All mutex groups now require exactly one flag to be provided.
6
+
7
+ ### Features
8
+
9
+ - **Flag dependencies.** New `CoRequired` and `Requires` types for declaring flags that must appear together.
10
+
11
+ ### Fixes
12
+
13
+ - **Choices on global flags.** Global flags now validate choices correctly.
14
+ - **Repeatable global flags.** Global flags with `repeatable=True` now work correctly.
15
+ - **Strict int parsing.** Integer flags now enforce 64-bit signed range to match Go behavior.
16
+ - **Strict int env parsing.** Integer environment variables reject leading/trailing whitespace.
@@ -0,0 +1,4 @@
1
+ {"commits":["1d4c04f6dd477ee11ead0c712a6fe1d16cdfe6bb","d113fc263470557d4614eacd2ec21e49e11d5419","40255eb12d485b7a36a382b34c8cd09f41e34a1c","8eca2aedc3642bd79d01420fb2c88b9b5e1df493"],"user_facing":false}
2
+ {"commits":["8eca2aedc3642bd79d01420fb2c88b9b5e1df493","5c99daf541a3983088081b3736b7cd3e197c5d65","5e924f2ffe83c76d54c3b5e9da736f24325ed0a0"],"user_facing":false}
3
+ {"commits":["430e30bb4e48a6dd80099185f03eb866a14e02c8","776673f97f30f4e1241a42b1334b285db46afde4","93111cb1440ce3953805e33935021a1bd39b78b7","bd63ba30698098272031e7944d879972c6944d51"],"user_facing":false}
4
+ {"commits":["8eca2aedc3642bd79d01420fb2c88b9b5e1df493"],"user_facing":true,"description":"**CI publish fix.** Fixed publish workflow for GitHub Actions compatibility.","type":"fix"}
@@ -0,0 +1,5 @@
1
+ ## 0.4.1
2
+
3
+ ### Fixes
4
+
5
+ - **CI publish fix.** Fixed publish workflow for GitHub Actions compatibility.
File without changes
@@ -0,0 +1,15 @@
1
+ {
2
+ ".github/workflows/ci.yml": "d1da13d13914be16b2ecafe67afc62d611dc8dcc4ebc9db2befd84c2d6296ab2",
3
+ ".github/workflows/publish.yml": "5f4ac1bf0bdd4c70041e3d2502efaae28d29eca7575e8ff12fdaad0d3af5b17a",
4
+ "CHANGELOG.md": "7a6ec46141007c18090a0ff325e2dd68cd51588c4e0b5af7b580365e5eaaca85",
5
+ ".gitignore": "c89d76c6c43e7f0897b3472a15b7c0103e0be5b3a04c2b44e585fa48bdcda2bb",
6
+ "LICENSE": "e958892abc1dd5d991fca6d528e695d335f25773d373d2e0be5f4a9507d8f8d5",
7
+ "CLAUDE.md": "7294b791570185dc31020dadb092b5b79681ba8ee932fe9a3974e27eaae56c4f",
8
+ ".rlsbl/hooks/pre-release.sh": "b2dc17c243d0b1a2c1e23c1c25db6f94878596df81dc76c41b32d95f740a7d44",
9
+ ".rlsbl/hooks/post-release.sh": "b455f8511e0b2655509ecf5dcb0ab7da5bb7c961f47910ff8e00cab5bd51f833",
10
+ ".claude/settings.json": "78922a784ee78e9e50587e93628cd3b9d4dfbe49087adc4514e6781cea38cbb9",
11
+ ".rlsbl/hooks/pre-checks.sh": "60c57d4563263124530e6f33aca77550ea2161ad3b33b3ba6ad1c03fea9eb6e2",
12
+ ".rlsbl/lint/python.toml": "9cfbcef2e010d5fad243437bf2fd8df54a1fae70ee0762f9d11da70fe207501c",
13
+ ".rlsbl/lint/go.toml": "807d5cf760baad6d571a5bfd43cb163efe356f7462ba9f1918d72de45f62339f",
14
+ ".rlsbl/lint/npm.toml": "baa36014e65923d8cc5c8b83c77fa651da79351627570476402da66840027645"
15
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ # This hook runs BEFORE built-in pre-release checks (tests, lint).
4
+ # Use it for setup tasks: starting services, setting env vars, etc.
5
+ # Built-in checks run after this hook. Custom validation goes in pre-release.sh.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ # Project-specific pre-release checks.
4
+ # Built-in checks (tests, lint) run automatically before this hook.
5
+ # Add custom validation here, e.g.:
6
+ # - Check for uncommitted documentation
7
+ # - Verify external service connectivity
8
+ # - Run integration tests not covered by the test suite
@@ -0,0 +1,17 @@
1
+ [forbidden-imports]
2
+ modules = [
3
+ "net/http",
4
+ "github.com/spf13/cobra",
5
+ "github.com/urfave/cli",
6
+ ]
7
+
8
+ [stdout]
9
+ enabled = true
10
+ ignore = []
11
+
12
+ [entry-point]
13
+ enabled = true
14
+ ignore = []
15
+
16
+ [files]
17
+ exclude = []
@@ -0,0 +1,19 @@
1
+ [forbidden-imports]
2
+ modules = [
3
+ "express",
4
+ "koa",
5
+ "hono",
6
+ "commander",
7
+ "yargs",
8
+ ]
9
+
10
+ [stdout]
11
+ enabled = true
12
+ ignore = []
13
+
14
+ [entry-point]
15
+ enabled = true
16
+ ignore = []
17
+
18
+ [files]
19
+ exclude = []
@@ -0,0 +1,25 @@
1
+ [forbidden-imports]
2
+ modules = [
3
+ "argparse",
4
+ "click",
5
+ "typer",
6
+ "flask",
7
+ "fastapi",
8
+ "django",
9
+ "uvicorn",
10
+ "granian",
11
+ "starlette",
12
+ "tornado",
13
+ "bottle",
14
+ ]
15
+
16
+ [stdout]
17
+ enabled = true
18
+ ignore = []
19
+
20
+ [entry-point]
21
+ enabled = true
22
+ ignore = []
23
+
24
+ [files]
25
+ exclude = []
@@ -0,0 +1 @@
1
+ 0.31.0
@@ -0,0 +1,26 @@
1
+ <!-- Generated by rlsbl from .rlsbl/changes/ — do not edit -->
2
+
3
+ # Changelog
4
+
5
+ ## 0.4.1
6
+
7
+ ### Fixes
8
+
9
+ - **CI publish fix.** Fixed publish workflow for GitHub Actions compatibility.
10
+
11
+ ## 0.4.0
12
+
13
+ ### Breaking
14
+
15
+ - **Breaking: mutex groups always required.** Removed the `required` parameter from `MutexGroup`. All mutex groups now require exactly one flag to be provided.
16
+
17
+ ### Features
18
+
19
+ - **Flag dependencies.** New `CoRequired` and `Requires` types for declaring flags that must appear together.
20
+
21
+ ### Fixes
22
+
23
+ - **Choices on global flags.** Global flags now validate choices correctly.
24
+ - **Repeatable global flags.** Global flags with `repeatable=True` now work correctly.
25
+ - **Strict int parsing.** Integer flags now enforce 64-bit signed range to match Go behavior.
26
+ - **Strict int env parsing.** Integer environment variables reject leading/trailing whitespace.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strictcli
3
- Version: 0.1.0
3
+ Version: 0.4.1
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
@@ -246,6 +246,99 @@ def status(token, insecure):
246
246
 
247
247
  Both commands now have `--token` and `--insecure` flags. Tag flags appear in help output and are parsed like any other flag.
248
248
 
249
+ ## Mutex Groups
250
+
251
+ Mutex groups declare mutually exclusive flags -- exactly one flag from the group must be provided. If the user provides more than one, or provides none, the parser errors.
252
+
253
+ ```python
254
+ @app.command("log", help="show logs", mutex=[
255
+ strictcli.MutexGroup(flags=[
256
+ strictcli.Flag(name="verbose", type=bool, help="verbose output"),
257
+ strictcli.Flag(name="quiet", type=bool, help="quiet output"),
258
+ ]),
259
+ ])
260
+ def log(verbose, quiet):
261
+ if verbose:
262
+ print("showing all logs")
263
+ elif quiet:
264
+ print("showing errors only")
265
+ ```
266
+
267
+ If both flags are provided:
268
+
269
+ ```
270
+ $ myapp log --verbose --quiet
271
+ error: --verbose and --quiet are mutually exclusive
272
+ try 'myapp --help'
273
+ ```
274
+
275
+ If neither flag is provided:
276
+
277
+ ```
278
+ $ myapp log
279
+ error: one of --verbose, --quiet is required
280
+ try 'myapp --help'
281
+ ```
282
+
283
+ Mutex group flags appear in a separate section in help output:
284
+
285
+ ```
286
+ $ myapp log --help
287
+ myapp log -- show logs
288
+
289
+ Flags (mutually exclusive):
290
+ --verbose, --no-verbose verbose output [default: false]
291
+ --quiet, --no-quiet quiet output [default: false]
292
+ ```
293
+
294
+ Flags inside a mutex group follow the same rules as regular flags (short aliases, env vars, types), but they are not declared with `@strictcli.flag` -- they live inside the `MutexGroup`.
295
+
296
+ ## Flag Dependencies
297
+
298
+ Flag dependencies enforce relationships between flags. Two types are available:
299
+
300
+ - `CoRequired(flags=["output", "format"])` -- all listed flags must be provided together, or none. Providing some but not all is an error.
301
+ - `Requires(flag="verbose", depends_on="output")` -- if `--verbose` is provided, `--output` must also be provided. But `--output` can appear alone.
302
+
303
+ ```python
304
+ @app.command("export", help="export data", dependencies=[
305
+ strictcli.CoRequired(flags=["output", "format"]),
306
+ strictcli.Requires(flag="verbose", depends_on="output"),
307
+ ])
308
+ @strictcli.flag("output", short="o", type=str, help="output file path", default="")
309
+ @strictcli.flag("format", type=str, help="output format (json, csv)", default="")
310
+ @strictcli.flag("verbose", type=bool, help="show export progress")
311
+ def export(output, format, verbose):
312
+ if output:
313
+ print(f"exporting to {output} as {format}")
314
+ if verbose:
315
+ print("progress: 100%")
316
+ ```
317
+
318
+ If `--output` is provided without `--format`:
319
+
320
+ ```
321
+ $ myapp export --output data.csv
322
+ error: flags --output, --format must be used together
323
+ try 'myapp --help'
324
+ ```
325
+
326
+ If `--verbose` is provided without `--output`:
327
+
328
+ ```
329
+ $ myapp export --verbose
330
+ error: flag '--verbose' requires '--output'
331
+ try 'myapp --help'
332
+ ```
333
+
334
+ Notes:
335
+
336
+ - Flag names in dependencies are strings (names without `--` prefix).
337
+ - `CoRequired` needs at least 2 flags.
338
+ - `Requires` is unidirectional -- use two `Requires` for bidirectional dependency.
339
+ - Checked after environment variable resolution, before defaults are applied.
340
+ - Can be combined with mutex groups.
341
+
249
342
  ## Help Output
250
343
 
251
344
  Help is auto-generated at three levels. Pass `--help` or `-h` at any level, or invoke the app with no arguments.
@@ -228,6 +228,99 @@ def status(token, insecure):
228
228
 
229
229
  Both commands now have `--token` and `--insecure` flags. Tag flags appear in help output and are parsed like any other flag.
230
230
 
231
+ ## Mutex Groups
232
+
233
+ Mutex groups declare mutually exclusive flags -- exactly one flag from the group must be provided. If the user provides more than one, or provides none, the parser errors.
234
+
235
+ ```python
236
+ @app.command("log", help="show logs", mutex=[
237
+ strictcli.MutexGroup(flags=[
238
+ strictcli.Flag(name="verbose", type=bool, help="verbose output"),
239
+ strictcli.Flag(name="quiet", type=bool, help="quiet output"),
240
+ ]),
241
+ ])
242
+ def log(verbose, quiet):
243
+ if verbose:
244
+ print("showing all logs")
245
+ elif quiet:
246
+ print("showing errors only")
247
+ ```
248
+
249
+ If both flags are provided:
250
+
251
+ ```
252
+ $ myapp log --verbose --quiet
253
+ error: --verbose and --quiet are mutually exclusive
254
+ try 'myapp --help'
255
+ ```
256
+
257
+ If neither flag is provided:
258
+
259
+ ```
260
+ $ myapp log
261
+ error: one of --verbose, --quiet is required
262
+ try 'myapp --help'
263
+ ```
264
+
265
+ Mutex group flags appear in a separate section in help output:
266
+
267
+ ```
268
+ $ myapp log --help
269
+ myapp log -- show logs
270
+
271
+ Flags (mutually exclusive):
272
+ --verbose, --no-verbose verbose output [default: false]
273
+ --quiet, --no-quiet quiet output [default: false]
274
+ ```
275
+
276
+ Flags inside a mutex group follow the same rules as regular flags (short aliases, env vars, types), but they are not declared with `@strictcli.flag` -- they live inside the `MutexGroup`.
277
+
278
+ ## Flag Dependencies
279
+
280
+ Flag dependencies enforce relationships between flags. Two types are available:
281
+
282
+ - `CoRequired(flags=["output", "format"])` -- all listed flags must be provided together, or none. Providing some but not all is an error.
283
+ - `Requires(flag="verbose", depends_on="output")` -- if `--verbose` is provided, `--output` must also be provided. But `--output` can appear alone.
284
+
285
+ ```python
286
+ @app.command("export", help="export data", dependencies=[
287
+ strictcli.CoRequired(flags=["output", "format"]),
288
+ strictcli.Requires(flag="verbose", depends_on="output"),
289
+ ])
290
+ @strictcli.flag("output", short="o", type=str, help="output file path", default="")
291
+ @strictcli.flag("format", type=str, help="output format (json, csv)", default="")
292
+ @strictcli.flag("verbose", type=bool, help="show export progress")
293
+ def export(output, format, verbose):
294
+ if output:
295
+ print(f"exporting to {output} as {format}")
296
+ if verbose:
297
+ print("progress: 100%")
298
+ ```
299
+
300
+ If `--output` is provided without `--format`:
301
+
302
+ ```
303
+ $ myapp export --output data.csv
304
+ error: flags --output, --format must be used together
305
+ try 'myapp --help'
306
+ ```
307
+
308
+ If `--verbose` is provided without `--output`:
309
+
310
+ ```
311
+ $ myapp export --verbose
312
+ error: flag '--verbose' requires '--output'
313
+ try 'myapp --help'
314
+ ```
315
+
316
+ Notes:
317
+
318
+ - Flag names in dependencies are strings (names without `--` prefix).
319
+ - `CoRequired` needs at least 2 flags.
320
+ - `Requires` is unidirectional -- use two `Requires` for bidirectional dependency.
321
+ - Checked after environment variable resolution, before defaults are applied.
322
+ - Can be combined with mutex groups.
323
+
231
324
  ## Help Output
232
325
 
233
326
  Help is auto-generated at three levels. Pass `--help` or `-h` at any level, or invoke the app with no arguments.
@@ -1,11 +1,11 @@
1
1
  {
2
- "name": "excli",
2
+ "name": "strictcli",
3
3
  "version": "0.1.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
- "name": "excli",
8
+ "name": "strictcli",
9
9
  "version": "0.1.0",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strictcli",
3
- "version": "0.1.0",
3
+ "version": "0.4.1",
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.1.0"
7
+ version = "0.4.1"
8
8
  description = "A strict, zero-dependency CLI framework for Python"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -20,7 +20,7 @@ classifiers = [
20
20
  ]
21
21
 
22
22
  [dependency-groups]
23
- dev = ["pytest"]
23
+ dev = ["pytest", "allpairspy", "jsonschema"]
24
24
 
25
25
  [tool.pytest.ini_options]
26
26
  testpaths = ["tests"]