Merge pull request #82 from abates/feature/FollowSymlinks

Implementation for following symlinks
This commit is contained in:
Jim Teeuwen 2015-04-16 17:24:44 +02:00
commit 76a6418a0a
10 changed files with 92 additions and 4 deletions

View File

@ -28,9 +28,10 @@ func Translate(c *Config) error {
} }
var knownFuncs = make(map[string]int) var knownFuncs = make(map[string]int)
var visitedPaths = make(map[string]bool)
// Locate all the assets. // Locate all the assets.
for _, input := range c.Input { for _, input := range c.Input {
err = findFiles(input.Path, c.Prefix, input.Recursive, &toc, c.Ignore, knownFuncs) err = findFiles(input.Path, c.Prefix, input.Recursive, &toc, c.Ignore, knownFuncs, visitedPaths)
if err != nil { if err != nil {
return err return err
} }
@ -96,7 +97,7 @@ func (v ByName) Less(i, j int) bool { return v[i].Name() < v[j].Name() }
// findFiles recursively finds all the file paths in the given directory tree. // findFiles recursively finds all the file paths in the given directory tree.
// They are added to the given map as keys. Values will be safe function names // They are added to the given map as keys. Values will be safe function names
// for each file, which will be used when generating the output code. // for each file, which will be used when generating the output code.
func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regexp.Regexp, knownFuncs map[string]int) error { func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regexp.Regexp, knownFuncs map[string]int, visitedPaths map[string]bool) error {
if len(prefix) > 0 { if len(prefix) > 0 {
dir, _ = filepath.Abs(dir) dir, _ = filepath.Abs(dir)
prefix, _ = filepath.Abs(prefix) prefix, _ = filepath.Abs(prefix)
@ -114,6 +115,7 @@ func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regex
dir = "" dir = ""
list = []os.FileInfo{fi} list = []os.FileInfo{fi}
} else { } else {
visitedPaths[dir] = true
fd, err := os.Open(dir) fd, err := os.Open(dir)
if err != nil { if err != nil {
return err return err
@ -148,7 +150,23 @@ func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regex
if file.IsDir() { if file.IsDir() {
if recursive { if recursive {
findFiles(asset.Path, prefix, recursive, toc, ignore, knownFuncs) visitedPaths[asset.Path] = true
findFiles(asset.Path, prefix, recursive, toc, ignore, knownFuncs, visitedPaths)
}
continue
} else if file.Mode()&os.ModeSymlink == os.ModeSymlink {
var linkPath string
if linkPath, err = os.Readlink(asset.Path); err != nil {
return err
}
if !filepath.IsAbs(linkPath) {
if linkPath, err = filepath.Abs(dir + "/" + linkPath); err != nil {
return err
}
}
if _, ok := visitedPaths[linkPath]; !ok {
visitedPaths[linkPath] = true
findFiles(asset.Path, prefix, recursive, toc, ignore, knownFuncs, visitedPaths)
} }
continue continue
} }

View File

@ -2,6 +2,7 @@ package bindata
import ( import (
"regexp" "regexp"
"strings"
"testing" "testing"
) )
@ -17,7 +18,8 @@ func TestSafeFunctionName(t *testing.T) {
func TestFindFiles(t *testing.T) { func TestFindFiles(t *testing.T) {
var toc []Asset var toc []Asset
var knownFuncs = make(map[string]int) var knownFuncs = make(map[string]int)
err := findFiles("testdata/dupname", "testdata/dupname", true, &toc, []*regexp.Regexp{}, knownFuncs) var visitedPaths = make(map[string]bool)
err := findFiles("testdata/dupname", "testdata/dupname", true, &toc, []*regexp.Regexp{}, knownFuncs, visitedPaths)
if err != nil { if err != nil {
t.Errorf("expected to be no error: %+v", err) t.Errorf("expected to be no error: %+v", err)
} }
@ -25,3 +27,63 @@ func TestFindFiles(t *testing.T) {
t.Errorf("name collision") t.Errorf("name collision")
} }
} }
func TestFindFilesWithSymlinks(t *testing.T) {
var tocSrc []Asset
var tocTarget []Asset
var knownFuncs = make(map[string]int)
var visitedPaths = make(map[string]bool)
err := findFiles("testdata/symlinkSrc", "testdata/symlinkSrc", true, &tocSrc, []*regexp.Regexp{}, knownFuncs, visitedPaths)
if err != nil {
t.Errorf("expected to be no error: %+v", err)
}
knownFuncs = make(map[string]int)
visitedPaths = make(map[string]bool)
err = findFiles("testdata/symlinkParent", "testdata/symlinkParent", true, &tocTarget, []*regexp.Regexp{}, knownFuncs, visitedPaths)
if err != nil {
t.Errorf("expected to be no error: %+v", err)
}
if len(tocSrc) != len(tocTarget) {
t.Errorf("Symlink source and target should have the same number of assets. Expected %d got %d", len(tocTarget), len(tocSrc))
} else {
for i, _ := range tocSrc {
targetFunc := strings.TrimPrefix(tocTarget[i].Func, "symlinktarget_")
if tocSrc[i].Func != targetFunc {
t.Errorf("Symlink source and target produced different function lists. Expected %s to be %s", targetFunc, tocSrc[i].Func)
}
}
}
}
func TestFindFilesWithRecursiveSymlinks(t *testing.T) {
var toc []Asset
var knownFuncs = make(map[string]int)
var visitedPaths = make(map[string]bool)
err := findFiles("testdata/symlinkRecursiveParent", "testdata/symlinkRecursiveParent", true, &toc, []*regexp.Regexp{}, knownFuncs, visitedPaths)
if err != nil {
t.Errorf("expected to be no error: %+v", err)
}
if len(toc) != 1 {
t.Errorf("Only one asset should have been found. Got %d: %v", len(toc), toc)
}
}
func TestFindFilesWithSymlinkedFile(t *testing.T) {
var toc []Asset
var knownFuncs = make(map[string]int)
var visitedPaths = make(map[string]bool)
err := findFiles("testdata/symlinkFile", "testdata/symlinkFile", true, &toc, []*regexp.Regexp{}, knownFuncs, visitedPaths)
if err != nil {
t.Errorf("expected to be no error: %+v", err)
}
if len(toc) != 1 {
t.Errorf("Only one asset should have been found. Got %d: %v", len(toc), toc)
}
}

1
testdata/symlinkFile/file1 vendored Symbolic link
View File

@ -0,0 +1 @@
../symlinkSrc/file1

1
testdata/symlinkParent/symlinkTarget vendored Symbolic link
View File

@ -0,0 +1 @@
../symlinkSrc/

1
testdata/symlinkRecursiveParent/file1 vendored Normal file
View File

@ -0,0 +1 @@
// test file 1

View File

@ -0,0 +1 @@
../symlinkRecursiveParent/

1
testdata/symlinkSrc/file1 vendored Normal file
View File

@ -0,0 +1 @@
// symlink file 1

1
testdata/symlinkSrc/file2 vendored Normal file
View File

@ -0,0 +1 @@
// symlink file 2

1
testdata/symlinkSrc/file3 vendored Normal file
View File

@ -0,0 +1 @@
// symlink file 3

1
testdata/symlinkSrc/file4 vendored Normal file
View File

@ -0,0 +1 @@
// symlink file 4