From 263bfcb2ae0fb2b29eb9f506273cf1185a9c70e7 Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Wed, 26 Sep 2018 09:01:35 -0700 Subject: [PATCH] Convert dashes in plugin names to underscores (#60) For dashes to be preserved in a plugin's name, its executable name must convert dashes to underscores. For example a plugin named "foo-bar" would today be linked as: kubectl-foo-bar therefore, it can only be invoked as: kubectl foo bar However, linking the same plugin as: kubectl-foo_bar allows plugin to be called as: kubectl foo-bar kubectl foo_bar - convert OS detection pluginNameToBin() to explicit input for testability - test pluginNameToBin(). Fixes #59. --- pkg/installation/install.go | 19 ++++++++++++------- pkg/installation/install_test.go | 21 +++++++++++++++++++++ pkg/installation/util.go | 2 +- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/pkg/installation/install.go b/pkg/installation/install.go index 448776d6..7084f343 100644 --- a/pkg/installation/install.go +++ b/pkg/installation/install.go @@ -124,7 +124,7 @@ func Remove(p environment.KrewPaths, name string) error { } func createOrUpdateLink(binDir string, binary string, plugin string) error { - dst := filepath.Join(binDir, pluginNameToBin(plugin)) + dst := filepath.Join(binDir, pluginNameToBin(plugin, isWindows())) if err := removeLink(binDir, plugin); err != nil { return fmt.Errorf("failed to remove old symlink, err: %v", err) @@ -138,13 +138,13 @@ func createOrUpdateLink(binDir string, binary string, plugin string) error { if err := os.Symlink(binary, dst); err != nil { return fmt.Errorf("failed to create a symlink form %q to %q, err: %v", binDir, dst, err) } - glog.V(2).Infof("Created symlink in %q", dst) + glog.V(2).Infof("Created symlink at %q", dst) return nil } func removeLink(binDir string, plugin string) error { - dst := filepath.Join(binDir, pluginNameToBin(plugin)) + dst := filepath.Join(binDir, pluginNameToBin(plugin, isWindows())) if err := os.Remove(dst); err != nil && !os.IsNotExist(err) { return fmt.Errorf("failed to remove the symlink in %q, err: %v", dst, err) } else if err == nil { @@ -153,10 +153,15 @@ func removeLink(binDir string, plugin string) error { return nil } -func pluginNameToBin(name string) string { - if runtime.GOOS == "windows" && !strings.HasSuffix(name, ".exe") { +func isWindows() bool { return runtime.GOOS == "windows" } + +// pluginNameToBin creates the name of the symlink file for the plugin name. +// It converts dashes to underscores. +func pluginNameToBin(name string, isWindows bool) string { + name = strings.Replace(name, "-", "_", -1) + name = "kubectl-" + name + if isWindows { name = name + ".exe" } - - return "kubectl-" + name + return name } diff --git a/pkg/installation/install_test.go b/pkg/installation/install_test.go index cf3c04dc..30eae2de 100644 --- a/pkg/installation/install_test.go +++ b/pkg/installation/install_test.go @@ -123,3 +123,24 @@ func Test_createOrUpdateLink(t *testing.T) { }) } } + +func Test_pluginNameToBin(t *testing.T) { + + tests := []struct { + name string + isWindows bool + want string + }{ + {"foo", false, "kubectl-foo"}, + {"foo-bar", false, "kubectl-foo_bar"}, + {"foo", true, "kubectl-foo.exe"}, + {"foo-bar", true, "kubectl-foo_bar.exe"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := pluginNameToBin(tt.name, tt.isWindows); got != tt.want { + t.Errorf("pluginNameToBin(%v, %v) = %v; want %v", tt.name, tt.isWindows, got, tt.want) + } + }) + } +} diff --git a/pkg/installation/util.go b/pkg/installation/util.go index 59145676..532bdfd7 100644 --- a/pkg/installation/util.go +++ b/pkg/installation/util.go @@ -59,7 +59,7 @@ func findInstalledPluginVersion(installPath, binDir, pluginName string) (name st return "", false, fmt.Errorf("the plugin name %q is not allowed", pluginName) } glog.V(3).Infof("Searching for installed versions of %s in %q", pluginName, binDir) - link, err := os.Readlink(filepath.Join(binDir, pluginNameToBin(pluginName))) + link, err := os.Readlink(filepath.Join(binDir, pluginNameToBin(pluginName, isWindows()))) if os.IsNotExist(err) { return "", false, nil } else if err != nil {