Implementation for following symlinks
This is an implementation where findFiles will follow symlinks and keep track of paths already followed. No paths will be evaluated more than once, therefore preventing recursive link evaluation. Commit includes test cases and test data
This commit is contained in:
parent
f449dcd26c
commit
465fc29db9
24
convert.go
24
convert.go
|
@ -28,9 +28,10 @@ func Translate(c *Config) error {
|
|||
}
|
||||
|
||||
var knownFuncs = make(map[string]int)
|
||||
var visitedPaths = make(map[string]bool)
|
||||
// Locate all the assets.
|
||||
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 {
|
||||
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.
|
||||
// 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.
|
||||
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 {
|
||||
dir, _ = filepath.Abs(dir)
|
||||
prefix, _ = filepath.Abs(prefix)
|
||||
|
@ -114,6 +115,7 @@ func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regex
|
|||
dir = ""
|
||||
list = []os.FileInfo{fi}
|
||||
} else {
|
||||
visitedPaths[dir] = true
|
||||
fd, err := os.Open(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -148,7 +150,23 @@ func findFiles(dir, prefix string, recursive bool, toc *[]Asset, ignore []*regex
|
|||
|
||||
if file.IsDir() {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package bindata
|
|||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -17,7 +18,8 @@ func TestSafeFunctionName(t *testing.T) {
|
|||
func TestFindFiles(t *testing.T) {
|
||||
var toc []Asset
|
||||
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 {
|
||||
t.Errorf("expected to be no error: %+v", err)
|
||||
}
|
||||
|
@ -25,3 +27,63 @@ func TestFindFiles(t *testing.T) {
|
|||
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
1
testdata/symlinkFile/file1
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../symlinkSrc/file1
|
1
testdata/symlinkParent/symlinkTarget
vendored
Symbolic link
1
testdata/symlinkParent/symlinkTarget
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../symlinkSrc/
|
1
testdata/symlinkRecursiveParent/file1
vendored
Normal file
1
testdata/symlinkRecursiveParent/file1
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
// test file 1
|
1
testdata/symlinkRecursiveParent/symlinkTarget
vendored
Symbolic link
1
testdata/symlinkRecursiveParent/symlinkTarget
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../symlinkRecursiveParent/
|
1
testdata/symlinkSrc/file1
vendored
Normal file
1
testdata/symlinkSrc/file1
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
// symlink file 1
|
1
testdata/symlinkSrc/file2
vendored
Normal file
1
testdata/symlinkSrc/file2
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
// symlink file 2
|
1
testdata/symlinkSrc/file3
vendored
Normal file
1
testdata/symlinkSrc/file3
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
// symlink file 3
|
1
testdata/symlinkSrc/file4
vendored
Normal file
1
testdata/symlinkSrc/file4
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
// symlink file 4
|
Loading…
Reference in New Issue
Block a user