github.phpd.cn/thought-machine/please@v12.2.0+incompatible/src/utils/utils.go (about)

     1  // Package utils contains various utility functions and whatnot.
     2  package utils
     3  
     4  import (
     5  	"path"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"gopkg.in/op/go-logging.v1"
    10  
    11  	"cli"
    12  	"core"
    13  	"fs"
    14  )
    15  
    16  var log = logging.MustGetLogger("utils")
    17  
    18  // FindAllSubpackages finds all packages under a particular path.
    19  // Used to implement rules with ... where we need to know all possible packages
    20  // under that location.
    21  func FindAllSubpackages(config *core.Configuration, rootPath string, prefix string) <-chan string {
    22  	ch := make(chan string)
    23  	go func() {
    24  		if rootPath == "" {
    25  			rootPath = "."
    26  		}
    27  		if err := fs.Walk(rootPath, func(name string, isDir bool) error {
    28  			basename := path.Base(name)
    29  			if name == core.OutDir || (isDir && strings.HasPrefix(basename, ".") && name != ".") {
    30  				return filepath.SkipDir // Don't walk output or hidden directories
    31  			} else if isDir && !strings.HasPrefix(name, prefix) && !strings.HasPrefix(prefix, name) {
    32  				return filepath.SkipDir // Skip any directory without the prefix we're after (but not any directory beneath that)
    33  			} else if isABuildFile(basename, config) && !isDir {
    34  				dir, _ := path.Split(name)
    35  				ch <- strings.TrimRight(dir, "/")
    36  			} else if cli.ContainsString(name, config.Parse.ExperimentalDir) {
    37  				return filepath.SkipDir // Skip the experimental directory if it's set
    38  			}
    39  			// Check against blacklist
    40  			for _, dir := range config.Parse.BlacklistDirs {
    41  				if dir == basename || strings.HasPrefix(name, dir) {
    42  					return filepath.SkipDir
    43  				}
    44  			}
    45  			return nil
    46  		}); err != nil {
    47  			log.Fatalf("Failed to walk tree under %s; %s\n", rootPath, err)
    48  		}
    49  		close(ch)
    50  	}()
    51  	return ch
    52  }
    53  
    54  // isABuildFile returns true if given filename is a build file name.
    55  func isABuildFile(name string, config *core.Configuration) bool {
    56  	for _, buildFileName := range config.Parse.BuildFileName {
    57  		if name == buildFileName {
    58  			return true
    59  		}
    60  	}
    61  	return false
    62  }