Repository: helm/helm
Pull request #10008 (2021-08-07 01:49:59)

Fix helm plugins behavior another way
Signed-off-by: yxxhero <aiopsclub@163.com>

<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Make sure to read the Contributing Guide before submitting your PR: https://github.com/helm/helm/blob/main/CONTRIBUTING.md
2. If this PR closes another issue, add 'closes #<issue number>' somewhere in the PR summary. GitHub will automatically close that issue when this PR gets merged. Alternatively, adding 'refs #<issue number>' will not close the issue, but help provide the reviewer more context.-->

**What this PR does / why we need it**:
fix: https://github.com/helm/helm/issues/9814 https://github.com/helm/helm/issues/9942
**Special notes for your reviewer**:

**If applicable**:
- [ ] this PR contains documentation
- [x] this PR contains unit tests
- [ ] this PR has been tested for backwards compatibility



Patch:
diff --git a/cmd/helm/completion.go b/cmd/helm/completion.go
index 310c915b8..880e77c57 100644
--- a/cmd/helm/completion.go
+++ b/cmd/helm/completion.go
@@ -72,16 +72,6 @@ To load completions for every new session, execute once:
 You will need to start a new shell for this setup to take effect.
 `
 
-const powershellCompDesc = `
-Generate the autocompletion script for powershell.
-
-To load completions in your current shell session:
-PS C:\> helm completion powershell | Out-String | Invoke-Expression
-
-To load completions for every new session, add the output of the above command
-to your powershell profile.
-`
-
 const (
 	noDescFlagName = "no-descriptions"
 	noDescFlagText = "disable completion descriptions"
@@ -98,16 +88,16 @@ func newCompletionCmd(out io.Writer) *cobra.Command {
 	}
 
 	bash := &cobra.Command{
-		Use:               "bash",
-		Short:             "generate autocompletion script for bash",
-		Long:              bashCompDesc,
-		Args:              require.NoArgs,
-		ValidArgsFunction: noCompletions,
+		Use:                   "bash",
+		Short:                 "generate autocompletion script for bash",
+		Long:                  bashCompDesc,
+		Args:                  require.NoArgs,
+		DisableFlagsInUseLine: true,
+		ValidArgsFunction:     noCompletions,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			return runCompletionBash(out, cmd)
 		},
 	}
-	bash.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)
 
 	zsh := &cobra.Command{
 		Use:               "zsh",
@@ -133,25 +123,13 @@ func newCompletionCmd(out io.Writer) *cobra.Command {
 	}
 	fish.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)
 
-	powershell := &cobra.Command{
-		Use:               "powershell",
-		Short:             "generate autocompletion script for powershell",
-		Long:              powershellCompDesc,
-		Args:              require.NoArgs,
-		ValidArgsFunction: noCompletions,
-		RunE: func(cmd *cobra.Command, args []string) error {
-			return runCompletionPowershell(out, cmd)
-		},
-	}
-	powershell.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)
-
-	cmd.AddCommand(bash, zsh, fish, powershell)
+	cmd.AddCommand(bash, zsh, fish)
 
 	return cmd
 }
 
 func runCompletionBash(out io.Writer, cmd *cobra.Command) error {
-	err := cmd.Root().GenBashCompletionV2(out, !disableCompDescriptions)
+	err := cmd.Root().GenBashCompletion(out)
 
 	// In case the user renamed the helm binary (e.g., to be able to run
 	// both helm2 and helm3), we hook the new binary name to the completion function
@@ -202,13 +180,6 @@ func runCompletionFish(out io.Writer, cmd *cobra.Command) error {
 	return cmd.Root().GenFishCompletion(out, !disableCompDescriptions)
 }
 
-func runCompletionPowershell(out io.Writer, cmd *cobra.Command) error {
-	if disableCompDescriptions {
-		return cmd.Root().GenPowerShellCompletion(out)
-	}
-	return cmd.Root().GenPowerShellCompletionWithDesc(out)
-}
-
 // Function to disable file completion
 func noCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
 	return nil, cobra.ShellCompDirectiveNoFileComp
diff --git a/pkg/plugin/installer/base.go b/pkg/plugin/installer/base.go
index dcc3ad644..ba6a55d55 100644
--- a/pkg/plugin/installer/base.go
+++ b/pkg/plugin/installer/base.go
@@ -18,16 +18,22 @@ package installer // import "helm.sh/helm/v3/pkg/plugin/installer"
 import (
 	"path/filepath"
 
-	"helm.sh/helm/v3/pkg/helmpath"
+	"helm.sh/helm/v3/pkg/cli"
 )
 
 type base struct {
 	// Source is the reference to a plugin
 	Source string
+	// PluginsDirectory is the directory where plugins are installed
+	PluginsDirectory string
 }
 
 func newBase(source string) base {
-	return base{source}
+	settings := cli.New()
+	return base{
+		Source:           source,
+		PluginsDirectory: settings.PluginsDirectory,
+	}
 }
 
 // Path is where the plugin will be installed.
@@ -35,5 +41,5 @@ func (b *base) Path() string {
 	if b.Source == "" {
 		return ""
 	}
-	return helmpath.DataPath("plugins", filepath.Base(b.Source))
+	return filepath.Join(b.PluginsDirectory, filepath.Base(b.Source))
 }


Test patch:
diff --git a/internal/resolver/resolver_test.go b/internal/resolver/resolver_test.go
index 419f8f316..bc84ba952 100644
--- a/internal/resolver/resolver_test.go
+++ b/internal/resolver/resolver_test.go
@@ -16,7 +16,6 @@ limitations under the License.
 package resolver
 
 import (
-	"runtime"
 	"testing"
 
 	"helm.sh/helm/v3/pkg/chart"
@@ -247,28 +246,24 @@ func TestGetLocalPath(t *testing.T) {
 		repo      string
 		chartpath string
 		expect    string
-		winExpect string
 		err       bool
 	}{
 		{
-			name:      "absolute path",
-			repo:      "file:////",
-			expect:    "/",
-			winExpect: "\\",
+			name:   "absolute path",
+			repo:   "file:////tmp",
+			expect: "/tmp",
 		},
 		{
 			name:      "relative path",
 			repo:      "file://../../testdata/chartpath/base",
 			chartpath: "foo/bar",
 			expect:    "testdata/chartpath/base",
-			winExpect: "testdata\\chartpath\\base",
 		},
 		{
 			name:      "current directory path",
 			repo:      "../charts/localdependency",
 			chartpath: "testdata/chartpath/charts",
 			expect:    "testdata/chartpath/charts/localdependency",
-			winExpect: "testdata\\chartpath\\charts\\localdependency",
 		},
 		{
 			name:      "invalid local path",
@@ -296,12 +291,8 @@ func TestGetLocalPath(t *testing.T) {
 			if tt.err {
 				t.Fatalf("Expected error in test %q", tt.name)
 			}
-			expect := tt.expect
-			if runtime.GOOS == "windows" {
-				expect = tt.winExpect
-			}
-			if p != expect {
-				t.Errorf("%q: expected %q, got %q", tt.name, expect, p)
+			if p != tt.expect {
+				t.Errorf("%q: expected %q, got %q", tt.name, tt.expect, p)
 			}
 		})
 	}
diff --git a/pkg/plugin/installer/base_test.go b/pkg/plugin/installer/base_test.go
new file mode 100644
index 000000000..38ef28c3e
--- /dev/null
+++ b/pkg/plugin/installer/base_test.go
@@ -0,0 +1,48 @@
+/*
+Copyright The Helm Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package installer // import "helm.sh/helm/v3/pkg/plugin/installer"
+
+import (
+	"os"
+	"testing"
+)
+
+func TestPath(t *testing.T) {
+	tests := []struct {
+		source         string
+		helmPluginsDir string
+		expectPath     string
+	}{
+		{
+			source:         "",
+			helmPluginsDir: "/helm/data/plugins",
+			expectPath:     "",
+		}, {
+			source:         "https://github.com/jkroepke/helm-secrets",
+			helmPluginsDir: "/helm/data/plugins",
+			expectPath:     "/helm/data/plugins/helm-secrets",
+		},
+	}
+
+	for _, tt := range tests {
+
+		os.Setenv("HELM_PLUGINS", tt.helmPluginsDir)
+		baseIns := newBase(tt.source)
+		baseInsPath := baseIns.Path()
+		if baseInsPath != tt.expectPath {
+			t.Errorf("expected name %s, got %s", tt.expectPath, baseInsPath)
+		}
+		os.Unsetenv("HELM_PLUGINS")
+	}
+}