github.com/strongmonkey/helm@v2.7.2+incompatible/cmd/helm/search.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "io" 22 "strings" 23 24 "github.com/Masterminds/semver" 25 "github.com/gosuri/uitable" 26 "github.com/spf13/cobra" 27 28 "k8s.io/helm/cmd/helm/search" 29 "k8s.io/helm/pkg/helm/helmpath" 30 "k8s.io/helm/pkg/repo" 31 ) 32 33 const searchDesc = ` 34 Search reads through all of the repositories configured on the system, and 35 looks for matches. 36 37 Repositories are managed with 'helm repo' commands. 38 ` 39 40 // searchMaxScore suggests that any score higher than this is not considered a match. 41 const searchMaxScore = 25 42 43 type searchCmd struct { 44 out io.Writer 45 helmhome helmpath.Home 46 47 versions bool 48 regexp bool 49 version string 50 } 51 52 func newSearchCmd(out io.Writer) *cobra.Command { 53 sc := &searchCmd{out: out} 54 55 cmd := &cobra.Command{ 56 Use: "search [keyword]", 57 Short: "search for a keyword in charts", 58 Long: searchDesc, 59 RunE: func(cmd *cobra.Command, args []string) error { 60 sc.helmhome = settings.Home 61 return sc.run(args) 62 }, 63 } 64 65 f := cmd.Flags() 66 f.BoolVarP(&sc.regexp, "regexp", "r", false, "use regular expressions for searching") 67 f.BoolVarP(&sc.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line") 68 f.StringVarP(&sc.version, "version", "v", "", "search using semantic versioning constraints") 69 70 return cmd 71 } 72 73 func (s *searchCmd) run(args []string) error { 74 index, err := s.buildIndex() 75 if err != nil { 76 return err 77 } 78 79 var res []*search.Result 80 if len(args) == 0 { 81 res = index.All() 82 } else { 83 q := strings.Join(args, " ") 84 res, err = index.Search(q, searchMaxScore, s.regexp) 85 if err != nil { 86 return nil 87 } 88 } 89 90 search.SortScore(res) 91 data, err := s.applyConstraint(res) 92 if err != nil { 93 return err 94 } 95 96 fmt.Fprintln(s.out, s.formatSearchResults(data)) 97 98 return nil 99 } 100 101 func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, error) { 102 if len(s.version) == 0 { 103 return res, nil 104 } 105 106 constraint, err := semver.NewConstraint(s.version) 107 if err != nil { 108 return res, fmt.Errorf("an invalid version/constraint format: %s", err) 109 } 110 111 data := res[:0] 112 for _, r := range res { 113 v, err := semver.NewVersion(r.Chart.Version) 114 if err != nil || constraint.Check(v) { 115 data = append(data, r) 116 } 117 } 118 119 return data, nil 120 } 121 122 func (s *searchCmd) formatSearchResults(res []*search.Result) string { 123 if len(res) == 0 { 124 return "No results found" 125 } 126 table := uitable.New() 127 table.MaxColWidth = 50 128 table.AddRow("NAME", "VERSION", "DESCRIPTION") 129 for _, r := range res { 130 table.AddRow(r.Name, r.Chart.Version, r.Chart.Description) 131 } 132 return table.String() 133 } 134 135 func (s *searchCmd) buildIndex() (*search.Index, error) { 136 // Load the repositories.yaml 137 rf, err := repo.LoadRepositoriesFile(s.helmhome.RepositoryFile()) 138 if err != nil { 139 return nil, err 140 } 141 142 i := search.NewIndex() 143 for _, re := range rf.Repositories { 144 n := re.Name 145 f := s.helmhome.CacheIndex(n) 146 ind, err := repo.LoadIndexFile(f) 147 if err != nil { 148 fmt.Fprintf(s.out, "WARNING: Repo %q is corrupt or missing. Try 'helm repo update'.", n) 149 continue 150 } 151 152 i.AddRepo(n, ind, s.versions) 153 } 154 return i, nil 155 }