github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/pkg/filepathutil/list.go (about)

     1  package filepathutil
     2  
     3  import (
     4  	"fmt"
     5  	"io/fs"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"github.com/yargevad/filepathx"
    10  )
    11  
    12  // DefaultIgnores
    13  var (
    14  	DefaultIgnores = map[string]bool{
    15  		"node_modules": true,
    16  		".git":         true,
    17  	}
    18  )
    19  
    20  func ListRecursive(inp string) (all []string, err error) {
    21  
    22  	// TODO: possibly ignore here too, before calling listDir
    23  	if s, err := os.Stat(inp); err != nil || !s.IsDir() {
    24  		// File
    25  
    26  		// Use glob for unknowns (wildcard-paths) and existing files (non-dirs)
    27  		matches, err := filepathx.Glob(inp)
    28  		if err != nil {
    29  			return nil, fmt.Errorf("failed to glob %q: %w", inp, err)
    30  		}
    31  
    32  		for _, m := range matches {
    33  			s, err := os.Stat(m)
    34  			if err == nil && !s.IsDir() {
    35  
    36  				// Existing file
    37  				all = append(all, m)
    38  			} else {
    39  				// Directory
    40  				files, err := listDir(m)
    41  				if err != nil {
    42  					// TODO: handle error
    43  					return nil, fmt.Errorf("failed to list dir: %w", err)
    44  				}
    45  
    46  				all = append(all, files...)
    47  			}
    48  		}
    49  	} else {
    50  		// Directory
    51  		files, err := listDir(inp)
    52  		if err != nil {
    53  			return nil, fmt.Errorf("failed to list dir: %w", err)
    54  		}
    55  
    56  		all = append(all, files...)
    57  	}
    58  
    59  	return all, nil
    60  }
    61  
    62  var WalkedDirs = map[string]int{}
    63  
    64  func listDir(path string) ([]string, error) {
    65  
    66  	times := WalkedDirs[path]
    67  	WalkedDirs[path] = times + 1
    68  
    69  	var all []string
    70  	if err := filepath.WalkDir(path, func(p string, fi fs.DirEntry, err error) error {
    71  		if err != nil {
    72  			return err
    73  		}
    74  
    75  		// Skip default ignored
    76  		if fi.IsDir() && ignored(fi.Name()) {
    77  			return fs.SkipDir
    78  		}
    79  
    80  		// Skip dirs
    81  		if !fi.IsDir() {
    82  			all = append(all, p)
    83  		}
    84  
    85  		return nil
    86  	}); err != nil {
    87  		return nil, fmt.Errorf("failed to walk dir %q: %w", path, err)
    88  	}
    89  
    90  	return all, nil
    91  }
    92  
    93  func ignored(fileName string) bool {
    94  	return DefaultIgnores[fileName]
    95  }