From bc8d3987c52082292807c15eb31afc5a41900a20 Mon Sep 17 00:00:00 2001 From: Lvjiawei Date: Thu, 12 Mar 2020 23:19:54 +0800 Subject: [PATCH] Fix plugin execution for Windows Fixes #737 * Use exec.Command instend of syscall.Exec for windows. * Fix a bug in plugin handler test when running it on windows. * Fix typo. --- CHANGELOG.adoc | 4 ++++ docs/plugins/README.md | 2 +- pkg/kn/commands/plugin/handler.go | 13 +++++++++++++ pkg/kn/commands/plugin/handler_test.go | 12 ++++++++++++ pkg/kn/commands/plugin/plugin_test_helper.go | 7 +------ 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 5a9fcc776e..2d2d1f074c 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -26,6 +26,10 @@ | Fix trigger create --filter flag to be optional | https://github.com/knative/client/pull/745[#745] +| 🐛 +| Fix plugin execution for Windows. +| https://github.com/knative/client/pull/738[#738] + ## v0.13.0 (2020-03-11) [cols="1,10,3", options="header", width="100%"] diff --git a/docs/plugins/README.md b/docs/plugins/README.md index b885efe052..4f0d1ab4a2 100644 --- a/docs/plugins/README.md +++ b/docs/plugins/README.md @@ -5,7 +5,7 @@ Plugins follow a similar architecture to with some small differences. One key difference is that `kn` plugins can either live in your `PATH` or in a chosen and specified directory. [Kn plugins](https://github.com/knative/client/tree/master/docs/cmd/kn_plugin.md) -shows how to install and create new plugins as well as gives some examples and +show how to install and create new plugins as well as gives some examples and best practices. To see what plugins are installed on your machine, you can use the diff --git a/pkg/kn/commands/plugin/handler.go b/pkg/kn/commands/plugin/handler.go index 5fc8104318..7ee7c4eeb5 100644 --- a/pkg/kn/commands/plugin/handler.go +++ b/pkg/kn/commands/plugin/handler.go @@ -20,6 +20,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strings" "syscall" @@ -93,6 +94,18 @@ func (h *DefaultPluginHandler) Lookup(name string) (string, bool) { // Execute implements PluginHandler func (h *DefaultPluginHandler) Execute(executablePath string, cmdArgs, environment []string) error { + if runtime.GOOS == "windows" { + cmd := exec.Command(executablePath, cmdArgs...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + cmd.Env = environment + err := cmd.Run() + if err == nil { + os.Exit(0) + } + return err + } return syscall.Exec(executablePath, cmdArgs, environment) } diff --git a/pkg/kn/commands/plugin/handler_test.go b/pkg/kn/commands/plugin/handler_test.go index 65d5b424ab..5757a7eb3c 100644 --- a/pkg/kn/commands/plugin/handler_test.go +++ b/pkg/kn/commands/plugin/handler_test.go @@ -19,6 +19,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "testing" "gotest.tools/assert" @@ -45,6 +46,9 @@ func TestPluginHandler(t *testing.T) { beforeEach := func(t *testing.T) { pluginName = "fake" + if runtime.GOOS == "windows" { + pluginName += ".bat" + } pluginPath = CreateTestPluginInPath(t, "kn-"+pluginName, KnTestPluginScript, FileModeExecutable, tmpPathDir) assert.Assert(t, pluginPath != "") @@ -134,6 +138,14 @@ func TestPluginHandler(t *testing.T) { err = pluginHandler.Execute(bogusPath, []string{bogusPath}, os.Environ()) assert.Assert(t, err != nil, fmt.Sprintf("bogus plugin in path %s unexpectedly executed OK", bogusPath)) }) + t.Run("executing fake plugin successfully", func(t *testing.T) { + setup(t) + defer cleanup(t) + beforeEach(t) + + err = pluginHandler.Execute(pluginPath, []string{}, os.Environ()) + assert.Assert(t, err == nil, fmt.Sprintf("fail to execute fake plugin in path %s ", pluginPath)) + }) }) t.Run("HandlePluginCommand", func(t *testing.T) { diff --git a/pkg/kn/commands/plugin/plugin_test_helper.go b/pkg/kn/commands/plugin/plugin_test_helper.go index 7af57a74d6..c080d4602a 100644 --- a/pkg/kn/commands/plugin/plugin_test_helper.go +++ b/pkg/kn/commands/plugin/plugin_test_helper.go @@ -18,7 +18,6 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "testing" "github.com/spf13/cobra" @@ -58,13 +57,9 @@ func CreateTestPlugin(t *testing.T, name, script string, fileMode os.FileMode) s // CreateTestPluginInPath with name, path, script, and fileMode and return the tmp random path func CreateTestPluginInPath(t *testing.T, name, script string, fileMode os.FileMode, path string) string { fullPath := filepath.Join(path, name) - if runtime.GOOS == "windows" { - fullPath += ".bat" - } err := ioutil.WriteFile(fullPath, []byte(script), fileMode) assert.NilError(t, err) - - return filepath.Join(path, name) + return fullPath } // DeleteTestPlugin with path