github.com/ernestokarim/closurer@v0.0.0-20130119214741-f245d086c750/scan/scan.go (about)

     1  package scan
     2  
     3  import (
     4  	"io/ioutil"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/ernestokarim/closurer/app"
     9  	"github.com/ernestokarim/closurer/config"
    10  )
    11  
    12  var (
    13  	libraryCache = map[string][]string{}
    14  )
    15  
    16  type visitor struct {
    17  	results []string
    18  }
    19  
    20  func (v *visitor) scan(file string, ext string) error {
    21  	ls, err := ioutil.ReadDir(file)
    22  	if err != nil {
    23  		return app.Error(err)
    24  	}
    25  
    26  	for _, entry := range ls {
    27  		fullpath := filepath.Join(file, entry.Name())
    28  
    29  		if entry.IsDir() {
    30  			if v.validDir(fullpath, entry.Name()) {
    31  				if err := v.scan(fullpath, ext); err != nil {
    32  					return err
    33  				}
    34  			}
    35  		} else if strings.HasSuffix(entry.Name(), ext) {
    36  			v.results = append(v.results, fullpath)
    37  		}
    38  	}
    39  
    40  	return nil
    41  }
    42  
    43  // Returns true if the directory name is worth scanning.
    44  // It checks too the list of ignored files.
    45  func (v *visitor) validDir(path, name string) bool {
    46  	conf := config.Current()
    47  	if conf.Ignores != nil && path != "" {
    48  		for _, ignore := range conf.Ignores {
    49  			if strings.HasPrefix(path, ignore.Path) {
    50  				return false
    51  			}
    52  		}
    53  	}
    54  
    55  	return name != ".svn" && name != ".hg" && name != ".git"
    56  }
    57  
    58  // Scans folder recursively search for files with the ext
    59  // extension and returns the whole list.
    60  func Do(folder string, ext string) ([]string, error) {
    61  	conf := config.Current()
    62  
    63  	var library bool
    64  	if conf.Library != nil {
    65  		library = strings.Contains(folder, conf.Library.Root)
    66  	}
    67  
    68  	if library {
    69  		r, ok := libraryCache[folder]
    70  		if ok {
    71  			return r, nil
    72  		}
    73  	}
    74  
    75  	v := &visitor{[]string{}}
    76  	if err := v.scan(folder, ext); err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	if library {
    81  		libraryCache[folder] = v.results
    82  	}
    83  
    84  	return v.results, nil
    85  }