Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,54 @@
## 7.0.0b14 (unreleased)


- Nothing changed yet.
- Save `~/.plonecli/config.toml` with a real TOML writer, so quotes, backslashes
and newlines in any value round-trip instead of producing a file plonecli can
no longer read. An unreadable config now fails with a message naming the path.
[MrTango]

- Compare versions with PEP 440 in the update check, so users on a beta are told
about newer betas and a final release is never "updated" to an older one.
[MrTango]

- Abort instead of proceeding when a template runs on a git repository with
uncommitted changes in non-interactive mode (`--defaults` or no terminal). New
`--allow-dirty` flag on `create`, `add` and `setup` opts back in.
[MrTango]

- Give `setup` the `--data`, `--data-file` and `--defaults` options of
`create`/`add`, so a backend addon can be bootstrapped from a script or CI.
[MrTango]

- Restore test filtering: `plonecli test -t NAME` runs a single test and
`-s TARGET` restricts the run to one package. Both pass through to the
generated `invoke test` task; projects with an older `tasks.py` get a message
naming the fix instead of an unknown-flag error from invoke.
[MrTango]

- `plonecli test` now exits with the test run's exit code, so a failing test run
fails the command.
[MrTango]

- Report a failed git auto-commit as a coloured error on stderr naming the
uncommitted directory, instead of a bare stdout print.
[MrTango]

- Explain what is missing when `serve`, `test` or `debug` cannot run the invoke
tasks - no `uv` on PATH, no generated `tasks.py`, or a project that does not
declare `invoke` (dev group) or `pytest` (`test` extra) - instead of failing
inside a subprocess.
[MrTango]

- Fix `plonecli completion <shell> --install`, which failed with
"No such option: --install" because the chained top-level group disables
interspersed arguments.
[MrTango]

- Add CLI-level tests for `config`, `update`, `setup` and `completion`, unit
tests for the Plone-version fetching module, and update-banner tests. Document
the full command set, the non-interactive options and the test filters in the
README.
[MrTango]


## 7.0.0b13 (2026-07-24)
Expand Down
64 changes: 55 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,49 @@ This creates `~/.plonecli/config.toml` with your settings.
plonecli --help

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

Options:
-l, --list-templates List available templates
-V, --versions Show version information
-V, --versions Show plonecli and copier-templates versions
-h, --help Show this message and exit.
```

The list is context-aware: outside a Plone project only the global commands
(`completion`, `config`, `create`, `skill`, `update`) are shown; inside one,
`create` is replaced by the project commands.

`create`, `add` and `setup` share the non-interactive options, so a package can
be bootstrapped from a script or CI:

```shell
plonecli create addon collective.todo --defaults -d description="Todo lists"
plonecli add content_type --defaults --data-file answers.yml
plonecli setup --defaults -d plone_version=6.1.1
```

| Option | What it does |
|---------------------|--------------------------------------------------------------------|
| `-d KEY=VALUE` | Pre-fill a template answer (repeatable), skipping its prompt |
| `--data-file FILE` | Load answers from a YAML/JSON file (`-d` wins on conflicts) |
| `--defaults` | Use template defaults for unanswered questions instead of prompting |
| `--allow-dirty` | Run even if the git repository has uncommitted changes |
| `--no-git` | Skip the auto-commit (`create`, `add`) |

On a repository with uncommitted changes, an interactive run asks whether to
continue, and a non-interactive one (`--defaults`, or no terminal) aborts so
generated files never silently mix into your work in progress. Pass
`--allow-dirty` when that mixing is intended.


### Creating a Plone Add-on

Expand Down Expand Up @@ -205,6 +233,20 @@ With verbose output:
plonecli test --verbose
```

Run a single test, or restrict the run to one package:

```shell
plonecli test -t test_behavior_installed
plonecli test -s src/collective/todo
```

Both are passed to the project's `invoke test` task: `-t/--test` becomes pytest's
`-k`, and `-s/--package` becomes the pytest target path. `plonecli test` exits
with the test run's exit code, so it can gate a script or a CI job.

Projects generated before the task gained these parameters need their `tasks.py`
refreshed with `plonecli update && plonecli setup`.


### Debug Mode

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

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

Run `plonecli config` to (re)write the file interactively. If it ever becomes
unreadable, plonecli says so and names the path — delete it and run
`plonecli config` again to start fresh.

### Environment Variables

You can override template configuration using environment variables. These take precedence over the config file:
Expand Down
1 change: 1 addition & 0 deletions evals/skill/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ means a skill leaked into the baseline.
| `restapi-implicit` | The skill *triggers* when the prompt never says "plonecli" |
| `fields-manual` | Fields are hand-edited into the schema (`plone-schema-fields` skill) |
| `upgrade-step` | Profile-XML edits for installed sites get `plonecli add upgrade_step` |
| `uninstall-mirror` | Recreatable settings in `profiles/default` are mirrored for removal in `profiles/uninstall` |
| `no-serve` | The agent never starts the dev server itself |
| `legacy-adapt` | Legacy packages get minimal adaptation, not re-scaffolding |
| `reconfigure` | Settings changes use `invoke reconfigure`, not `create` |
Expand Down
25 changes: 25 additions & 0 deletions evals/skill/run_evals.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,31 @@ class Case:
"needs plonecli add upgrade_step."
),
),
Case(
id="uninstall-mirror",
prompt=(
"Add a boolean catalog index is_featured to the GenericSetup "
"profile of the collective.demo add-on in this directory, and make "
"sure uninstalling the add-on cleans the index up again."
),
fixture="addon",
checks=[
file_has(
"collective.demo/src/collective/demo/profiles/default/catalog.xml",
r"is_featured",
"default catalog.xml gains the index",
),
file_has(
"collective.demo/src/collective/demo/profiles/uninstall/catalog.xml",
r'is_featured(?s).*remove="True"|remove="True"(?s).*is_featured',
"uninstall catalog.xml removes the index (remove=\"True\")",
),
],
notes=(
"Uninstall rule: a recreatable setting added to profiles/default "
"must be mirrored for removal in profiles/uninstall."
),
),
Case(
id="no-serve",
prompt=(
Expand Down
Loading
Loading