mirror of
https://github.com/hashicorp/packer.git
synced 2026-02-23 01:40:26 -05:00
If a user attempts to remove a plugin through the `packer plugins remove' subcommand, and the specified plugin is not installed, the command succeeds, but does nothing, and exits silently. This is not clear what is happening, and arguably, calling a command that does nothing, not even explain what went wrong, is not intuitive. Because of that, this commit changes how the command behaves in this case, stating what went wrong, and exiting with a non-zero status.
117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package command
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/go-version"
|
|
"github.com/hashicorp/packer/hcl2template/addrs"
|
|
plugingetter "github.com/hashicorp/packer/packer/plugin-getter"
|
|
"github.com/mitchellh/cli"
|
|
)
|
|
|
|
type PluginsRemoveCommand struct {
|
|
Meta
|
|
}
|
|
|
|
func (c *PluginsRemoveCommand) Synopsis() string {
|
|
return "Remove Packer plugins [matching a version]"
|
|
}
|
|
|
|
func (c *PluginsRemoveCommand) Help() string {
|
|
helpText := `
|
|
Usage: packer plugins remove <plugin> [<version constraint>]
|
|
|
|
This command will remove all Packer plugins matching the version constraint
|
|
for the current OS and architecture.
|
|
When the version is omitted all installed versions will be removed.
|
|
|
|
Ex: packer plugins remove github.com/hashicorp/happycloud v1.2.3
|
|
`
|
|
|
|
return strings.TrimSpace(helpText)
|
|
}
|
|
|
|
func (c *PluginsRemoveCommand) Run(args []string) int {
|
|
ctx, cleanup := handleTermInterrupt(c.Ui)
|
|
defer cleanup()
|
|
|
|
return c.RunContext(ctx, args)
|
|
}
|
|
|
|
func (c *PluginsRemoveCommand) RunContext(buildCtx context.Context, args []string) int {
|
|
if len(args) < 1 || len(args) > 2 {
|
|
return cli.RunResultHelp
|
|
}
|
|
|
|
opts := plugingetter.ListInstallationsOptions{
|
|
FromFolders: c.Meta.CoreConfig.Components.PluginConfig.KnownPluginFolders,
|
|
BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{
|
|
OS: runtime.GOOS,
|
|
ARCH: runtime.GOARCH,
|
|
Checksummers: []plugingetter.Checksummer{
|
|
{Type: "sha256", Hash: sha256.New()},
|
|
},
|
|
},
|
|
}
|
|
|
|
if runtime.GOOS == "windows" && opts.Ext == "" {
|
|
opts.BinaryInstallationOptions.Ext = ".exe"
|
|
}
|
|
|
|
plugin, diags := addrs.ParsePluginSourceString(args[0])
|
|
if diags.HasErrors() {
|
|
c.Ui.Error(diags.Error())
|
|
return 1
|
|
}
|
|
|
|
// a plugin requirement that matches them all
|
|
pluginRequirement := plugingetter.Requirement{
|
|
Identifier: plugin,
|
|
}
|
|
|
|
if len(args) > 1 {
|
|
constraints, err := version.NewConstraint(args[1])
|
|
if err != nil {
|
|
c.Ui.Error(err.Error())
|
|
return 1
|
|
}
|
|
pluginRequirement.VersionConstraints = constraints
|
|
}
|
|
|
|
installations, err := pluginRequirement.ListInstallations(opts)
|
|
if err != nil {
|
|
c.Ui.Error(err.Error())
|
|
return 1
|
|
}
|
|
for _, installation := range installations {
|
|
if err := os.Remove(installation.BinaryPath); err != nil {
|
|
c.Ui.Error(err.Error())
|
|
return 1
|
|
}
|
|
shasumFile := fmt.Sprintf("%s_SHA256SUM", installation.BinaryPath)
|
|
if err := os.Remove(shasumFile); err != nil {
|
|
c.Ui.Error(fmt.Sprintf("failed to remove %s: %s", shasumFile, err))
|
|
c.Ui.Error("You may need to remove it manually")
|
|
}
|
|
c.Ui.Message(installation.BinaryPath)
|
|
}
|
|
|
|
if len(installations) == 0 {
|
|
errMsg := fmt.Sprintf("No installed plugin found matching the plugin constraints %s", args[0])
|
|
if len(args) == 2 {
|
|
errMsg = fmt.Sprintf("%s %s", errMsg, args[1])
|
|
}
|
|
c.Ui.Error(errMsg)
|
|
return 1
|
|
}
|
|
|
|
return 0
|
|
}
|