Test plugins from rootCommand

This commit is contained in:
Ian Howell 2019-05-14 12:55:52 -05:00
parent 6f879da587
commit f3fa2b6bd2
3 changed files with 21 additions and 13 deletions
cmd
internal/test
pkg/plugin

@ -21,7 +21,7 @@ const defaultPluginDir = "_plugins/bin"
// NewRootCmd creates the root `airshipctl` command. All other commands are
// subcommands branching from this one
func NewRootCmd(out io.Writer, args []string) (*cobra.Command, error) {
func NewRootCmd(out io.Writer, pluginDir string, args []string) (*cobra.Command, error) {
rootCmd := &cobra.Command{
Use: "airshipctl",
Short: "airshipctl is a unified entrypoint to various airship components",
@ -33,14 +33,19 @@ func NewRootCmd(out io.Writer, args []string) (*cobra.Command, error) {
rootCmd.AddCommand(NewVersionCommand(out))
if _, err := os.Stat(defaultPluginDir); err == nil {
pluginFiles, err := util.ReadDir(defaultPluginDir)
if _, err := os.Stat(pluginDir); err == nil {
pluginFiles, err := util.ReadDir(pluginDir)
if err != nil {
return nil, errors.New("could not read plugins: " + err.Error())
}
for _, pluginFile := range pluginFiles {
pathToPlugin := filepath.Join(defaultPluginDir, pluginFile.Name())
rootCmd.AddCommand(plugin.CreateCommandFromPlugin(pathToPlugin, out, args))
pathToPlugin := filepath.Join(pluginDir, pluginFile.Name())
newCommand, err := plugin.CreateCommandFromPlugin(pathToPlugin, out, args)
if err != nil {
log.Debugf("Could not load plugin from %s: %s\n", pathToPlugin, err.Error())
} else {
rootCmd.AddCommand(newCommand)
}
}
}
@ -51,7 +56,7 @@ func NewRootCmd(out io.Writer, args []string) (*cobra.Command, error) {
// Execute runs the base airshipctl command
func Execute(out io.Writer) {
rootCmd, err := NewRootCmd(out, os.Args[1:])
rootCmd, err := NewRootCmd(out, defaultPluginDir, os.Args[1:])
osExitIfError(out, err)
osExitIfError(out, rootCmd.Execute())
}

@ -42,7 +42,7 @@ func executeCmd(t *testing.T, command string) []byte {
var actual bytes.Buffer
// TODO(howell): switch to shellwords (or similar)
args := strings.Fields(command)
rootCmd, err := cmd.NewRootCmd(&actual, args)
rootCmd, err := cmd.NewRootCmd(&actual, "testdata/_plugins/bin", args)
if err != nil {
t.Fatalf(err.Error())
}

@ -1,25 +1,28 @@
package plugin
import (
"fmt"
"io"
"plugin"
"github.com/spf13/cobra"
)
func CreateCommandFromPlugin(pluginPath string, out io.Writer, args []string) *cobra.Command {
//TODO(howell): Remove these panics
const badInterfaceFormat = `plugin at %s is missing required function:
- NewCommand(func io.writer, []string) *cobra.Command)`
func CreateCommandFromPlugin(pluginPath string, out io.Writer, args []string) (*cobra.Command, error) {
plug, err := plugin.Open(pluginPath)
if err != nil {
panic(err.Error())
return nil, fmt.Errorf("plugin at %s could not be opened", pluginPath)
}
cmdSym, err := plug.Lookup("NewCommand")
if err != nil {
panic(err.Error())
return nil, fmt.Errorf(badInterfaceFormat, pluginPath)
}
command, ok := cmdSym.(func(io.Writer, []string) *cobra.Command)
if !ok {
panic("NewCommand does not meet the interface.")
return nil, fmt.Errorf(badInterfaceFormat, pluginPath)
}
return command(out, args)
return command(out, args), nil
}