toolrack-cli 0.1.0__tar.gz → 0.3.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.
Files changed (29) hide show
  1. {toolrack_cli-0.1.0/src/toolrack_cli.egg-info → toolrack_cli-0.3.0}/PKG-INFO +79 -4
  2. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/README.md +78 -3
  3. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/pyproject.toml +4 -0
  4. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/__init__.py +1 -1
  5. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/cli.py +255 -139
  6. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/completion.py +24 -0
  7. toolrack_cli-0.3.0/src/toolrack/doctor.py +126 -0
  8. toolrack_cli-0.3.0/src/toolrack/pytest_plugin.py +55 -0
  9. toolrack_cli-0.3.0/src/toolrack/scaffold.py +93 -0
  10. toolrack_cli-0.3.0/src/toolrack/shells.py +73 -0
  11. toolrack_cli-0.3.0/src/toolrack/sidecar.py +75 -0
  12. toolrack_cli-0.3.0/src/toolrack/testing.py +262 -0
  13. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0/src/toolrack_cli.egg-info}/PKG-INFO +79 -4
  14. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/SOURCES.txt +10 -1
  15. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/entry_points.txt +3 -0
  16. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/tests/test_cli.py +77 -0
  17. toolrack_cli-0.3.0/tests/test_init_doctor.py +109 -0
  18. toolrack_cli-0.3.0/tests/test_testing.py +130 -0
  19. toolrack_cli-0.3.0/tests/test_validate.py +106 -0
  20. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/LICENSE +0 -0
  21. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/setup.cfg +0 -0
  22. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/__main__.py +0 -0
  23. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/entrypoint.py +0 -0
  24. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/runtime.py +0 -0
  25. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/dependency_links.txt +0 -0
  26. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/requires.txt +0 -0
  27. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/top_level.txt +0 -0
  28. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/tests/test_completion.py +0 -0
  29. {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/tests/test_cross_shell.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolrack-cli
3
- Version: 0.1.0
3
+ Version: 0.3.0
4
4
  Summary: Turn a folder of small scripts plus YAML sidecars into one typed, completable CLI
5
5
  Author: Jan Chimiak
6
6
  License-Expression: MIT
@@ -33,6 +33,9 @@ and builds a typed Click CLI at runtime.
33
33
  If you want the starter repository that uses this engine, see
34
34
  [`toolrack-template`](https://github.com/anfit/toolrack-template).
35
35
 
36
+ [![PyPI](https://img.shields.io/pypi/v/toolrack-cli)](https://pypi.org/project/toolrack-cli/)
37
+ [![Unit tests](https://github.com/anfit/toolrack/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/anfit/toolrack/actions/workflows/unit-tests.yml)
38
+
36
39
  ![Animated toolrack walkthrough: register, discover, and run scripts](docs/assets/toolrack-demo.gif)
37
40
 
38
41
  ## Quickstart
@@ -127,10 +130,72 @@ Which also makes the AI prompt much nicer:
127
130
 
128
131
  > Hey AI, make me one like this, but mauve.
129
132
 
133
+ ## Testing Your Tools
134
+
135
+ Installing `toolrack-cli` also gives your test suite a pytest plugin. It runs the
136
+ real CLI in a subprocess against a repository, so tests cover what users run:
137
+ sidecar parsing, argument mapping, exit codes and the script itself. Python,
138
+ Bash and SQL scripts are all supported.
139
+
140
+ **Check the whole repo in CI.** `core validate` is read-only and exits non-zero
141
+ on a missing script or sidecar, an invalid sidecar, a bad `aliases.cfg`, or two
142
+ scripts that map to the same command. Unregistered sidecar pairs and a stale
143
+ cache are warnings; `--strict` makes them failures.
144
+
145
+ ```sh
146
+ my core validate --strict
147
+ ```
148
+
149
+ **Or from pytest**, against your real repo (`toolrack_project`) or a throwaway
150
+ one (`toolrack_repo`):
151
+
152
+ ```python
153
+ def test_repo_is_valid(toolrack_project):
154
+ toolrack_project.validate(strict=True) # AssertionError lists every problem
155
+
156
+ def test_python_tool(toolrack_repo):
157
+ toolrack_repo.add_script(
158
+ "greet/hello.py",
159
+ "import sys\nprint('hi', sys.argv[2])\n",
160
+ {"description": "Say hi.", "args": [{"name": "name", "required": True}]},
161
+ )
162
+ assert toolrack_repo.run("greet", "hello", "--name", "Ada").check().stdout == "hi Ada\n"
163
+
164
+ def test_bash_tool(toolrack_repo, toolrack_require_bash): # skips without bash
165
+ toolrack_repo.add_script("ops/fail.sh", "exit 3\n", {"description": "Fails."})
166
+ assert toolrack_repo.run("ops", "fail").returncode == 3
167
+
168
+ def test_sql_tool(toolrack_repo, toolrack_require_posix): # no database needed
169
+ psql = toolrack_repo.stub_executable("psql", record_env=("PGDATABASE",))
170
+ script = toolrack_repo.add_script("db/ping.sql", "SELECT 1;", {"description": "Ping."})
171
+ toolrack_repo.run("db", "ping", env={"PGDATABASE": "dev"}).check()
172
+ assert psql.calls()[0]["argv"] == ["-f", str(script)]
173
+ ```
174
+
175
+ SQL scripts run as `psql -f <file>`, so `stub_executable` puts a recording fake
176
+ `psql` first on `PATH` instead of needing a database. It works on POSIX hosts
177
+ only. `ToolrackRepo` is in `toolrack.testing` if you prefer to use it without
178
+ the fixtures.
179
+
180
+ ## Migrating From a Checked-Out toolrack
181
+
182
+ If you installed the engine editable from a clone (`pip install -e path/to/toolrack`,
183
+ distribution name `toolrack`), switch your scripts repo to the PyPI release:
184
+
185
+ ```sh
186
+ python3 ./sync_toolrack.py # refresh setup_toolrack.py
187
+ python3 ./setup_toolrack.py --yes --force --cli-name <your-command>
188
+ ```
189
+
190
+ Setup removes the old editable install, installs `toolrack-cli`, rewrites the
191
+ wrappers, and regenerates completion. Full steps, plus the manual route, are in
192
+ the [toolrack-template README](https://github.com/anfit/toolrack-template#migrating-from-a-checked-out-toolrack).
193
+
130
194
  ## Deployment Model
131
195
 
132
- `toolrack` is meant to be installed into a scripts repository and launched
133
- through a repo-local wrapper in `bin/`.
196
+ `toolrack` is meant to be installed into a scripts repository's virtualenv
197
+ (`pip install toolrack-cli`) and launched through a repo-local wrapper in `bin/`.
198
+ The PyPI distribution is `toolrack-cli`; the package and command are `toolrack`.
134
199
 
135
200
  The wrapper is responsible for:
136
201
 
@@ -157,6 +222,13 @@ Defaults:
157
222
  - `core refresh-cache`: rebuild the cached command metadata next to `.toolrack`
158
223
  - `core list`: show registry entries and sidecar status
159
224
  - `core install-completion <shell>`: print shell completion source
225
+ - `core validate [--strict]`: read-only repository check for CI (see [Testing Your Tools](#testing-your-tools))
226
+ - `core init [path] [--no-example]`: create a minimal scripts repository; never overwrites existing files
227
+ - `core doctor`: diagnose the installation and setup (legacy `toolrack` install shadowing `toolrack-cli`,
228
+ missing `bash` or `psql` for registered scripts, command not on `PATH`, validation errors); exits 1 on failures
229
+
230
+ Starting without the template: `pip install toolrack-cli`, then
231
+ `python -m toolrack core init my-tools` and `cd my-tools`.
160
232
 
161
233
  ## Scripts Repo Contract
162
234
 
@@ -189,8 +261,11 @@ For a starter repository layout, use
189
261
 
190
262
  Completion is answered from `.toolrack.cache.json` without importing Click, so
191
263
  <TAB> stays fast; anything the fast path does not model exactly falls back to
192
- Click. `core install-completion bash` prints a script that calls the Python
264
+ Click. `core install-completion <shell>` prints a script that calls the Python
193
265
  interpreter directly and falls back to the wrapper if that interpreter moves.
266
+ This applies to bash, zsh and fish; the zsh and fish scripts are covered by
267
+ string-level tests only, not exercised in a real zsh or fish, so report any
268
+ problems.
194
269
 
195
270
  ## Development
196
271
 
@@ -7,6 +7,9 @@ and builds a typed Click CLI at runtime.
7
7
  If you want the starter repository that uses this engine, see
8
8
  [`toolrack-template`](https://github.com/anfit/toolrack-template).
9
9
 
10
+ [![PyPI](https://img.shields.io/pypi/v/toolrack-cli)](https://pypi.org/project/toolrack-cli/)
11
+ [![Unit tests](https://github.com/anfit/toolrack/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/anfit/toolrack/actions/workflows/unit-tests.yml)
12
+
10
13
  ![Animated toolrack walkthrough: register, discover, and run scripts](docs/assets/toolrack-demo.gif)
11
14
 
12
15
  ## Quickstart
@@ -101,10 +104,72 @@ Which also makes the AI prompt much nicer:
101
104
 
102
105
  > Hey AI, make me one like this, but mauve.
103
106
 
107
+ ## Testing Your Tools
108
+
109
+ Installing `toolrack-cli` also gives your test suite a pytest plugin. It runs the
110
+ real CLI in a subprocess against a repository, so tests cover what users run:
111
+ sidecar parsing, argument mapping, exit codes and the script itself. Python,
112
+ Bash and SQL scripts are all supported.
113
+
114
+ **Check the whole repo in CI.** `core validate` is read-only and exits non-zero
115
+ on a missing script or sidecar, an invalid sidecar, a bad `aliases.cfg`, or two
116
+ scripts that map to the same command. Unregistered sidecar pairs and a stale
117
+ cache are warnings; `--strict` makes them failures.
118
+
119
+ ```sh
120
+ my core validate --strict
121
+ ```
122
+
123
+ **Or from pytest**, against your real repo (`toolrack_project`) or a throwaway
124
+ one (`toolrack_repo`):
125
+
126
+ ```python
127
+ def test_repo_is_valid(toolrack_project):
128
+ toolrack_project.validate(strict=True) # AssertionError lists every problem
129
+
130
+ def test_python_tool(toolrack_repo):
131
+ toolrack_repo.add_script(
132
+ "greet/hello.py",
133
+ "import sys\nprint('hi', sys.argv[2])\n",
134
+ {"description": "Say hi.", "args": [{"name": "name", "required": True}]},
135
+ )
136
+ assert toolrack_repo.run("greet", "hello", "--name", "Ada").check().stdout == "hi Ada\n"
137
+
138
+ def test_bash_tool(toolrack_repo, toolrack_require_bash): # skips without bash
139
+ toolrack_repo.add_script("ops/fail.sh", "exit 3\n", {"description": "Fails."})
140
+ assert toolrack_repo.run("ops", "fail").returncode == 3
141
+
142
+ def test_sql_tool(toolrack_repo, toolrack_require_posix): # no database needed
143
+ psql = toolrack_repo.stub_executable("psql", record_env=("PGDATABASE",))
144
+ script = toolrack_repo.add_script("db/ping.sql", "SELECT 1;", {"description": "Ping."})
145
+ toolrack_repo.run("db", "ping", env={"PGDATABASE": "dev"}).check()
146
+ assert psql.calls()[0]["argv"] == ["-f", str(script)]
147
+ ```
148
+
149
+ SQL scripts run as `psql -f <file>`, so `stub_executable` puts a recording fake
150
+ `psql` first on `PATH` instead of needing a database. It works on POSIX hosts
151
+ only. `ToolrackRepo` is in `toolrack.testing` if you prefer to use it without
152
+ the fixtures.
153
+
154
+ ## Migrating From a Checked-Out toolrack
155
+
156
+ If you installed the engine editable from a clone (`pip install -e path/to/toolrack`,
157
+ distribution name `toolrack`), switch your scripts repo to the PyPI release:
158
+
159
+ ```sh
160
+ python3 ./sync_toolrack.py # refresh setup_toolrack.py
161
+ python3 ./setup_toolrack.py --yes --force --cli-name <your-command>
162
+ ```
163
+
164
+ Setup removes the old editable install, installs `toolrack-cli`, rewrites the
165
+ wrappers, and regenerates completion. Full steps, plus the manual route, are in
166
+ the [toolrack-template README](https://github.com/anfit/toolrack-template#migrating-from-a-checked-out-toolrack).
167
+
104
168
  ## Deployment Model
105
169
 
106
- `toolrack` is meant to be installed into a scripts repository and launched
107
- through a repo-local wrapper in `bin/`.
170
+ `toolrack` is meant to be installed into a scripts repository's virtualenv
171
+ (`pip install toolrack-cli`) and launched through a repo-local wrapper in `bin/`.
172
+ The PyPI distribution is `toolrack-cli`; the package and command are `toolrack`.
108
173
 
109
174
  The wrapper is responsible for:
110
175
 
@@ -131,6 +196,13 @@ Defaults:
131
196
  - `core refresh-cache`: rebuild the cached command metadata next to `.toolrack`
132
197
  - `core list`: show registry entries and sidecar status
133
198
  - `core install-completion <shell>`: print shell completion source
199
+ - `core validate [--strict]`: read-only repository check for CI (see [Testing Your Tools](#testing-your-tools))
200
+ - `core init [path] [--no-example]`: create a minimal scripts repository; never overwrites existing files
201
+ - `core doctor`: diagnose the installation and setup (legacy `toolrack` install shadowing `toolrack-cli`,
202
+ missing `bash` or `psql` for registered scripts, command not on `PATH`, validation errors); exits 1 on failures
203
+
204
+ Starting without the template: `pip install toolrack-cli`, then
205
+ `python -m toolrack core init my-tools` and `cd my-tools`.
134
206
 
135
207
  ## Scripts Repo Contract
136
208
 
@@ -163,8 +235,11 @@ For a starter repository layout, use
163
235
 
164
236
  Completion is answered from `.toolrack.cache.json` without importing Click, so
165
237
  <TAB> stays fast; anything the fast path does not model exactly falls back to
166
- Click. `core install-completion bash` prints a script that calls the Python
238
+ Click. `core install-completion <shell>` prints a script that calls the Python
167
239
  interpreter directly and falls back to the wrapper if that interpreter moves.
240
+ This applies to bash, zsh and fish; the zsh and fish scripts are covered by
241
+ string-level tests only, not exercised in a real zsh or fish, so report any
242
+ problems.
168
243
 
169
244
  ## Development
170
245
 
@@ -39,6 +39,10 @@ dev = [
39
39
  [project.scripts]
40
40
  toolrack = "toolrack.entrypoint:main"
41
41
 
42
+ # Fixtures for testing your own scripts repo; inert unless a test requests them.
43
+ [project.entry-points.pytest11]
44
+ toolrack = "toolrack.pytest_plugin"
45
+
42
46
  [tool.setuptools.dynamic]
43
47
  version = { attr = "toolrack.__version__" }
44
48
 
@@ -1,3 +1,3 @@
1
1
  """toolrack - typed dispatcher for a user-owned scripts repository."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.3.0"