Skip to content

Commit 88dc45d

Browse files
committed
Merge branch 'master' of github.com:plone/plonecli
2 parents 26b0ece + 4511ba9 commit 88dc45d

28 files changed

Lines changed: 1861 additions & 180 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 & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,7 @@
1010
The Plone CLI is meant for developing Plone packages. It uses [copier](https://copier.readthedocs.io/) templates to scaffold Plone backend addons, Zope project setups, and add features like content types, behaviors, and REST API services.
1111

1212

13-
## Demo
1413

15-
Scaffolding a backend add-on, adding a content type and behavior, and wiring up a REST API service:
16-
17-
<video src="https://github.com/plone/plonecli/raw/master/docs/demo-backend.webm" controls muted width="100%"></video>
18-
19-
> ▶ If the video does not play inline, [watch `docs/demo-backend.webm`](https://github.com/plone/plonecli/raw/master/docs/demo-backend.webm).
2014

2115
## Compatibility
2216

@@ -132,21 +126,49 @@ This creates `~/.plonecli/config.toml` with your settings.
132126
plonecli --help
133127

134128
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
129+
add Add features to your existing Plone package
130+
completion Show or install shell completion
131+
config Configure plonecli global settings
132+
create Create a new Plone package
133+
debug Start the Plone instance in debug mode
134+
serve Start the Plone instance
135+
setup Run zope-setup inside an existing backend_addon
136+
skill Install/update the bundled Agent Skills for AI coding agents
137+
test Run the tests in your package
138+
update Update copier-templates and check for plonecli updates
143139

144140
Options:
145141
-l, --list-templates List available templates
146-
-V, --versions Show version information
142+
-V, --versions Show plonecli and copier-templates versions
147143
-h, --help Show this message and exit.
148144
```
149145

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

151173
### Creating a Plone Add-on
152174

@@ -205,6 +227,20 @@ With verbose output:
205227
plonecli test --verbose
206228
```
207229

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

209245
### Debug Mode
210246

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

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

353+
Run `plonecli config` to (re)write the file interactively. If it ever becomes
354+
unreadable, plonecli says so and names the path — delete it and run
355+
`plonecli config` again to start fresh.
356+
317357
### Environment Variables
318358

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

evals/skill/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ means a skill leaked into the baseline.
6161
| `restapi-implicit` | The skill *triggers* when the prompt never says "plonecli" |
6262
| `fields-manual` | Fields are hand-edited into the schema (`plone-schema-fields` skill) |
6363
| `upgrade-step` | Profile-XML edits for installed sites get `plonecli add upgrade_step` |
64+
| `uninstall-mirror` | Recreatable settings in `profiles/default` are mirrored for removal in `profiles/uninstall` |
6465
| `no-serve` | The agent never starts the dev server itself |
6566
| `legacy-adapt` | Legacy packages get minimal adaptation, not re-scaffolding |
6667
| `reconfigure` | Settings changes use `invoke reconfigure`, not `create` |

evals/skill/run_evals.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,31 @@ class Case:
259259
"needs plonecli add upgrade_step."
260260
),
261261
),
262+
Case(
263+
id="uninstall-mirror",
264+
prompt=(
265+
"Add a boolean catalog index is_featured to the GenericSetup "
266+
"profile of the collective.demo add-on in this directory, and make "
267+
"sure uninstalling the add-on cleans the index up again."
268+
),
269+
fixture="addon",
270+
checks=[
271+
file_has(
272+
"collective.demo/src/collective/demo/profiles/default/catalog.xml",
273+
r"is_featured",
274+
"default catalog.xml gains the index",
275+
),
276+
file_has(
277+
"collective.demo/src/collective/demo/profiles/uninstall/catalog.xml",
278+
r'is_featured(?s).*remove="True"|remove="True"(?s).*is_featured',
279+
"uninstall catalog.xml removes the index (remove=\"True\")",
280+
),
281+
],
282+
notes=(
283+
"Uninstall rule: a recreatable setting added to profiles/default "
284+
"must be mirrored for removal in profiles/uninstall."
285+
),
286+
),
262287
Case(
263288
id="no-serve",
264289
prompt=(

0 commit comments

Comments
 (0)