github.com/rotblauer/buffalo@v0.7.1-0.20170112214545-7aa55ef80dd3/render/resolvers/recursive.go (about)

     1  package resolvers
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  )
    10  
    11  // RecursiveResolver will walk the tree of the specified RootPath
    12  // to resolve the given file name to the a path on disk. It is recommended
    13  // to scope this as tight as possible as it is possibly quite slow
    14  // the first time a file is requested. Once a file is found it's resolved
    15  // path is cached to prevent further slow resolutions.
    16  type RecursiveResolver struct {
    17  	Path  string
    18  	cache map[string]string
    19  }
    20  
    21  // Resolve will walk the tree of the specified RootPath
    22  // to resolve the given file name to the a path on disk. It is recommended
    23  // to scope this as tight as possible as it is possibly quite slow
    24  // the first time a file is requested. Once a file is found it's resolved
    25  // path is cached to prevent further slow resolutions.
    26  func (r *RecursiveResolver) Resolve(name string) (string, error) {
    27  	if r.cache == nil {
    28  		r.cache = map[string]string{}
    29  	}
    30  	if p, ok := r.cache[name]; ok {
    31  		return p, nil
    32  	}
    33  	var p string
    34  	var err error
    35  	var found bool
    36  	fmt.Printf("### r.Path -> %+v\n", r.Path)
    37  	fmt.Printf("### name -> %+v\n", name)
    38  	err = filepath.Walk(r.Path, func(path string, info os.FileInfo, err error) error {
    39  		if strings.HasSuffix(path, name) {
    40  			found = true
    41  			r.cache[name] = path
    42  			p = path
    43  			return err
    44  		}
    45  		return nil
    46  	})
    47  	if err != nil {
    48  		return p, err
    49  	}
    50  	if !found {
    51  		return p, fmt.Errorf("could not find file %s", name)
    52  	}
    53  	return p, nil
    54  }
    55  
    56  // Read will walk the tree of the specified RootPath
    57  // to resolve the given file name to the a path on disk. It is recommended
    58  // to scope this as tight as possible as it is possibly quite slow
    59  // the first time a file is requested. Once a file is found it's resolved
    60  // path is cached to prevent further slow resolutions.
    61  func (r *RecursiveResolver) Read(name string) ([]byte, error) {
    62  	p, err := r.Resolve(name)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	return ioutil.ReadFile(p)
    67  }