Skip to content

Commit e05d13b

Browse files
committed
Make the CLI robust at its edges
Config saving round-trips any input, the update check understands pre-releases, non-interactive runs fail safely on a dirty tree, setup and test regain the scriptability and filtering users had before, and every command has CLI-level test coverage. - save_config uses a TOML writer, so quotes and backslashes no longer produce a config the tool cannot read back; load errors name the path - version comparison via PEP 440, so beta users are told about newer betas - dirty tree aborts in non-interactive mode; --allow-dirty opts back in - setup takes --data, --data-file and --defaults like create/add - test -t NAME / -s TARGET pass through to the invoke task and the command exits with the test run's exit code - serve/test/debug explain a missing uv, tasks.py, invoke or pytest - auto-commit failures go to the styled error channel - fixes "completion <shell> --install", which the new tests caught Requires the matching test task in copier-templates; projects with an older tasks.py get a message naming the fix.
1 parent 4f6576d commit e05d13b

23 files changed

Lines changed: 1811 additions & 174 deletions

CHANGES.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,54 @@
33
## 7.0.0b14 (unreleased)
44

55

6-
- Nothing changed yet.
6+
- Save `~/.plonecli/config.toml` with a real TOML writer, so quotes, backslashes
7+
and newlines in any value round-trip instead of producing a file plonecli can
8+
no longer read. An unreadable config now fails with a message naming the path.
9+
[MrTango]
10+
11+
- Compare versions with PEP 440 in the update check, so users on a beta are told
12+
about newer betas and a final release is never "updated" to an older one.
13+
[MrTango]
14+
15+
- Abort instead of proceeding when a template runs on a git repository with
16+
uncommitted changes in non-interactive mode (`--defaults` or no terminal). New
17+
`--allow-dirty` flag on `create`, `add` and `setup` opts back in.
18+
[MrTango]
19+
20+
- Give `setup` the `--data`, `--data-file` and `--defaults` options of
21+
`create`/`add`, so a backend addon can be bootstrapped from a script or CI.
22+
[MrTango]
23+
24+
- Restore test filtering: `plonecli test -t NAME` runs a single test and
25+
`-s TARGET` restricts the run to one package. Both pass through to the
26+
generated `invoke test` task; projects with an older `tasks.py` get a message
27+
naming the fix instead of an unknown-flag error from invoke.
28+
[MrTango]
29+
30+
- `plonecli test` now exits with the test run's exit code, so a failing test run
31+
fails the command.
32+
[MrTango]
33+
34+
- Report a failed git auto-commit as a coloured error on stderr naming the
35+
uncommitted directory, instead of a bare stdout print.
36+
[MrTango]
37+
38+
- Explain what is missing when `serve`, `test` or `debug` cannot run the invoke
39+
tasks - no `uv` on PATH, no generated `tasks.py`, or a project that does not
40+
declare `invoke` (dev group) or `pytest` (`test` extra) - instead of failing
41+
inside a subprocess.
42+
[MrTango]
43+
44+
- Fix `plonecli completion <shell> --install`, which failed with
45+
"No such option: --install" because the chained top-level group disables
46+
interspersed arguments.
47+
[MrTango]
48+
49+
- Add CLI-level tests for `config`, `update`, `setup` and `completion`, unit
50+
tests for the Plone-version fetching module, and update-banner tests. Document
51+
the full command set, the non-interactive options and the test filters in the
52+
README.
53+
[MrTango]
754

855

956
## 7.0.0b13 (2026-07-24)

README.md

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,49 @@ This creates `~/.plonecli/config.toml` with your settings.
132132
plonecli --help
133133

134134
Commands:
135-
add Add features to your existing Plone package
136-
config Configure plonecli global settings
137-
create Create a new Plone package
138-
debug Start the Plone instance in debug mode
139-
serve Start the Plone instance
140-
setup Run zope-setup inside an existing backend_addon
141-
test Run the tests in your package
142-
update Update copier-templates and check for plonecli updates
135+
add Add features to your existing Plone package
136+
completion Show or install shell completion
137+
config Configure plonecli global settings
138+
create Create a new Plone package
139+
debug Start the Plone instance in debug mode
140+
serve Start the Plone instance
141+
setup Run zope-setup inside an existing backend_addon
142+
skill Install/update the bundled Agent Skills for AI coding agents
143+
test Run the tests in your package
144+
update Update copier-templates and check for plonecli updates
143145

144146
Options:
145147
-l, --list-templates List available templates
146-
-V, --versions Show version information
148+
-V, --versions Show plonecli and copier-templates versions
147149
-h, --help Show this message and exit.
148150
```
149151

152+
The list is context-aware: outside a Plone project only the global commands
153+
(`completion`, `config`, `create`, `skill`, `update`) are shown; inside one,
154+
`create` is replaced by the project commands.
155+
156+
`create`, `add` and `setup` share the non-interactive options, so a package can
157+
be bootstrapped from a script or CI:
158+
159+
```shell
160+
plonecli create addon collective.todo --defaults -d description="Todo lists"
161+
plonecli add content_type --defaults --data-file answers.yml
162+
plonecli setup --defaults -d plone_version=6.1.1
163+
```
164+
165+
| Option | What it does |
166+
|---------------------|--------------------------------------------------------------------|
167+
| `-d KEY=VALUE` | Pre-fill a template answer (repeatable), skipping its prompt |
168+
| `--data-file FILE` | Load answers from a YAML/JSON file (`-d` wins on conflicts) |
169+
| `--defaults` | Use template defaults for unanswered questions instead of prompting |
170+
| `--allow-dirty` | Run even if the git repository has uncommitted changes |
171+
| `--no-git` | Skip the auto-commit (`create`, `add`) |
172+
173+
On a repository with uncommitted changes, an interactive run asks whether to
174+
continue, and a non-interactive one (`--defaults`, or no terminal) aborts so
175+
generated files never silently mix into your work in progress. Pass
176+
`--allow-dirty` when that mixing is intended.
177+
150178

151179
### Creating a Plone Add-on
152180

@@ -205,6 +233,20 @@ With verbose output:
205233
plonecli test --verbose
206234
```
207235

236+
Run a single test, or restrict the run to one package:
237+
238+
```shell
239+
plonecli test -t test_behavior_installed
240+
plonecli test -s src/collective/todo
241+
```
242+
243+
Both are passed to the project's `invoke test` task: `-t/--test` becomes pytest's
244+
`-k`, and `-s/--package` becomes the pytest target path. `plonecli test` exits
245+
with the test run's exit code, so it can gate a script or a CI job.
246+
247+
Projects generated before the task gained these parameters need their `tasks.py`
248+
refreshed with `plonecli update && plonecli setup`.
249+
208250

209251
### Debug Mode
210252

@@ -314,6 +356,10 @@ local_path = "~/.copier-templates/plone-copier-templates"
314356

315357
The default Plone version is fetched from `https://dist.plone.org/release/` and cached for 24 hours.
316358

359+
Run `plonecli config` to (re)write the file interactively. If it ever becomes
360+
unreadable, plonecli says so and names the path — delete it and run
361+
`plonecli config` again to start fresh.
362+
317363
### Environment Variables
318364

319365
You can override template configuration using environment variables. These take precedence over the config file:

0 commit comments

Comments
 (0)