Repository: helm/helm
Pull request #6778 (2019-10-24 15:06:58)

fix(repo/search): fix helm repo search command to display proper versions
**Description**
Fix the helm repo search command to display proper versions. 


Changes proposed in this pr:

- Adjust documentation to clearly state about installed/displayed versions.
- Introduce the `--devel` flag for `helm repo search` command.

**Current behavior:** 
```shell
# Searches only for stable releases, prerelease versions will be skipped
$ helm repo search 
 
# Searches for releases and prereleases (alpha, beta, and release candidate releases)
$ helm repo search --devel

# searches only for release in version 1.0.0
$ helm repo search --version 1.0.0
```
Signed-off-by: Mateusz Szostok <szostok.mateusz@gmail.com>

Fixes: https://github.com/helm/helm/issues/6712


Patch:
diff --git a/cmd/helm/install.go b/cmd/helm/install.go
index 6c6920daa..c80f8875d 100644
--- a/cmd/helm/install.go
+++ b/cmd/helm/install.go
@@ -93,9 +93,9 @@ A chart reference is a convenient way of referencing a chart in a chart reposito
 
 When you use a chart reference with a repo prefix ('example/mariadb'), Helm will look in the local
 configuration for a chart repository named 'example', and will then look for a
-chart in that repository whose name is 'mariadb'. It will install the latest
-version of that chart unless you also supply a version number with the
-'--version' flag.
+chart in that repository whose name is 'mariadb'. It will install the latest stable version of that chart 
+until you specify '--devel' flag to also include development version (alpha, beta, and release candidate releases), or  
+supply a version number with the '--version' flag.
 
 To see the list of chart repositories, use 'helm repo list'. To search for
 charts in a repository, use 'helm search'.
diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go
index 9a448f75f..8abcd1eb7 100644
--- a/cmd/helm/search_repo.go
+++ b/cmd/helm/search_repo.go
@@ -38,6 +38,20 @@ Search reads through all of the repositories configured on the system, and
 looks for matches. Search of these repositories uses the metadata stored on
 the system.
 
