feat(build): plugin:install resolves requirements, pins and prompts

- required plugins resolve transitively against the registry, each at the
  newest release meeting the framework and its minimum, dependencies first
- an installed requirement below its minimum stops with a plugin:update
  hint; cycles in registry data are reported
- one go get for the whole set; plugins sharing a module share a release
- behavior subtests: deps, installed_old, cycle, pin, unknown, prompt,
  offline, invalid
This commit is contained in:
Jakub Zych
2026-10-29 18:26:05 +01:00
parent 9b23e877a6
commit a462bf12c9
3 changed files with 439 additions and 19 deletions

View File

@@ -106,7 +106,23 @@ The command asks the registry for the plugin's releases and picks the newest one
The plugin is installed as a Go module: one `go get <module>@<version>` in the application, then an entry with its ID and package in `summer.yaml`. The edit appends to the `plugins:` list and keeps the file's comments and blank lines. Run `summer build` afterwards: it generates the import, and the new require in `go.mod` loses its `// indirect` marker the next time you run `go mod tidy`. A plugin that is already in `summer.yaml` is not installed again.
Before changing anything, the command prints each plugin it is about to add as `id@version (module)` and asks for confirmation. `--yes` skips the question. A run that cannot ask (no terminal, `-n` or `-q`) stops with an error unless `--yes` is given.
### Required plugins
A plugin's `requires` (from its `plugin.yaml`, as the registry lists it for the chosen release) are installed with it. For each required plugin the application does not have yet, the command picks the newest release that the framework version meets and that is at least the required minimum, then resolves that plugin's own requirements the same way. Required plugins come first in the list and in `summer.yaml`, and all module installs go through a single `go get`, so Go's minimal version selection sees the whole set. Two plugins that ship in the same module are installed from the same release of it.
A required plugin the application already has is not touched, but its version must be at least the minimum: the go.mod require for a module install, the tag `git describe` finds for a plugin checked out as a submodule. When it is older, the command stops and asks you to update that plugin first. A version it cannot read, such as that of a plugin kept in the application's own repository, is accepted with a warning. Requirements that form a cycle in the registry data are reported as an error.
### Confirmation
Before changing anything, the command prints each plugin it is about to add, one line per plugin:
```text
Installing 2 plugins into /srv/acme (framework v0.6.2):
acme.translate@v0.2.1 (module)
acme.blog@v0.3.0 (module)
```
Then it asks for confirmation, with "no" as the default. `--yes` skips the question. A run that cannot ask (no terminal, `-n` or `-q`) stops with an error naming `--yes` unless it is given. Declining changes nothing.
### The registry setting