Fixes #136: Fixed infinite recursion in list and tree commands
diff --git a/CHANGELOG.md b/CHANGELOG.md index 961103e..bd4c6e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,5 +1,6 @@ # Release 0.7.1 (xxxx-xx-xx) +- Fixed #136: Fixed infinite recursion in list and tree commands. - Fixed issue where glide guess listed a null parent. - Fixed #135: Hard failure when home directory not found for cache. - Fixed #137: Some messages not ending in "\n".
diff --git a/cmd/tree.go b/cmd/tree.go index 0a0297b..b521641 100644 --- a/cmd/tree.go +++ b/cmd/tree.go
@@ -1,6 +1,7 @@ package cmd import ( + "container/list" "fmt" "os" "path/filepath" @@ -30,7 +31,9 @@ } fmt.Println(myName) - displayTree(buildContext, basedir, myName, 1, showcore) + l := list.New() + l.PushBack(myName) + displayTree(buildContext, basedir, myName, 1, showcore, l) return nil, nil } @@ -87,12 +90,16 @@ default: info[name] = found for _, i := range walkDeps(b, found.Path, found.Name) { - listDeps(b, info, i, found.Path) + // Only walk the deps that are not already found to avoid + // infinite recursion. + if _, f := info[found.Name]; f == false { + listDeps(b, info, i, found.Path) + } } } } -func displayTree(b *BuildCtxt, basedir, myName string, level int, core bool) { +func displayTree(b *BuildCtxt, basedir, myName string, level int, core bool, l *list.List) { deps := walkDeps(b, basedir, myName) for _, name := range deps { found := findPkg(b, name, basedir) @@ -105,8 +112,17 @@ continue } fmt.Print(strings.Repeat("\t", level)) - fmt.Printf("%s (%s)\n", found.Name, found.Path) - displayTree(b, found.Path, found.Name, level+1, core) + + f := findInList(found.Name, l) + if f == true { + fmt.Printf("(Recursion) %s (%s)\n", found.Name, found.Path) + } else { + // Every branch in the tree is a copy to handle all the branches + cl := copyList(l) + cl.PushBack(found.Name) + fmt.Printf("%s (%s)\n", found.Name, found.Path) + displayTree(b, found.Path, found.Name, level+1, core, cl) + } } } @@ -249,3 +265,21 @@ } return false } + +func copyList(l *list.List) *list.List { + n := list.New() + for e := l.Front(); e != nil; e = e.Next() { + n.PushBack(e.Value.(string)) + } + return n +} + +func findInList(n string, l *list.List) bool { + for e := l.Front(); e != nil; e = e.Next() { + if e.Value.(string) == n { + return true + } + } + + return false +}
diff --git a/cmd/tree_test.go b/cmd/tree_test.go new file mode 100644 index 0000000..afa6667 --- /dev/null +++ b/cmd/tree_test.go
@@ -0,0 +1,23 @@ +package cmd + +import ( + "container/list" + "testing" +) + +func TestFindInTree(t *testing.T) { + l := list.New() + l.PushBack("github.com/Masterminds/glide") + l.PushBack("github.com/Masterminds/vcs") + l.PushBack("github.com/Masterminds/semver") + + f := findInList("foo", l) + if f != false { + t.Error("findInList found true instead of false") + } + + f = findInList("github.com/Masterminds/vcs", l) + if f != true { + t.Error("findInList found false instead of true") + } +}