github.com/andrewlunde/glide@v0.20.1/action/no_vendor.go (about)

     1  package action
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/andrewlunde/glide/msg"
     9  )
    10  
    11  // NoVendor generates a list of source code directories, excepting `vendor/`.
    12  //
    13  // If "onlyGo" is true, only folders that have Go code in them will be returned.
    14  //
    15  // If suffix is true, this will append `/...` to every directory.
    16  func NoVendor(path string, onlyGo, suffix bool) {
    17  	// This is responsible for printing the results of noVend.
    18  	paths, err := noVend(path, onlyGo, suffix)
    19  	if err != nil {
    20  		msg.Err("Failed to walk file tree: %s", err)
    21  		msg.Warn("FIXME: NoVendor should exit with non-zero exit code.")
    22  		return
    23  	}
    24  
    25  	for _, p := range paths {
    26  		msg.Puts(p)
    27  	}
    28  }
    29  
    30  // noVend takes a directory and returns a list of Go-like files or directories,
    31  // provided the directory is not a vendor directory.
    32  //
    33  // If onlyGo is true, this will filter out all directories that do not contain
    34  // ".go" files.
    35  //
    36  // TODO: Should we move this to its own package?
    37  func noVend(path string, onlyGo, suffix bool) ([]string, error) {
    38  
    39  	info, err := os.Stat(path)
    40  	if err != nil {
    41  		return []string{}, err
    42  	}
    43  
    44  	if !info.IsDir() {
    45  		return []string{path}, nil
    46  	}
    47  
    48  	res := []string{}
    49  	f, err := os.Open(path)
    50  	if err != nil {
    51  		return res, err
    52  	}
    53  
    54  	fis, err := f.Readdir(0)
    55  	if err != nil {
    56  		return res, err
    57  	}
    58  
    59  	cur := false
    60  
    61  	for _, fi := range fis {
    62  		if exclude(fi) {
    63  			continue
    64  		}
    65  
    66  		full := filepath.Join(path, fi.Name())
    67  		if fi.IsDir() && !isVend(fi) {
    68  			p := "./" + full + "/..."
    69  			res = append(res, p)
    70  		} else if !fi.IsDir() && isGoish(fi) {
    71  			//res = append(res, full)
    72  			cur = true
    73  		}
    74  	}
    75  
    76  	// Filter out directories that do not contain Go code
    77  	if onlyGo {
    78  		res = hasGoSource(res, suffix)
    79  	}
    80  
    81  	if cur {
    82  		res = append(res, ".")
    83  	}
    84  
    85  	return res, nil
    86  }
    87  
    88  // hasGoSource returns a list of directories that contain Go source.
    89  func hasGoSource(dirs []string, suffix bool) []string {
    90  	suf := "/"
    91  	if suffix {
    92  		suf = "/..."
    93  	}
    94  	buf := []string{}
    95  	for _, d := range dirs {
    96  		d := filepath.Dir(d)
    97  		found := false
    98  		walker := func(p string, fi os.FileInfo, err error) error {
    99  			// Dumb optimization
   100  			if found {
   101  				return nil
   102  			}
   103  
   104  			// If the file ends with .go, report a match.
   105  			if strings.ToLower(filepath.Ext(p)) == ".go" {
   106  				found = true
   107  			}
   108  
   109  			return nil
   110  		}
   111  		filepath.Walk(d, walker)
   112  
   113  		if found {
   114  			buf = append(buf, "./"+d+suf)
   115  		}
   116  	}
   117  	return buf
   118  }
   119  
   120  // isVend returns true of this directory is a vendor directory.
   121  //
   122  // TODO: Should we return true for Godeps directory?
   123  func isVend(fi os.FileInfo) bool {
   124  	return fi.Name() == "vendor"
   125  }
   126  
   127  // exclude returns true if the directory should be excluded by Go toolchain tools.
   128  //
   129  // Examples: directories prefixed with '.' or '_'.
   130  func exclude(fi os.FileInfo) bool {
   131  	if strings.HasPrefix(fi.Name(), "_") {
   132  		return true
   133  	}
   134  	if strings.HasPrefix(fi.Name(), ".") {
   135  		return true
   136  	}
   137  	return false
   138  }
   139  
   140  // isGoish returns true if the file appears to be Go source.
   141  func isGoish(fi os.FileInfo) bool {
   142  	return filepath.Ext(fi.Name()) == ".go"
   143  }