Skip to content

Commit

Permalink
feat(helm): add --versions flag on search
Browse files Browse the repository at this point in the history
This causes search to index by name/version instead of just name, which
means you can get a list of versions of a chart. The '--versions' flag
enables this behavior.

Partially fixes helm#1199
  • Loading branch information
technosophos committed Oct 5, 2016
1 parent ea66d66 commit 6ded70b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 26 deletions.
20 changes: 7 additions & 13 deletions cmd/helm/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ type searchCmd struct {
out io.Writer
helmhome helmpath.Home

regexp bool
versions bool
regexp bool
}

func newSearchCmd(out io.Writer) *cobra.Command {
Expand All @@ -59,7 +60,9 @@ func newSearchCmd(out io.Writer) *cobra.Command {
PreRunE: requireInit,
}

cmd.Flags().BoolVarP(&sc.regexp, "regexp", "r", false, "use regular expressions for searching")
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.")

return cmd
}
Expand Down Expand Up @@ -88,16 +91,7 @@ func (s *searchCmd) run(args []string) error {
}

func (s *searchCmd) showAllCharts(i *search.Index) {
e := i.Entries()
res := make([]*search.Result, len(e))
j := 0
for name, ch := range e {
res[j] = &search.Result{
Name: name,
Chart: ch,
}
j++
}
res := i.All()
search.SortScore(res)
fmt.Fprintln(s.out, s.formatSearchResults(res))
}
Expand Down Expand Up @@ -129,7 +123,7 @@ func (s *searchCmd) buildIndex() (*search.Index, error) {
continue
}

i.AddRepo(n, ind)
i.AddRepo(n, ind, s.versions)
}
return i, nil
}
46 changes: 37 additions & 9 deletions cmd/helm/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,51 @@ func NewIndex() *Index {
return &Index{lines: map[string]string{}, charts: map[string]*repo.ChartVersion{}}
}

// verSep is a separator for version fields in map keys.
const verSep = "$$"

// AddRepo adds a repository index to the search index.
func (i *Index) AddRepo(rname string, ind *repo.IndexFile) {
func (i *Index) AddRepo(rname string, ind *repo.IndexFile, all bool) {
for name, ref := range ind.Entries {
if len(ref) == 0 {
// Skip chart names that havae zero releases.
// Skip chart names that have zero releases.
continue
}
// By convention, an index file is supposed to have the newest at the
// 0 slot, so our best bet is to grab the 0 entry and build the index
// entry off of that.
fname := filepath.Join(rname, name)
i.lines[fname] = indstr(rname, ref[0])
i.charts[fname] = ref[0]
if !all {
i.lines[fname] = indstr(rname, ref[0])
i.charts[fname] = ref[0]
continue
}

// If 'all' is set, then we go through all of the refs, and add them all
// to the index. This will generate a lot of near-duplicate entries.
for _, rr := range ref {
versionedName := fname + verSep + rr.Version
i.lines[versionedName] = indstr(rname, rr)
i.charts[versionedName] = rr
}
}
}

// Entries returns the entries in an index.
func (i *Index) Entries() map[string]*repo.ChartVersion {
return i.charts
// All returns all charts in the index as if they were search results.
//
// Each will be given a score of 0.
func (i *Index) All() []*Result {
res := make([]*Result, len(i.charts))
j := 0
for name, ch := range i.charts {
parts := strings.Split(name, verSep)
res[j] = &Result{
Name: parts[0],
Chart: ch,
}
j++
}
return res
}

// Search searches an index for the given term.
Expand Down Expand Up @@ -118,7 +144,8 @@ func (i *Index) SearchLiteral(term string, threshold int) []*Result {
for k, v := range i.lines {
res := strings.Index(v, term)
if score := i.calcScore(res, v); res != -1 && score < threshold {
buf = append(buf, &Result{Name: k, Score: score, Chart: i.charts[k]})
parts := strings.Split(k, verSep) // Remove version, if it is there.
buf = append(buf, &Result{Name: parts[0], Score: score, Chart: i.charts[k]})
}
}
return buf
Expand All @@ -137,7 +164,8 @@ func (i *Index) SearchRegexp(re string, threshold int) ([]*Result, error) {
continue
}
if score := i.calcScore(ind[0], v); ind[0] >= 0 && score < threshold {
buf = append(buf, &Result{Name: k, Score: score, Chart: i.charts[k]})
parts := strings.Split(k, verSep) // Remove version, if it is there.
buf = append(buf, &Result{Name: parts[0], Score: score, Chart: i.charts[k]})
}
}
return buf, nil
Expand Down
34 changes: 30 additions & 4 deletions cmd/helm/search/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ var indexfileEntries = map[string]repo.ChartVersions{
},
}

func loadTestIndex(t *testing.T) *Index {
func loadTestIndex(t *testing.T, all bool) *Index {
i := NewIndex()
i.AddRepo("testing", &repo.IndexFile{Entries: indexfileEntries})
i.AddRepo("testing", &repo.IndexFile{Entries: indexfileEntries}, all)
i.AddRepo("ztesting", &repo.IndexFile{Entries: map[string]repo.ChartVersions{
"pinta": {
{
Expand All @@ -107,10 +107,24 @@ func loadTestIndex(t *testing.T) *Index {
},
},
},
}})
}}, all)
return i
}

func TestAll(t *testing.T) {
i := loadTestIndex(t, false)
all := i.All()
if len(all) != 4 {
t.Errorf("Expected 4 entries, got %d", len(all))
}

i = loadTestIndex(t, true)
all = i.All()
if len(all) != 5 {
t.Errorf("Expected 5 entries, got %d", len(all))
}
}

func TestSearchByName(t *testing.T) {

tests := []struct {
Expand Down Expand Up @@ -188,7 +202,7 @@ func TestSearchByName(t *testing.T) {
},
}

i := loadTestIndex(t)
i := loadTestIndex(t, false)

for _, tt := range tests {

Expand Down Expand Up @@ -224,6 +238,18 @@ func TestSearchByName(t *testing.T) {
}
}

func TestSearchByNameAll(t *testing.T) {
// Test with the All bit turned on.
i := loadTestIndex(t, true)
cs, err := i.Search("santa-maria", 100, false)
if err != nil {
t.Fatal(err)
}
if len(cs) != 2 {
t.Errorf("expected 2 charts, got %d", len(cs))
}
}

func TestCalcScore(t *testing.T) {
i := NewIndex()

Expand Down

0 comments on commit 6ded70b

Please sign in to comment.