diff --git a/commands/faas.go b/commands/faas.go index 259d8589f..709a811be 100644 --- a/commands/faas.go +++ b/commands/faas.go @@ -4,9 +4,11 @@ package commands import ( + "errors" "fmt" "log" "os" + "os/exec" "path" "runtime" "strings" @@ -88,21 +90,42 @@ func Execute(customArgs []string) { } if cmd1 != nil && len(args1) > 0 { - found := "" for _, plugin := range plugins { - if path.Base(plugin) == args1[0] { + pluginName := args1[0] + if runtime.GOOS == "windows" { + pluginName = fmt.Sprintf("%s.exe", args1[0]) + } + + if path.Base(plugin) == pluginName { found = plugin } } if len(found) > 0 { - - // if we have found the plugin then sysexec it by replacing current process. - if err := syscall.Exec(found, append([]string{found}, os.Args[2:]...), os.Environ()); err != nil { - fmt.Fprintf(os.Stderr, "Error from plugin: %v", err) - os.Exit(127) + // If we have found the plugin then sysexec it by replacing the current process. + // On Windows we use the os/exec package to run the plugins since replacing the current + // process with syscall.exec is not supported. + if runtime.GOOS == "windows" { + cmd := exec.Command(found, os.Args[2:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + os.Exit(exitErr.ExitCode()) + } else { + fmt.Println("Error from plugin", err) + os.Exit(127) + } + } + return + } else { + if err := syscall.Exec(found, append([]string{found}, os.Args[2:]...), os.Environ()); err != nil { + fmt.Fprintf(os.Stderr, "Error from plugin: %v", err) + os.Exit(127) + } + return } - return } } diff --git a/commands/plugin_get.go b/commands/plugin_get.go index 6dc6158de..6cdbf2cb4 100644 --- a/commands/plugin_get.go +++ b/commands/plugin_get.go @@ -132,6 +132,17 @@ func runPluginGetCmd(cmd *cobra.Command, args []string) error { if err := archive.Untar(tarFile, pluginDir, gzipped, true); err != nil { return fmt.Errorf("failed to untar %s: %w", tmpTar, err) } + + // Add the .exe filename extension to the plugin executable on windows. + // If the .exe extension is missing the plugin will not execute. + if runtime.GOOS == "windows" { + pluginPath := path.Join(pluginDir, pluginName) + err := os.Rename(pluginPath, fmt.Sprintf("%s.exe", pluginPath)) + if err != nil { + return fmt.Errorf("failed to move plugin %w", err) + } + } + fmt.Printf("Downloaded in (%ds)\n\nUsage:\n faas-cli %s\n", int(time.Since(st).Seconds()), pluginName) return nil }