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")
+ }
+}