Repository: helm/helm (go)

Issue:
helm v3 cannot show pre-release info
<!-- If you need help or think you have found a bug, please help us with your issue by entering the following information (otherwise you can delete this text): -->

Output of `helm version`:

version.BuildInfo{Version:"v3.1.0", GitCommit:"b29d20baf09943e134c2fa5e1e1cab3bf93315fa", GitTreeState:"clean", GoVersion:"go1.13.7"}

Output of `kubectl version`:

Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"06ad960bfd03b39c8310aaf92d1e7c12ce618213", GitTreeState:"clean", BuildDate:"2020-02-11T18:14:22Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.6", GitCommit:"72c30166b2105cd7d3350f2c28a219e6abcd79eb", GitTreeState:"clean", BuildDate:"2020-01-18T23:23:21Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"}

Cloud Provider/Platform (AKS, GKE, Minikube etc.): 

Rancher

`helm show` removed `--devel` flag in helm v3. `helm inspect` supported in helm v2.

Is it possible add it back in helm v3? 





Pull request description:
fix(show): Port --devel flag for show command
Port  PR #5141 to Helm v3 `show` command

Fixes #7658 

Patch:
diff --git a/cmd/helm/show.go b/cmd/helm/show.go
index a82ad2777..ac38ed5af 100644
--- a/cmd/helm/show.go
+++ b/cmd/helm/show.go
@@ -77,11 +77,7 @@ func newShowCmd(out io.Writer) *cobra.Command {
 		Args:  require.ExactArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			client.OutputFormat = action.ShowAll
-			cp, err := client.ChartPathOptions.LocateChart(args[0], settings)
-			if err != nil {
-				return err
-			}
-			output, err := client.Run(cp)
+			output, err := runShow(args, client)
 			if err != nil {
 				return err
 			}
@@ -97,11 +93,7 @@ func newShowCmd(out io.Writer) *cobra.Command {
 		Args:  require.ExactArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			client.OutputFormat = action.ShowValues
-			cp, err := client.ChartPathOptions.LocateChart(args[0], settings)
-			if err != nil {
-				return err
-			}
-			output, err := client.Run(cp)
+			output, err := runShow(args, client)
 			if err != nil {
 				return err
 			}
@@ -117,11 +109,7 @@ func newShowCmd(out io.Writer) *cobra.Command {
 		Args:  require.ExactArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			client.OutputFormat = action.ShowChart
-			cp, err := client.ChartPathOptions.LocateChart(args[0], settings)
-			if err != nil {
-				return err
-			}
-			output, err := client.Run(cp)
+			output, err := runShow(args, client)
 			if err != nil {
 				return err
 			}
@@ -137,11 +125,7 @@ func newShowCmd(out io.Writer) *cobra.Command {
 		Args:  require.ExactArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			client.OutputFormat = action.ShowReadme
-			cp, err := client.ChartPathOptions.LocateChart(args[0], settings)
-			if err != nil {
-				return err
-			}
-			output, err := client.Run(cp)
+			output, err := runShow(args, client)
 			if err != nil {
 				return err
 			}
@@ -152,8 +136,7 @@ func newShowCmd(out io.Writer) *cobra.Command {
 
 	cmds := []*cobra.Command{all, readmeSubCmd, valuesSubCmd, chartSubCmd}
 	for _, subCmd := range cmds {
-		addChartPathOptionsFlags(subCmd.Flags(), &client.ChartPathOptions)
-		showCommand.AddCommand(subCmd)
+		addShowFlags(showCommand, subCmd, client)
 
 		// Register the completion function for each subcommand
 		completion.RegisterValidArgsFunc(subCmd, validArgsFunc)
@@ -161,3 +144,25 @@ func newShowCmd(out io.Writer) *cobra.Command {
 
 	return showCommand
 }
+
+func addShowFlags(showCmd *cobra.Command, subCmd *cobra.Command, client *action.Show) {
+	f := subCmd.Flags()
+
+	f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
+	addChartPathOptionsFlags(f, &client.ChartPathOptions)
+	showCmd.AddCommand(subCmd)
+}
+
+func runShow(args []string, client *action.Show) (string, error) {
+	debug("Original chart version: %q", client.Version)
+	if client.Version == "" && client.Devel {
+		debug("setting version to >0.0.0-0")
+		client.Version = ">0.0.0-0"
+	}
+
+	cp, err := client.ChartPathOptions.LocateChart(args[0], settings)
+	if err != nil {
+		return "", err
+	}
+	return client.Run(cp)
+}
diff --git a/pkg/action/show.go b/pkg/action/show.go
index 14b59a5ea..cc85477cd 100644
--- a/pkg/action/show.go
+++ b/pkg/action/show.go
@@ -51,8 +51,9 @@ func (o ShowOutputFormat) String() string {
 //
 // It provides the implementation of 'helm show' and its respective subcommands.
 type Show struct {
-	OutputFormat ShowOutputFormat
 	ChartPathOptions
+	Devel        bool
+	OutputFormat ShowOutputFormat
 }
 
 // NewShow creates a new Show object with the given configuration.


Test patch:
diff --git a/cmd/helm/show_test.go b/cmd/helm/show_test.go
new file mode 100644
index 000000000..00d7c8145
--- /dev/null
+++ b/cmd/helm/show_test.go
@@ -0,0 +1,82 @@
+/*
+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 main
+
+import (
+	"fmt"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	"helm.sh/helm/v3/pkg/repo/repotest"
+)
+
+func TestShowPreReleaseChart(t *testing.T) {
+	srv, err := repotest.NewTempServer("testdata/testcharts/*.tgz*")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer srv.Stop()
+
+	if err := srv.LinkIndices(); err != nil {
+		t.Fatal(err)
+	}
+
+	tests := []struct {
+		name        string
+		args        string
+		flags       string
+		fail        bool
+		expectedErr string
+	}{
+		{
+			name:        "show pre-release chart",
+			args:        "test/pre-release-chart",
+			fail:        true,
+			expectedErr: "failed to download \"test/pre-release-chart\"",
+		},
+		{
+			name:  "show pre-release chart with 'devel' flag",
+			args:  "test/pre-release-chart",
+			flags: "--devel",
+			fail:  false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			outdir := srv.Root()
+			cmd := fmt.Sprintf("show all '%s' %s --repository-config %s --repository-cache %s",
+				tt.args,
+				tt.flags,
+				filepath.Join(outdir, "repositories.yaml"),
+				outdir,
+			)
+			//_, out, err := executeActionCommand(cmd)
+			_, _, err := executeActionCommand(cmd)
+			if err != nil {
+				if tt.fail {
+					if !strings.Contains(err.Error(), tt.expectedErr) {
+						t.Errorf("%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error())
+					}
+					return
+				}
+				t.Errorf("%q reported error: %s", tt.name, err)
+			}
+		})
+	}
+}