feat(build): summer plugin:update

- module installs move to the newest compatible registry release with
  one go get; submodules fetch tags, check out the release tag and
  require it in go.mod; go.work overrides and version pins are refreshed
- unlisted submodules (git URL installs) update from their own tags and
  plugin.yaml; --offline restricts to that
- without an ID every plugin that resolves is updated; in-app, unlisted
  and incompatible ones are reported; failure only when a resolved
  update cannot be carried out
- same prompt rule as plugin:install
This commit is contained in:
Jakub Zych
2026-10-29 18:46:14 +01:00
parent 8093587696
commit d024ab4bb8
8 changed files with 838 additions and 55 deletions

View File

@@ -44,6 +44,7 @@ func toolCommands() []bonfire.Command {
addPluginCommand(),
pluginManifestCommand(),
pluginInstallCommand(),
pluginUpdateCommand(),
newCommand(),
devCommand(),
parityProxyCommand(),
@@ -622,6 +623,76 @@ with a git URL. An empty plugins.registry_url disables registry calls.`,
}
}
func pluginUpdateCommand() bonfire.Command {
return bonfire.Command{
Name: "plugin:update",
Description: "Move installed plugins to their newest compatible release",
Long: `Updates one installed plugin, or every plugin in summer.yaml when no ID is
given, to the newest release whose framework minimum the application's
framework version meets. A plugin installed as a Go module moves with go get;
one installed as a git submodule fetches its tags, is checked out at the
release tag, and go.mod requires that tag. The go.work replaces the
application needs are refreshed, including version pins that follow the
framework requirement.
Releases come from the registry (plugins.registry_url). A submodule the
registry does not list, such as a plugin installed from a git URL, is updated
from its own tags and their plugin.yaml. A newer release that needs a newer
framework is reported, not installed. Plugins that cannot be updated (in-app
plugins, module installs the registry does not list, releases needing a
plugin the application lacks) are listed as not updated; the command fails
only when an update it resolved could not be carried out.
The updates are printed and confirmed with a prompt; --yes skips it, and a run
without a terminal needs --yes. --offline makes no registry call and updates
submodules from their own tags only. Run summer build afterwards.`,
Examples: []bonfire.Example{
{Command: "plugin:update acme.blog", Description: "Move acme.blog to its newest compatible release"},
{Command: "plugin:update --yes", Description: "Update every plugin that has a newer compatible release, without asking"},
{Command: "plugin:update --offline", Description: "Update submodule plugins from their own tags, without the registry"},
},
Args: []bonfire.Arg{{
Name: "plugin",
Description: "Plugin ID in vendor.name form (default: every plugin in summer.yaml)",
}},
Flags: []bonfire.Flag{
{Name: "yes", Description: "Update without asking for confirmation", Bare: true},
{Name: "offline", Description: "Make no registry call; update submodules from their own tags", Bare: true},
},
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
id, _ := in.Argument("plugin")
dir, err := os.Getwd()
if err != nil {
return err
}
appDir, err := build.FindAppDir(dir)
if err != nil {
return err
}
offline := bonfire.FlagBool(in, "offline")
reg, err := registryFor(appDir, offline)
if err != nil {
return err
}
err = build.Update(ctx, build.UpdateOptions{
StartDir: dir,
ID: id,
Yes: bonfire.FlagBool(in, "yes"),
Offline: offline,
Interactive: bonfire.Interactive(out),
Registry: reg,
Confirm: func(q string) (bool, error) { return out.Confirm(q, false) },
Out: out,
})
if errors.Is(err, build.ErrCancelled) {
out.Println("Nothing updated.")
return nil
}
return err
},
}
}
func newCommand() bonfire.Command {
return bonfire.Command{
Name: "new",