github.com/gofiber/fiber/v2@v2.47.0/internal/template/utils/utils.go (about)

     1  package utils
     2  
     3  import (
     4  	"io"
     5  	"net/http"
     6  	"os"
     7  	pathpkg "path"
     8  	"path/filepath"
     9  	"sort"
    10  )
    11  
    12  // Walk walks the filesystem rooted at root, calling walkFn for each file or
    13  // directory in the filesystem, including root. All errors that arise visiting files
    14  // and directories are filtered by walkFn. The files are walked in lexical
    15  // order.
    16  func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error {
    17  	info, err := stat(fs, root)
    18  	if err != nil {
    19  		return walkFn(root, nil, err)
    20  	}
    21  	return walk(fs, root, info, walkFn)
    22  }
    23  
    24  // #nosec G304
    25  // ReadFile returns the raw content of a file
    26  func ReadFile(path string, fs http.FileSystem) ([]byte, error) {
    27  	if fs != nil {
    28  		file, err := fs.Open(path)
    29  		if err != nil {
    30  			return nil, err
    31  		}
    32  		defer file.Close()
    33  		return io.ReadAll(file)
    34  	}
    35  	return os.ReadFile(path)
    36  }
    37  
    38  // readDirNames reads the directory named by dirname and returns
    39  // a sorted list of directory entries.
    40  func readDirNames(fs http.FileSystem, dirname string) ([]string, error) {
    41  	fis, err := readDir(fs, dirname)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	names := make([]string, len(fis))
    46  	for i := range fis {
    47  		names[i] = fis[i].Name()
    48  	}
    49  	sort.Strings(names)
    50  	return names, nil
    51  }
    52  
    53  // walk recursively descends path, calling walkFn.
    54  func walk(fs http.FileSystem, path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
    55  	err := walkFn(path, info, nil)
    56  	if err != nil {
    57  		if info.IsDir() && err == filepath.SkipDir {
    58  			return nil
    59  		}
    60  		return err
    61  	}
    62  
    63  	if !info.IsDir() {
    64  		return nil
    65  	}
    66  
    67  	names, err := readDirNames(fs, path)
    68  	if err != nil {
    69  		return walkFn(path, info, err)
    70  	}
    71  
    72  	for _, name := range names {
    73  		filename := pathpkg.Join(path, name)
    74  		fileInfo, err := stat(fs, filename)
    75  		if err != nil {
    76  			if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
    77  				return err
    78  			}
    79  		} else {
    80  			err = walk(fs, filename, fileInfo, walkFn)
    81  			if err != nil {
    82  				if !fileInfo.IsDir() || err != filepath.SkipDir {
    83  					return err
    84  				}
    85  			}
    86  		}
    87  	}
    88  	return nil
    89  }
    90  
    91  // readDir reads the contents of the directory associated with file and
    92  // returns a slice of FileInfo values in directory order.
    93  func readDir(fs http.FileSystem, name string) ([]os.FileInfo, error) {
    94  	f, err := fs.Open(name)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	defer f.Close()
    99  	return f.Readdir(0)
   100  }
   101  
   102  // stat returns the FileInfo structure describing file.
   103  func stat(fs http.FileSystem, name string) (os.FileInfo, error) {
   104  	f, err := fs.Open(name)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	defer f.Close()
   109  	return f.Stat()
   110  }