From 7150fc3d9e06e1532b55399a328210637bce7865 Mon Sep 17 00:00:00 2001 From: Shane Starcher Date: Tue, 18 Apr 2017 18:10:42 -0400 Subject: [PATCH] bug(helm) - install/upgrade/search semver constraint support --- cmd/helm/search.go | 45 ++++++++++++++++++++++++++++--------- docs/helm/helm_search.md | 7 +++--- docs/man/man1/helm_search.1 | 6 ++++- pkg/repo/index.go | 19 +++++++++++++--- scripts/completions.bash | 3 +++ 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index a6ad7bbe4..4e7bbb2b3 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -21,6 +21,7 @@ import ( "io" "strings" + "github.com/Masterminds/semver" "github.com/gosuri/uitable" "github.com/spf13/cobra" @@ -45,6 +46,7 @@ type searchCmd struct { versions bool regexp bool + version string } func newSearchCmd(out io.Writer) *cobra.Command { @@ -62,6 +64,7 @@ func newSearchCmd(out io.Writer) *cobra.Command { f := cmd.Flags() f.BoolVarP(&sc.regexp, "regexp", "r", false, "use regular expressions for searching") f.BoolVarP(&sc.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line") + f.StringVarP(&sc.version, "version", "v", "", "search using semantic versioning constraints") return cmd } @@ -72,27 +75,47 @@ func (s *searchCmd) run(args []string) error { return err } + var res []*search.Result if len(args) == 0 { - s.showAllCharts(index) - return nil + res = index.All() + } else { + q := strings.Join(args, " ") + res, err = index.Search(q, searchMaxScore, s.regexp) + if err != nil { + return nil + } } - q := strings.Join(args, " ") - res, err := index.Search(q, searchMaxScore, s.regexp) + search.SortScore(res) + data, err := s.applyConstraint(res) if err != nil { - return nil + return err } - search.SortScore(res) - fmt.Fprintln(s.out, s.formatSearchResults(res)) + fmt.Fprintln(s.out, s.formatSearchResults(data)) return nil } -func (s *searchCmd) showAllCharts(i *search.Index) { - res := i.All() - search.SortScore(res) - fmt.Fprintln(s.out, s.formatSearchResults(res)) +func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, error) { + if len(s.version) == 0 { + return res, nil + } + + constraint, err := semver.NewConstraint(s.version) + if err != nil { + return res, fmt.Errorf("an invalid version/constraint format: %s", err) + } + + data := res[:0] + for _, r := range res { + v, err := semver.NewVersion(r.Chart.Version) + if err != nil || constraint.Check(v) { + data = append(data, r) + } + } + + return data, nil } func (s *searchCmd) formatSearchResults(res []*search.Result) string { diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md index 238f92298..6f1f8a645 100644 --- a/docs/helm/helm_search.md +++ b/docs/helm/helm_search.md @@ -19,8 +19,9 @@ helm search [keyword] ### Options ``` - -r, --regexp use regular expressions for searching - -l, --versions show the long listing, with each version of each chart on its own line + -r, --regexp use regular expressions for searching + -v, --version string search using semantic versioning constraints + -l, --versions show the long listing, with each version of each chart on its own line ``` ### Options inherited from parent commands @@ -36,4 +37,4 @@ helm search [keyword] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 16-Apr-2017 +###### Auto generated by spf13/cobra on 18-Apr-2017 diff --git a/docs/man/man1/helm_search.1 b/docs/man/man1/helm_search.1 index 639f957eb..7afc38a12 100644 --- a/docs/man/man1/helm_search.1 +++ b/docs/man/man1/helm_search.1 @@ -27,6 +27,10 @@ Repositories are managed with 'helm repo' commands. \fB\-r\fP, \fB\-\-regexp\fP[=false] use regular expressions for searching +.PP +\fB\-v\fP, \fB\-\-version\fP="" + search using semantic versioning constraints + .PP \fB\-l\fP, \fB\-\-versions\fP[=false] show the long listing, with each version of each chart on its own line @@ -61,4 +65,4 @@ Repositories are managed with 'helm repo' commands. .SH HISTORY .PP -16\-Apr\-2017 Auto generated by spf13/cobra +18\-Apr\-2017 Auto generated by spf13/cobra diff --git a/pkg/repo/index.go b/pkg/repo/index.go index 1ba5500d6..4e59b8d58 100644 --- a/pkg/repo/index.go +++ b/pkg/repo/index.go @@ -155,12 +155,25 @@ func (i IndexFile) Get(name, version string) (*ChartVersion, error) { if len(vs) == 0 { return nil, ErrNoChartVersion } + + var constraint *semver.Constraints if len(version) == 0 { - return vs[0], nil + constraint, _ = semver.NewConstraint("*") + } else { + var err error + constraint, err = semver.NewConstraint(version) + if err != nil { + return nil, err + } } + for _, ver := range vs { - // TODO: Do we need to normalize the version field with the SemVer lib? - if ver.Version == version { + test, err := semver.NewVersion(ver.Version) + if err != nil { + continue + } + + if constraint.Check(test) { return ver, nil } } diff --git a/scripts/completions.bash b/scripts/completions.bash index c7b4d7870..b1cd9fe43 100644 --- a/scripts/completions.bash +++ b/scripts/completions.bash @@ -1265,6 +1265,9 @@ _helm_search() flags+=("--regexp") flags+=("-r") local_nonpersistent_flags+=("--regexp") + flags+=("--version=") + two_word_flags+=("-v") + local_nonpersistent_flags+=("--version=") flags+=("--versions") flags+=("-l") local_nonpersistent_flags+=("--versions")