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  }