github.com/banzaicloud/operator-tools@v0.28.10/pkg/docgen/lister.go (about) 1 // Copyright © 2020 Banzai Cloud 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package docgen 16 17 import ( 18 "io/ioutil" 19 "path/filepath" 20 "regexp" 21 "sort" 22 "strings" 23 24 "emperror.dev/errors" 25 "github.com/go-logr/logr" 26 "github.com/iancoleman/orderedmap" 27 ) 28 29 type SourceLister struct { 30 Logger logr.Logger 31 Sources map[string]SourceDir 32 IgnoredSources []string 33 IncludeSources []string 34 DefaultValueFromTagExtractor func(string) string 35 Index *Doc 36 DocGeneratedHook func(doc *Doc) error 37 Header string 38 Footer string 39 } 40 41 type DocIndex struct { 42 Path string 43 } 44 45 type SourceDir struct { 46 Path string 47 DestPath string 48 } 49 50 func NewSourceLister(sources map[string]SourceDir, logger logr.Logger) *SourceLister { 51 return &SourceLister{ 52 Logger: logger, 53 Sources: sources, 54 } 55 } 56 57 func (sl *SourceLister) ListSources() ([]DocItem, error) { 58 sourceList := []DocItem{} 59 60 for _, key := range orderedMap(sl.Sources).Keys() { 61 p := sl.Sources[key] 62 files, err := ioutil.ReadDir(p.Path) 63 if err != nil { 64 return nil, errors.WrapIff(err, "failed to read files from %s", p.Path) 65 } 66 for _, file := range files { 67 fname := strings.Replace(file.Name(), ".go", "", 1) 68 if filepath.Ext(file.Name()) == ".go" && (sl.isWhitelisted(fname) || !sl.isBlacklisted(fname)) { 69 fullPath := filepath.Join(p.Path, file.Name()) 70 sl.Logger.V(2).Info("included", "source", fname) 71 sourceList = append(sourceList, DocItem{ 72 Name: fname, 73 SourcePath: fullPath, 74 DestPath: p.DestPath, 75 DefaultValueFromTagExtractor: sl.DefaultValueFromTagExtractor, 76 Category: key, 77 }, 78 ) 79 } 80 } 81 } 82 83 return sourceList, nil 84 } 85 86 87 func (sl *SourceLister) isBlacklisted(source string) bool { 88 for _, p := range sl.IgnoredSources { 89 r := regexp.MustCompile(p) 90 if r.MatchString(source) { 91 sl.Logger.V(2).Info("blacklisted", "source", source) 92 return true 93 } 94 } 95 return false 96 } 97 98 func (sl *SourceLister) isWhitelisted(source string) bool { 99 for _, p := range sl.IncludeSources { 100 r := regexp.MustCompile(p) 101 if r.MatchString(source) { 102 sl.Logger.V(2).Info("whitelisted", "source", source) 103 return true 104 } 105 } 106 return false 107 } 108 109 func (lister *SourceLister) Generate() error { 110 lister.Index.Append(lister.Header) 111 112 sources, err := lister.ListSources() 113 if err != nil { 114 return errors.WrapIf(err, "failed to get plugin list") 115 } 116 117 for _, source := range sources { 118 document := GetDocumentParser(source, lister.Logger.WithName("docgen")) 119 if err := document.Generate(); err != nil { 120 return err 121 } 122 123 if lister.DocGeneratedHook != nil { 124 if err := lister.DocGeneratedHook(document); err != nil { 125 return err 126 } 127 } 128 } 129 130 lister.Index.Append(lister.Footer) 131 132 if err := lister.Index.Generate(); err != nil { 133 return err 134 } 135 136 return nil 137 } 138 139 func orderedMap(original map[string]SourceDir) *orderedmap.OrderedMap { 140 o := orderedmap.New() 141 for k, v := range original { 142 o.Set(k, v) 143 } 144 o.SortKeys(sort.Strings) 145 return o 146 }