+It will display the latest stable versions of that chart until you specify '--devel' flag 
+to also include development versions (alpha, beta, and release candidate releases), or  
+supply a version number with the '--version' flag.
+
+Examples: 
+	# Searches only for stable releases, prerelease versions will be skipped
+	helm repo search 
+ 
+	# Searches for releases and prereleases (alpha, beta, and release candidate releases)
+	helm repo search --devel
+
+	# searches only for release in version 1.0.0
+	helm repo search --version 1.0.0
+
 Repositories are managed with 'helm repo' commands.
 `
 
@@ -47,6 +61,7 @@ const searchMaxScore = 25
 type searchRepoOptions struct {
 	versions     bool
 	regexp       bool
+	devel        bool
 	version      string
 	maxColWidth  uint
 	repoFile     string
@@ -71,6 +86,7 @@ func newSearchRepoCmd(out io.Writer) *cobra.Command {
 	f := cmd.Flags()
 	f.BoolVarP(&o.regexp, "regexp", "r", false, "use regular expressions for searching repositories you have added")
 	f.BoolVarP(&o.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line, for repositories you have added")
+	f.BoolVar(&o.devel, "devel", false, "use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
 	f.StringVar(&o.version, "version", "", "search using semantic versioning constraints on repositories you have added")
 	f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table")
 	bindOutputFlag(cmd, &o.outputFormat)
@@ -79,6 +95,8 @@ func newSearchRepoCmd(out io.Writer) *cobra.Command {
 }
 
 func (o *searchRepoOptions) run(out io.Writer, args []string) error {
+	o.setupSearchedVersion()
+
 	index, err := o.buildIndex(out)
 	if err != nil {
 		return err
@@ -104,6 +122,22 @@ func (o *searchRepoOptions) run(out io.Writer, args []string) error {
 	return o.outputFormat.Write(out, &repoSearchWriter{data, o.maxColWidth})
 }
 
+func (o *searchRepoOptions) setupSearchedVersion() {
+	debug("Original chart version: %q", o.version)
+
+	if o.version != "" {
+		return
+	}
+
+	if o.devel { // search for releases and prereleases (alpha, beta, and release candidate releases).
+		debug("setting version to >0.0.0-0")
+		o.version = ">0.0.0-0"
+	} else { // search only for stable releases, prerelease versions will be skip
+		debug("setting version to >0.0.0")
+		o.version = ">0.0.0"
+	}
+}
+
 func (o *searchRepoOptions) applyConstraint(res []*search.Result) ([]*search.Result, error) {
 	if len(o.version) == 0 {
 		return res, nil
diff --git a/cmd/helm/testdata/output/search-multiple.txt b/cmd/helm/testdata/output/search-multiple-stable-release.txt
similarity index 100%
rename from cmd/helm/testdata/output/search-multiple.txt
rename to cmd/helm/testdata/output/search-multiple-stable-release.txt
diff --git a/pkg/repo/index.go b/pkg/repo/index.go
index 8e8f56d47..b3703304f 100644
--- a/pkg/repo/index.go
+++ b/pkg/repo/index.go
@@ -147,7 +147,8 @@ func (i IndexFile) SortEntries() {
 
 // Get returns the ChartVersion for the given name.
 //
-// If version is empty, this will return the chart with the highest version.
+// If version is empty, this will return the chart with the latest stable version,
+// prerelease versions will be skipped.
 func (i IndexFile) Get(name, version string) (*ChartVersion, error) {
 	vs, ok := i.Entries[name]
 	if !ok {


Test patch:
diff --git a/cmd/helm/search_repo_test.go b/cmd/helm/search_repo_test.go
index 5e945e3b7..6ece55505 100644
--- a/cmd/helm/search_repo_test.go
+++ b/cmd/helm/search_repo_test.go
@@ -25,13 +25,13 @@ func TestSearchRepositoriesCmd(t *testing.T) {
 	repoCache := "testdata/helmhome/helm/repository"
 
 	tests := []cmdTestCase{{
-		name:   "search for 'alpine', expect two matches",
+		name:   "search for 'alpine', expect one match with latest stable version",
 		cmd:    "search repo alpine",
-		golden: "output/search-multiple.txt",
+		golden: "output/search-multiple-stable-release.txt",
 	}, {
-		name:   "search for 'alpine', expect two matches",
-		cmd:    "search repo alpine",
-		golden: "output/search-multiple.txt",
+		name:   "search for 'alpine', expect one match with newest development version",
+		cmd:    "search repo alpine --devel",
+		golden: "output/search-multiple-devel-release.txt",
 	}, {
 		name:   "search for 'alpine' with versions, expect three matches",
 		cmd:    "search repo alpine --versions",
diff --git a/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml b/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml
index aab74f742..429388fb8 100644
--- a/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml
+++ b/cmd/helm/testdata/helmhome/helm/repository/testing-index.yaml
@@ -25,6 +25,18 @@ entries:
       keywords: []
       maintainers: []
       icon: ""
+    - name: alpine
+      url: https://kubernetes-charts.storage.googleapis.com/alpine-0.3.0-rc.1.tgz
+      checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
+      home: https://helm.sh/helm
+      sources:
+        - https://github.com/helm/helm
+      version: 0.3.0-rc.1
+      appVersion: 3.0.0
+      description: Deploy a basic Alpine Linux pod
+      keywords: []
+      maintainers: []
+      icon: ""
   mariadb:
     - name: mariadb
       url: https://kubernetes-charts.storage.googleapis.com/mariadb-0.3.0.tgz
diff --git a/cmd/helm/testdata/output/search-multiple-devel-release.txt b/cmd/helm/testdata/output/search-multiple-devel-release.txt
new file mode 100644
index 000000000..7e29a8f7e
--- /dev/null
+++ b/cmd/helm/testdata/output/search-multiple-devel-release.txt
@@ -0,0 +1,2 @@
+NAME          	CHART VERSION	APP VERSION	DESCRIPTION                    
+testing/alpine	0.3.0-rc.1   	3.0.0      	Deploy a basic Alpine Linux pod