Repository: helm/helm
Pull request #8960 (2020-10-30 02:30:19)

Flag descriptions should start with lowercase
Standardizing new flag descriptions to start with a lower case letter like all the other flags.



Patch:
diff --git a/cmd/helm/root.go b/cmd/helm/root.go
index 23b8d7be6..4a0bc5bbd 100644
--- a/cmd/helm/root.go
+++ b/cmd/helm/root.go
@@ -62,8 +62,8 @@ Environment variables:
 | $HELM_REPOSITORY_CONFIG            | set the path to the repositories file.                                            |
 | $KUBECONFIG                        | set an alternative Kubernetes configuration file (default "~/.kube/config")       |
 | $HELM_KUBEAPISERVER                | set the Kubernetes API Server Endpoint for authentication                         |
-| $HELM_KUBEASGROUPS                 | set the Username to impersonate for the operation.                                |
-| $HELM_KUBEASUSER                   | set the Groups to use for impoersonation using a comma-separated list.            |
+| $HELM_KUBEASGROUPS                 | set the Groups to use for impersonation using a comma-separated list.             |
+| $HELM_KUBEASUSER                   | set the Username to impersonate for the operation.                                |
 | $HELM_KUBECONTEXT                  | set the name of the kubeconfig context.                                           |
 | $HELM_KUBETOKEN                    | set the Bearer KubeToken used for authentication.                                 |
 
diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go
index bf82a6051..a6ec16ea6 100644
--- a/cmd/helm/search_repo.go
+++ b/cmd/helm/search_repo.go
@@ -154,16 +154,26 @@ func (o *searchRepoOptions) applyConstraint(res []*search.Result) ([]*search.Res
 
 	data := res[:0]
 	foundNames := map[string]bool{}
+	appendSearchResults := func(res *search.Result) {
+		data = append(data, res)
+		if !o.versions {
+			foundNames[res.Name] = true // If user hasn't requested all versions, only show the latest that matches
+		}
+	}
 	for _, r := range res {
 		if _, found := foundNames[r.Name]; found {
 			continue
 		}
 		v, err := semver.NewVersion(r.Chart.Version)
-		if err != nil || constraint.Check(v) {
-			data = append(data, r)
-			if !o.versions {
-				foundNames[r.Name] = true // If user hasn't requested all versions, only show the latest that matches
+
+		if err != nil {
+			// If the current version number check appears ErrSegmentStartsZero or ErrInvalidPrerelease error and not devel mode, ingore
+			if (err == semver.ErrSegmentStartsZero || err == semver.ErrInvalidPrerelease) && !o.devel {
+				continue
 			}
+			appendSearchResults(r)
+		} else if constraint.Check(v) {
+			appendSearchResults(r)
 		}
 	}
 
diff --git a/pkg/action/package.go b/pkg/action/package.go
index 8f53bcac4..38dd1ac91 100644
--- a/pkg/action/package.go
+++ b/pkg/action/package.go
@@ -27,7 +27,6 @@ import (
 	"github.com/pkg/errors"
 	"golang.org/x/crypto/ssh/terminal"
 
-	"helm.sh/helm/v3/pkg/chart"
 	"helm.sh/helm/v3/pkg/chart/loader"
 	"helm.sh/helm/v3/pkg/chartutil"
 	"helm.sh/helm/v3/pkg/provenance"
@@ -64,9 +63,11 @@ func (p *Package) Run(path string, vals map[string]interface{}) (string, error)
 
 	// If version is set, modify the version.
 	if p.Version != "" {
-		if err := setVersion(ch, p.Version); err != nil {
-			return "", err
-		}
+		ch.Metadata.Version = p.Version
+	}
+
+	if err := validateVersion(ch.Metadata.Version); err != nil {
+		return "", err
 	}
 
 	if p.AppVersion != "" {
@@ -103,14 +104,11 @@ func (p *Package) Run(path string, vals map[string]interface{}) (string, error)
 	return name, err
 }
 
-func setVersion(ch *chart.Chart, ver string) error {
-	// Verify that version is a Version, and error out if it is not.
+// validateVersion Verify that version is a Version, and error out if it is not.
+func validateVersion(ver string) error {
 	if _, err := semver.NewVersion(ver); err != nil {
 		return err
 	}
-
-	// Set the version field on the chart.
-	ch.Metadata.Version = ver
 	return nil
 }
 
diff --git a/pkg/chartutil/validate_name.go b/pkg/chartutil/validate_name.go
index 22132c80e..913a477cf 100644
--- a/pkg/chartutil/validate_name.go
+++ b/pkg/chartutil/validate_name.go
@@ -17,6 +17,7 @@ limitations under the License.
 package chartutil
 
 import (
+	"fmt"
 	"regexp"
 
 	"github.com/pkg/errors"
@@ -39,11 +40,15 @@ var (
 	errMissingName = errors.New("no name provided")
 
 	// errInvalidName indicates that an invalid release name was provided
-	errInvalidName = errors.New("invalid release name, must match regex ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+$ and the length must not longer than 53")
+	errInvalidName = errors.New(fmt.Sprintf(
+		"invalid release name, must match regex %s and the length must not be longer than 53",
+		validName.String()))
 
 	// errInvalidKubernetesName indicates that the name does not meet the Kubernetes
 	// restrictions on metadata names.
-	errInvalidKubernetesName = errors.New("invalid metadata name, must match regex ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+$ and the length must not longer than 253")
+	errInvalidKubernetesName = errors.New(fmt.Sprintf(
+		"invalid metadata name, must match regex %s and the length must not be longer than 253",
+		validName.String()))
 )
 
 const (
diff --git a/pkg/cli/environment.go b/pkg/cli/environment.go
index 4f3abc08b..2202b02da 100644
--- a/pkg/cli/environment.go
+++ b/pkg/cli/environment.go
@@ -103,8 +103,8 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
 	fs.StringVar(&s.KubeConfig, "kubeconfig", "", "path to the kubeconfig file")
 	fs.StringVar(&s.KubeContext, "kube-context", s.KubeContext, "name of the kubeconfig context to use")
 	fs.StringVar(&s.KubeToken, "kube-token", s.KubeToken, "bearer token used for authentication")
-	fs.StringVar(&s.KubeAsUser, "kube-as-user", s.KubeAsUser, "Username to impersonate for the operation")
-	fs.StringArrayVar(&s.KubeAsGroups, "kube-as-group", s.KubeAsGroups, "Group to impersonate for the operation, this flag can be repeated to specify multiple groups.")
+	fs.StringVar(&s.KubeAsUser, "kube-as-user", s.KubeAsUser, "username to impersonate for the operation")
+	fs.StringArrayVar(&s.KubeAsGroups, "kube-as-group", s.KubeAsGroups, "group to impersonate for the operation, this flag can be repeated to specify multiple groups.")
 	fs.StringVar(&s.KubeAPIServer, "kube-apiserver", s.KubeAPIServer, "the address and the port for the Kubernetes API server")
 	fs.BoolVar(&s.Debug, "debug", s.Debug, "enable verbose output")
 	fs.StringVar(&s.RegistryConfig, "registry-config", s.RegistryConfig, "path to the registry config file")


Test patch:
diff --git a/cmd/helm/search_repo_test.go b/cmd/helm/search_repo_test.go
index 39c9c53f5..86519cd42 100644
--- a/cmd/helm/search_repo_test.go
+++ b/cmd/helm/search_repo_test.go
@@ -68,6 +68,14 @@ func TestSearchRepositoriesCmd(t *testing.T) {
 		name:   "search for 'maria', expect valid json output",
 		cmd:    "search repo maria --output json",
 		golden: "output/search-output-json.txt",
+	}, {
+		name:   "search for 'maria', expect one match with semver begin with zero development version",
+		cmd:    "search repo maria --devel",
+		golden: "output/search-semver-pre-zero-devel-release.txt",
+	}, {
+		name:   "search for 'nginx-ingress', expect one match with invalid development pre version",
+		cmd:    "search repo nginx-ingress --devel",
+		golden: "output/search-semver-pre-invalid-release.txt",
 	}, {
 		name:   "search for 'alpine', expect valid yaml output",
 		cmd:    "search repo alpine --output yaml",
diff --git a/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml b/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml
index e00e7de79..d76501e57 100644
--- a/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml
+++ b/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml
@@ -55,3 +55,33 @@ entries:
         - name: Bitnami
           email: containers@bitnami.com
       icon: ""
+    - name: mariadb
+      url: https://charts.helm.sh/stable/mariadb-0.3.0-0565674.tgz
+      checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56
+      home: https://mariadb.org
+      sources:
+        - https://github.com/bitnami/bitnami-docker-mariadb
+      version: 0.3.0-0565674
+      description: Chart for MariaDB
+      keywords:
+        - mariadb
+        - mysql
+        - database
+        - sql
+      maintainers:
+        - name: Bitnami
+          email: containers@bitnami.com
+      icon: ""
+  nginx-ingress:
+    - name: nginx-ingress
+      url: https://github.com/kubernetes/ingress-nginx/ingress-a.b.c.sdfsdf.tgz
+      checksum: 25229f6de44a2be9f215d11dbff31167ddc8ba56
+      home: https://github.com/kubernetes/ingress-nginx
+      sources:
+        - https://github.com/kubernetes/ingress-nginx
+      version: a.b.c.sdfsdf
+      description: Chart for nginx-ingress
+      keywords:
+        - ingress
+        - nginx
+      icon: ""
diff --git a/cmd/helm/testdata/output/search-semver-pre-invalid-release.txt b/cmd/helm/testdata/output/search-semver-pre-invalid-release.txt
new file mode 100644
index 000000000..ea39e2978
--- /dev/null
+++ b/cmd/helm/testdata/output/search-semver-pre-invalid-release.txt
@@ -0,0 +1,2 @@
+NAME                 	CHART VERSION	APP VERSION	DESCRIPTION            
+testing/nginx-ingress	a.b.c.sdfsdf 	           	Chart for nginx-ingress
diff --git a/cmd/helm/testdata/output/search-semver-pre-zero-devel-release.txt b/cmd/helm/testdata/output/search-semver-pre-zero-devel-release.txt
new file mode 100644
index 000000000..971c6523e
--- /dev/null
+++ b/cmd/helm/testdata/output/search-semver-pre-zero-devel-release.txt
@@ -0,0 +1,2 @@
+NAME           	CHART VERSION	APP VERSION	DESCRIPTION      
+testing/mariadb	0.3.0-0565674	           	Chart for MariaDB
diff --git a/pkg/action/package_test.go b/pkg/action/package_test.go
index 9a202cde4..5c5fed571 100644
--- a/pkg/action/package_test.go
+++ b/pkg/action/package_test.go
@@ -22,31 +22,11 @@ import (
 	"path"
 	"testing"
 
+	"github.com/Masterminds/semver/v3"
+
 	"helm.sh/helm/v3/internal/test/ensure"
-	"helm.sh/helm/v3/pkg/chart"
 )
 
-func TestSetVersion(t *testing.T) {
-	c := &chart.Chart{
-		Metadata: &chart.Metadata{
-			Name:    "prow",
-			Version: "0.0.1",
-		},
-	}
-	expect := "1.2.3-beta.5"
-	if err := setVersion(c, expect); err != nil {
-		t.Fatal(err)
-	}
-
-	if c.Metadata.Version != expect {
-		t.Errorf("Expected %q, got %q", expect, c.Metadata.Version)
-	}
-
-	if err := setVersion(c, "monkeyface"); err == nil {
-		t.Error("Expected bogus version to return an error.")
-	}
-}
-
 func TestPassphraseFileFetcher(t *testing.T) {
 	secret := "secret"
 	directory := ensure.TempFile(t, "passphrase-file", []byte(secret))
@@ -100,3 +80,46 @@ func TestPassphraseFileFetcher_WithInvalidStdin(t *testing.T) {
 		t.Error("Expected passphraseFileFetcher returning an error")
 	}
 }
+
+func TestValidateVersion(t *testing.T) {
+	type args struct {
+		ver string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr error
+	}{
+		{
+			"normal semver version",
+			args{
+				ver: "1.1.3-23658",
+			},
+			nil,
+		},
+		{
+			"Pre version number starting with 0",
+			args{
+				ver: "1.1.3-023658",
+			},
+			semver.ErrSegmentStartsZero,
+		},
+		{
+			"Invalid version number",
+			args{
+				ver: "1.1.3.sd.023658",
+			},
+			semver.ErrInvalidSemVer,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := validateVersion(tt.args.ver); err != nil {
+				if err != tt.wantErr {
+					t.Errorf("Expected {%v}, got {%v}", tt.wantErr, err)
+				}
+
+			}
+		})
+	}
+}