// Copyright IBM Corp. 2013, 2025 // SPDX-License-Identifier: BUSL-1.1 package command import ( "context" "crypto/sha256" "log" "runtime" "strings" plugingetter "github.com/hashicorp/packer/packer/plugin-getter" ) type PluginsInstalledCommand struct { Meta } func (c *PluginsInstalledCommand) Synopsis() string { return "List all installed Packer plugin binaries" } func (c *PluginsInstalledCommand) Help() string { helpText := ` Usage: packer plugins installed This command lists all installed plugin binaries that match with the current OS and architecture. Packer's API version will be ignored. ` return strings.TrimSpace(helpText) } func (c *PluginsInstalledCommand) Run(args []string) int { ctx, cleanup := handleTermInterrupt(c.Ui) defer cleanup() return c.RunContext(ctx) } func (c *PluginsInstalledCommand) RunContext(buildCtx context.Context) int { opts := plugingetter.ListInstallationsOptions{ PluginDirectory: c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory, 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" } log.Printf("[TRACE] init: %#v", opts) // a plugin requirement that matches them all allPlugins := plugingetter.Requirement{ Accessor: "", VersionConstraints: nil, Identifier: nil, } installations, err := allPlugins.ListInstallations(opts) if err != nil { c.Ui.Error(err.Error()) return 1 } for _, installation := range installations { c.Ui.Message(installation.BinaryPath) } return 0 }