Use dependency resolver for "glide list".
diff --git a/cmd/tree.go b/cmd/tree.go index 8983c4a..65456c5 100644 --- a/cmd/tree.go +++ b/cmd/tree.go
@@ -9,6 +9,8 @@ "strings" "github.com/Masterminds/cookoo" + "github.com/Masterminds/glide/dependency" + "github.com/Masterminds/glide/msg" ) // Tree prints a tree representing dependencies. @@ -40,40 +42,77 @@ // ListDeps lists all of the dependencies of the current project. // // Params: +// - dir (string): basedir +// - deep (bool): whether to do a deep scan or a shallow scan // // Returns: // func ListDeps(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) { - buildContext, err := GetBuildContext() - if err != nil { - return nil, err - } + //buildContext, err := GetBuildContext() + //if err != nil { + //return nil, err + //} basedir := p.Get("dir", ".").(string) - myName := guessPackageName(buildContext, basedir) + deep := p.Get("deep", true).(bool) + //myName := guessPackageName(buildContext, basedir) - basedir, err = filepath.Abs(basedir) + basedir, err := filepath.Abs(basedir) if err != nil { return nil, err } - direct := map[string]*pinfo{} - d := walkDeps(buildContext, basedir, myName) - for _, i := range d { - listDeps(buildContext, direct, i, basedir) + r, err := dependency.NewResolver(basedir) + if err != nil { + return nil, err + } + h := &dependency.DefaultMissingPackageHandler{Missing: []string{}, Gopath: []string{}} + r.Handler = h + + sortable, err := r.ResolveLocal(deep) + if err != nil { + return nil, err } - sortable := make([]string, len(direct)) - i := 0 - for k := range direct { - sortable[i] = k - i++ - } + /* + direct := map[string]*pinfo{} + d := walkDeps(buildContext, basedir, myName) + for _, i := range d { + listDeps(buildContext, direct, i, basedir) + } + + sortable := make([]string, len(direct)) + i := 0 + for k := range direct { + sortable[i] = k + i++ + } + */ sort.Strings(sortable) + fmt.Println("INSTALLED packages:") for _, k := range sortable { - t := direct[k].PType - fmt.Printf("%s (Location: %s)\n", k, ptypeString(t)) + //t := direct[k].PType + //fmt.Printf("%s (Location: %s)\n", k, ptypeString(t)) + v, err := filepath.Rel(basedir, k) + if err != nil { + msg.Warn("Failed to Rel path: %s", err) + v = k + } + fmt.Printf("\t%s\n", v) + } + + if len(h.Missing) > 0 { + fmt.Println("\nMISSING packages:") + for _, pkg := range h.Missing { + fmt.Printf("\t%s\n", pkg) + } + } + if len(h.Gopath) > 0 { + fmt.Println("\nGOPATH packages:") + for _, pkg := range h.Gopath { + fmt.Printf("\t%s\n", pkg) + } } return nil, nil
diff --git a/dependency/resolver.go b/dependency/resolver.go index a071fa4..21ac93a 100644 --- a/dependency/resolver.go +++ b/dependency/resolver.go
@@ -109,7 +109,7 @@ vdir := filepath.Join(basedir, "vendor") r := &Resolver{ - Handler: &DefaultMissingPackageHandler{Missing: []string{}}, + Handler: &DefaultMissingPackageHandler{Missing: []string{}, Gopath: []string{}}, basedir: basedir, VendorDir: vdir, BuildContext: build.Default, @@ -137,7 +137,7 @@ // there. func (r *Resolver) Resolve(pkg, basepath string) ([]string, error) { target := filepath.Join(basepath, pkg) - msg.Info("Scanning %s", target) + //msg.Debug("Scanning %s", target) l := list.New() l.PushBack(target) return r.resolveList(l) @@ -145,9 +145,12 @@ // ResolveLocal resolves dependencies for the current project. // -// This begins with the project, builds up a list of external dependencies, and -// then runs ResolveAll on those. -func (r *Resolver) ResolveLocal() ([]string, error) { +// This begins with the project, builds up a list of external dependencies. +// +// If the deep flag is set to true, this will then resolve all of the dependencies +// of the dependencies it has found. If not, it will return just the packages that +// the base project relies upon. +func (r *Resolver) ResolveLocal(deep bool) ([]string, error) { // We build a list of local source to walk, then send this list // to resolveList. l := list.New() @@ -178,18 +181,18 @@ if alreadySeen[imp] { continue } - msg.Info("Scanning %s", imp) alreadySeen[imp] = true info := r.FindPkg(imp) switch info.Loc { case LocUnknown, LocVendor: - msg.Info("adding pkg %s", imp) l.PushBack(filepath.Join(r.VendorDir, imp)) // Do we need a path on this? case LocGopath: - msg.Info("Checking for %s on %s", info.Path, r.basedir) if !strings.HasPrefix(info.Path, r.basedir) { - msg.Warn("YAY %s on %s", info.Path, r.basedir) - l.PushBack(imp) + // FIXME: This is a package outside of the project we're + // scanning. It should really be on vendor. But we don't + // want it to reference GOPATH. We want it to be detected + // and moved. + l.PushBack(filepath.Join(r.VendorDir, imp)) } } } @@ -202,7 +205,17 @@ return []string{}, err } - return r.resolveList(l) + if deep { + return r.resolveList(l) + } + + // If we're not doing a deep scan, we just convert the list into an + // array and return. + res := make([]string, 0, l.Len()) + for e := l.Front(); e != nil; e = e.Next() { + res = append(res, e.Value.(string)) + } + return res, nil } // ResolveAll takes a list of packages and returns an inclusive list of all @@ -228,8 +241,8 @@ var failedDep string for e := queue.Front(); e != nil; e = e.Next() { dep := e.Value.(string) - msg.Warn("#### %s ####", dep) - msg.Info("Seen Count: %d", len(r.seen)) + //msg.Warn("#### %s ####", dep) + //msg.Info("Seen Count: %d", len(r.seen)) // Catch the outtermost dependency. failedDep = dep err := filepath.Walk(dep, func(path string, fi os.FileInfo, err error) error { @@ -244,7 +257,6 @@ // Skip dirs that are not source. if !srcDir(fi) { //msg.Debug("Skip resource %s", fi.Name()) - msg.Info("Skip resource %s", fi.Name()) return filepath.SkipDir } @@ -286,8 +298,11 @@ if err != nil && !strings.HasPrefix(err.Error(), "no buildable Go source") { msg.Error("Could not find %s: %s", pkg, err) return err - } else if err != nil { - msg.Warn(err.Error()) + // NOTE: If we uncomment this, we get lots of "no buildable Go source" errors, + // which don't ever seem to be helpful. They don't actually indicate an error + // condition, and it's perfectly okay to run into that condition. + //} else if err != nil { + // msg.Warn(err.Error()) } for _, d := range deps { @@ -295,10 +310,6 @@ r.alreadyQ[d] = true queue.PushBack(d) } - //if _, ok := r.seen[d]; !ok { - //queue.PushBack(d) - ////r.seen[d] = true - //} } return nil }
diff --git a/dependency/resolver_test.go b/dependency/resolver_test.go index 80b1f38..bed414d 100644 --- a/dependency/resolver_test.go +++ b/dependency/resolver_test.go
@@ -3,28 +3,58 @@ import ( "os" "path/filepath" + "strings" "testing" "github.com/Masterminds/glide/yaml" ) -func TestResolveLocal(t *testing.T) { +func TestResolveLocalShallow(t *testing.T) { r, err := NewResolver("../") if err != nil { t.Fatal(err) } - l, err := r.ResolveLocal() + l, err := r.ResolveLocal(false) if err != nil { t.Fatalf("Failed to resolve: %s", err) } - for _, p := range l { - t.Log(p) + expect := []string{ + "github.com/Masterminds/cookoo", + "github.com/Masterminds/semver", + "github.com/Masterminds/vcs", + "gopkg.in/yaml.v2", + "github.com/codegangsta/cli", } - if len(l) != 12 { - t.Errorf("Expected 12 dep, got %d: %s", len(l)) + for _, p := range expect { + found := false + for _, li := range l { + if strings.HasSuffix(li, p) { + found = true + break + } + } + if !found { + t.Errorf("Could not find %s in resolved list.", p) + } + } +} + +func TestResolveLocalDeep(t *testing.T) { + r, err := NewResolver("../") + if err != nil { + t.Fatal(err) + } + + l, err := r.ResolveLocal(true) + if err != nil { + t.Fatalf("Failed to resolve: %s", err) + } + + if len(l) < 8 { + t.Errorf("Expected at least 8 deps, got %d: %s", len(l)) } } @@ -46,12 +76,11 @@ } func TestResolveAll(t *testing.T) { - t.Skip() // These are build dependencies of Glide, so we know they are here. deps := []*yaml.Dependency{ &yaml.Dependency{Name: "github.com/codegangsta/cli"}, &yaml.Dependency{Name: "github.com/Masterminds/cookoo"}, - &yaml.Dependency{Name: "github.com/Masterminds/squirrel"}, + &yaml.Dependency{Name: "github.com/Masterminds/semver"}, &yaml.Dependency{Name: "gopkg.in/yaml.v2"}, } @@ -64,17 +93,7 @@ t.Fatalf("Failed to resolve: %s", err) } - if len(l) < 3 { - t.Errorf("Expected len=3, got %d", len(l)) - } - - println("SEEN") - for k := range r.seen { - println(k) - } - println("RESULT") - - for _, v := range l { - println(v) + if len(l) < len(deps) { + t.Errorf("Expected at least %d deps, got %d", len(deps), len(l)) } }
diff --git a/glide.go b/glide.go index 0df3a4b..565a80a 100644 --- a/glide.go +++ b/glide.go
@@ -37,13 +37,9 @@ package main import ( - "io/ioutil" "path/filepath" "github.com/Masterminds/glide/cmd" - "github.com/Masterminds/glide/dependency" - "github.com/Masterminds/glide/msg" - "github.com/Masterminds/glide/yaml" "github.com/Masterminds/cookoo" "github.com/codegangsta/cli" @@ -429,25 +425,7 @@ vendor are only included if they are used by the project. `, Action: func(c *cli.Context) { - //setupHandler(c, "list", cxt, router) - fname := c.GlobalString("yaml") - //parse YAML - f, err := ioutil.ReadFile(fname) - if err != nil { - msg.Error("Failed to open %s: %s", fname, err) - } - gc, _ := yaml.FromYaml(string(f)) - r, err := dependency.NewResolver(".") - if err != nil { - msg.Error("Failed. %s", err) - } - res, err := r.ResolveAll(gc.Imports) - if err != nil { - msg.Error("Failed resolve: %s", err) - } - for _, r := range res { - msg.Puts("\t%s", r) - } + setupHandler(c, "list", cxt, router) }, }, {