|
| 1 | +# plonecli scaffolding evaluations |
| 2 | + |
| 3 | +This directory contains a reusable, real-CLI evaluation of plonecli commands and |
| 4 | +all copier templates in the development checkout. It is intentionally separate |
| 5 | +from product and template source. |
| 6 | + |
| 7 | +## Run |
| 8 | + |
| 9 | +From the repository root: |
| 10 | + |
| 11 | +```sh |
| 12 | +uv run python evals/scaffolding/run_evals.py --quick |
| 13 | +uv run python evals/scaffolding/run_evals.py --ci-validation |
| 14 | +uv run python evals/scaffolding/run_evals.py |
| 15 | +``` |
| 16 | + |
| 17 | +`--quick` runs a reduced smoke subset. `--ci-validation` runs every template |
| 18 | +once plus hostile-input and command checks. With no flag, the runner executes |
| 19 | +the explicit finite high-interaction matrices described below. It audits the |
| 20 | +repository template inventory and fails when a new template has no lane. The runner itself invokes plonecli only as |
| 21 | +`uv run --project /workspaces/plonecli plonecli`, so copied generated projects cannot shadow the checkout with their own environment. It sets: |
| 22 | + |
| 23 | +```text |
| 24 | +PLONECLI_TEMPLATES_DIR=/workspaces/plonecli/develop/plone/src/copier-templates |
| 25 | +``` |
| 26 | + |
| 27 | +Generated trees are disposable and always live beneath `workspaces/`. Reports |
| 28 | +and per-case command logs are written beneath `results/`: |
| 29 | + |
| 30 | +- `results/report.json` — machine-readable case inventory, commands, coverage, |
| 31 | + validation results, counts, and failures. |
| 32 | +- `results/report.md` — human-readable coverage table and problem summary. |
| 33 | +- `results/logs/*.log` — captured stdout/stderr for every case. |
| 34 | + |
| 35 | +Both output directories are ignored by git and replaced at the start of a run. |
| 36 | + |
| 37 | +## Coverage |
| 38 | + |
| 39 | +The full run covers: |
| 40 | + |
| 41 | +- harmless root commands: help, template list, versions, and bash/zsh/fish |
| 42 | + completion output; |
| 43 | +- real non-default creation of `backend_addon`, `zope-setup`, and the `addon` |
| 44 | + composite, plus a real standalone `setup` application; |
| 45 | +- every currently shipped backend subtemplate individually against a copied |
| 46 | + clean parent, plus `zope_instance` against a copied Zope parent; |
| 47 | +- both backend headless states and both Svelte custom-element states; |
| 48 | +- the complete behavior boolean matrix (4 cases); |
| 49 | +- all REST boolean states crossed with normal/manual registration targets |
| 50 | + (64 cases); |
| 51 | +- all reachable content-type gated boolean/choice states; |
| 52 | +- every view base class × template × marker × normal/manual target state; |
| 53 | +- both vocabulary implementation choices; |
| 54 | +- all 26 viewlet managers with both template values (52 cases); |
| 55 | +- both Zope distributions × all three storage modes, and all three |
| 56 | + `zope_instance` storage modes; |
| 57 | +- one all-backend-subtemplates project, reversed-order pairs, and representative |
| 58 | + repeated-application/idempotency cases; |
| 59 | +- TOML-hostile quote/newline/backslash partitions and a real chained |
| 60 | + `create` → `setup` command. |
| 61 | + |
| 62 | +Names are unique per isolated project to make collisions deterministic. The |
| 63 | +report records the full planned and actually executed counts by category, and |
| 64 | +each matrix case records its parameter values. |
| 65 | + |
| 66 | +## Validation and safety |
| 67 | + |
| 68 | +Every generated project receives deterministic syntax and duplicate-registration |
| 69 | +checks without installing Plone. The template unit suite supplies |
| 70 | +feature-specific semantic assertions: |
| 71 | + |
| 72 | +- every TOML file is parsed with `tomllib`; |
| 73 | +- every XML and ZCML file is parsed; |
| 74 | +- every Python file is compiled; |
| 75 | +- exact duplicate direct-child XML registrations are reported where practical; |
| 76 | +- every subprocess exit code is checked; |
| 77 | +- stdin is disabled and every command has a configurable timeout. |
| 78 | + |
| 79 | +The harness does **not** run `serve` or `debug`, and does not run a generated |
| 80 | +project's `test` task because those branches can start services or resolve a |
| 81 | +full Plone environment. Instead it runs the repository's root CLI command unit |
| 82 | +test suite, which covers `serve`, `debug`, and `test` dispatch and error paths |
| 83 | +with mocked subprocesses. Template hooks may still ask native `uv` to resolve |
| 84 | +small hook-only tools (`tomlkit`, Copier extensions); use a warmed uv cache for |
| 85 | +the most network-independent run. |
| 86 | + |
| 87 | +## Reading failures |
| 88 | + |
| 89 | +A nonzero runner exit means at least one case failed or was blocked. Start with |
| 90 | +`results/report.md`, then inspect the referenced log. Failures are retained as |
| 91 | +evaluation findings rather than hidden or retried with defaults. Reports include |
| 92 | +repository commits, dirty state, Python, and uv provenance. |
0 commit comments