...

Source file src/sigs.k8s.io/kustomize/kyaml/fn/framework/parser/parser.go

Documentation: sigs.k8s.io/kustomize/kyaml/fn/framework/parser

     1  // Copyright 2021 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package parser
     5  
     6  import (
     7  	"io"
     8  	iofs "io/fs"
     9  	"path"
    10  	"strings"
    11  
    12  	"sigs.k8s.io/kustomize/kyaml/errors"
    13  )
    14  
    15  type parser struct {
    16  	fs         iofs.FS
    17  	paths      []string
    18  	extensions []string
    19  }
    20  
    21  type contentProcessor func(content []byte, name string) error
    22  
    23  func (l parser) parse(processContent contentProcessor) error {
    24  	for _, path := range l.paths {
    25  		if err := l.readPath(path, processContent); err != nil {
    26  			return err
    27  		}
    28  	}
    29  	return nil
    30  }
    31  
    32  func (l parser) readPath(path string, processContent contentProcessor) error {
    33  	f, err := l.fs.Open(path)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	defer f.Close()
    38  
    39  	info, err := f.Stat()
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	// File is directory -- read templates among its immediate children
    45  	if info.IsDir() {
    46  		dir, ok := f.(iofs.ReadDirFile)
    47  		if !ok {
    48  			return errors.Errorf("%s is a directory but could not be opened as one", path)
    49  		}
    50  		return l.readDir(dir, path, processContent)
    51  	}
    52  
    53  	// Path is a file -- check extension and read it
    54  	if err := checkExtension(path, l.extensions); err != nil {
    55  		return err
    56  	}
    57  	b, err := io.ReadAll(f)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	return processContent(b, path)
    62  }
    63  
    64  func checkExtension(path string, extensions []string) error {
    65  	for _, ext := range extensions {
    66  		if strings.HasSuffix(path, ext) {
    67  			return nil
    68  		}
    69  	}
    70  	return errors.Errorf("file %s does not have any of permitted extensions %s", path, extensions)
    71  }
    72  
    73  func (l parser) readDir(dir iofs.ReadDirFile, dirname string, processContent contentProcessor) error {
    74  	entries, err := dir.ReadDir(0)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	for _, entry := range entries {
    80  		if err := checkExtension(entry.Name(), l.extensions); err != nil || entry.IsDir() {
    81  			continue
    82  		}
    83  		// Note: using filepath.Join will break Windows, because io/fs.FS implementations require slashes on all OS.
    84  		// See https://golang.org/pkg/io/fs/#ValidPath
    85  		b, err := l.readFile(path.Join(dirname, entry.Name()))
    86  		if err != nil {
    87  			return err
    88  		}
    89  		if err := processContent(b, entry.Name()); err != nil {
    90  			return err
    91  		}
    92  	}
    93  	return nil
    94  }
    95  
    96  func (l parser) readFile(path string) ([]byte, error) {
    97  	f, err := l.fs.Open(path)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	defer f.Close()
   102  
   103  	content, err := io.ReadAll(f)
   104  	return content, errors.Wrap(err)
   105  }
   106  

View as plain text