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.
- {toolrack_cli-0.1.0/src/toolrack_cli.egg-info → toolrack_cli-0.3.0}/PKG-INFO +79 -4
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/README.md +78 -3
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/pyproject.toml +4 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/__init__.py +1 -1
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/cli.py +255 -139
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/completion.py +24 -0
- toolrack_cli-0.3.0/src/toolrack/doctor.py +126 -0
- toolrack_cli-0.3.0/src/toolrack/pytest_plugin.py +55 -0
- toolrack_cli-0.3.0/src/toolrack/scaffold.py +93 -0
- toolrack_cli-0.3.0/src/toolrack/shells.py +73 -0
- toolrack_cli-0.3.0/src/toolrack/sidecar.py +75 -0
- toolrack_cli-0.3.0/src/toolrack/testing.py +262 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0/src/toolrack_cli.egg-info}/PKG-INFO +79 -4
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/SOURCES.txt +10 -1
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/entry_points.txt +3 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/tests/test_cli.py +77 -0
- toolrack_cli-0.3.0/tests/test_init_doctor.py +109 -0
- toolrack_cli-0.3.0/tests/test_testing.py +130 -0
- toolrack_cli-0.3.0/tests/test_validate.py +106 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/LICENSE +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/setup.cfg +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/__main__.py +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/entrypoint.py +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack/runtime.py +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/dependency_links.txt +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/requires.txt +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/src/toolrack_cli.egg-info/top_level.txt +0 -0
- {toolrack_cli-0.1.0 → toolrack_cli-0.3.0}/tests/test_completion.py +0 -0
- {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.
|
|
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
|
+
[](https://pypi.org/project/toolrack-cli/)
|
|
37
|
+
[](https://github.com/anfit/toolrack/actions/workflows/unit-tests.yml)
|
|
38
|
+
|
|
36
39
|

|
|
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
|
|
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
|
|
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
|
+
[](https://pypi.org/project/toolrack-cli/)
|
|
11
|
+
[](https://github.com/anfit/toolrack/actions/workflows/unit-tests.yml)
|
|
12
|
+
|
|
10
13
|

|
|
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
|
|
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
|
|
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
|
|