Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

Commit

Permalink
Merge pull request #962 from darkowlzz/status-transitive-constraint
Browse files Browse the repository at this point in the history
fix(status): add constraint for locked projects
  • Loading branch information
sdboyer committed Nov 27, 2017
2 parents 7ccbfed + 1814fc3 commit 26f91c7
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 12 deletions.
60 changes: 53 additions & 7 deletions cmd/dep/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/golang/dep"
"github.com/golang/dep/gps"
"github.com/golang/dep/gps/paths"
"github.com/golang/dep/gps/pkgtree"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -389,7 +388,7 @@ func runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Project, sm gps.SourceMana
return false, 0, errors.Wrapf(err, "could not set up solver for input hashing")
}

cm := collectConstraints(ptree, p, sm)
cm := collectConstraints(ctx, p, sm)

// Get the project list and sort it so that the printed output users see is
// deterministically ordered. (This may be superfluous if the lock is always
Expand Down Expand Up @@ -461,7 +460,7 @@ func runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Project, sm gps.SourceMana
} else {
bs.Constraint = gps.Any()
for _, c := range cm[bs.ProjectRoot] {
bs.Constraint = c.Intersect(bs.Constraint)
bs.Constraint = c.Constraint.Intersect(bs.Constraint)
}
}

Expand All @@ -470,7 +469,12 @@ func runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Project, sm gps.SourceMana
if bs.Version != nil && bs.Version.Type() != gps.IsVersion {
c, has := p.Manifest.Constraints[proj.Ident().ProjectRoot]
if !has {
c.Constraint = gps.Any()
// Get constraint for locked project
for _, lockedP := range p.Lock.P {
if lockedP.Ident().ProjectRoot == proj.Ident().ProjectRoot {
c.Constraint = lockedP.Version()
}
}
}
// TODO: This constraint is only the constraint imposed by the
// current project, not by any transitive deps. As a result,
Expand Down Expand Up @@ -639,7 +643,49 @@ func formatVersion(v gps.Version) string {
return v.String()
}

func collectConstraints(ptree pkgtree.PackageTree, p *dep.Project, sm gps.SourceManager) map[string][]gps.Constraint {
// TODO
return map[string][]gps.Constraint{}
// projectConstraint stores ProjectRoot and Constraint for that project.
type projectConstraint struct {
Project gps.ProjectRoot
Constraint gps.Constraint
}

// constraintsCollection is a map of ProjectRoot(dependency) and a collection of
// projectConstraint for the dependencies. This can be used to find constraints
// on a dependency and the projects that apply those constraints.
type constraintsCollection map[string][]projectConstraint

// collectConstraints collects constraints declared by all the dependencies.
func collectConstraints(ctx *dep.Ctx, p *dep.Project, sm gps.SourceManager) constraintsCollection {
constraintCollection := make(constraintsCollection)

// Get direct deps of the root project.
_, directDeps, err := getDirectDependencies(sm, p)
if err != nil {
ctx.Err.Println("Error getting direct deps:", err)
}
// Create a root analyzer.
rootAnalyzer := newRootAnalyzer(false, ctx, directDeps, sm)

// Iterate through the locked projects and collect constraints of all the projects.
for _, proj := range p.Lock.Projects() {
manifest, _, err := sm.GetManifestAndLock(proj.Ident(), proj.Version(), rootAnalyzer)
if err != nil {
ctx.Err.Println("Error getting manifest and lock:", err)
continue
}

// Get project constraints.
pc := manifest.DependencyConstraints()

// Iterate through the project constraints to get individual dependency
// project and constraint values.
for pr, pp := range pc {
constraintCollection[string(pr)] = append(
constraintCollection[string(pr)],
projectConstraint{proj.Ident().ProjectRoot, pp.Constraint},
)
}
}

return constraintCollection
}
119 changes: 119 additions & 0 deletions cmd/dep/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ package main

import (
"bytes"
"io/ioutil"
"log"
"reflect"
"testing"
"text/tabwriter"

"strings"

"github.com/golang/dep"
"github.com/golang/dep/gps"
"github.com/golang/dep/internal/test"
)

func TestStatusFormatVersion(t *testing.T) {
Expand Down Expand Up @@ -287,3 +291,118 @@ func TestBasicStatusGetConsolidatedLatest(t *testing.T) {
})
}
}

func TestCollectConstraints(t *testing.T) {
ver1, _ := gps.NewSemverConstraintIC("v1.0.0")
ver08, _ := gps.NewSemverConstraintIC("v0.8.0")
ver2, _ := gps.NewSemverConstraintIC("v2.0.0")

cases := []struct {
name string
project dep.Project
wantConstraints constraintsCollection
}{
{
name: "without any constraints",
project: dep.Project{
Lock: &dep.Lock{
P: []gps.LockedProject{
gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/sdboyer/deptest")},
gps.NewVersion("v1.0.0"),
[]string{"."},
),
},
},
},
wantConstraints: constraintsCollection{},
},
{
name: "with multiple constraints",
project: dep.Project{
Lock: &dep.Lock{
P: []gps.LockedProject{
gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/sdboyer/deptest")},
gps.NewVersion("v1.0.0"),
[]string{"."},
),
gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-1")},
gps.NewVersion("v0.1.0"),
[]string{"."},
),
gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-2")},
gps.NewBranch("master").Pair(gps.Revision("824a8d56a4c6b2f4718824a98cd6d70d3dbd4c3e")),
[]string{"."},
),
},
},
},
wantConstraints: constraintsCollection{
"github.com/sdboyer/deptest": []projectConstraint{
{"github.com/darkowlzz/deptest-project-1", ver1},
{"github.com/darkowlzz/deptest-project-2", ver08},
},
"github.com/sdboyer/deptestdos": []projectConstraint{
{"github.com/darkowlzz/deptest-project-2", ver2},
},
"github.com/sdboyer/dep-test": []projectConstraint{
{"github.com/darkowlzz/deptest-project-2", ver1},
},
},
},
{
name: "skip projects with invalid versions",
project: dep.Project{
Lock: &dep.Lock{
P: []gps.LockedProject{
gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-1")},
gps.NewVersion("v0.1.0"),
[]string{"."},
),
gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-2")},
gps.NewVersion("v1.0.0"),
[]string{"."},
),
},
},
},
wantConstraints: constraintsCollection{
"github.com/sdboyer/deptest": []projectConstraint{
{"github.com/darkowlzz/deptest-project-1", ver1},
},
},
},
}

h := test.NewHelper(t)
defer h.Cleanup()

h.TempDir("src")
pwd := h.Path(".")
discardLogger := log.New(ioutil.Discard, "", 0)

ctx := &dep.Ctx{
GOPATH: pwd,
Out: discardLogger,
Err: discardLogger,
}

sm, err := ctx.SourceManager()
h.Must(err)
defer sm.Release()

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
gotConstraints := collectConstraints(ctx, &c.project, sm)

if !reflect.DeepEqual(gotConstraints, c.wantConstraints) {
t.Fatalf("Unexpected collected constraints: \n\t(GOT): %v\n\t(WNT): %v", gotConstraints, c.wantConstraints)
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"ProjectRoot":"github.com/sdboyer/deptest","Constraint":"^0.8.0","Version":"v0.8.0","Revision":"ff2948a2ac8f538c4ecd55962e919d1e13e74baf","Latest":"3f4c3bea144e112a69bbe5d8d01c1b09a544253f","PackageCount":1},{"ProjectRoot":"github.com/sdboyer/deptestdos","Constraint":"*","Version":"v2.0.0","Revision":"5c607206be5decd28e6263ffffdcee067266015e","Latest":"5c607206be5decd28e6263ffffdcee067266015e","PackageCount":1}]
[{"ProjectRoot":"github.com/sdboyer/deptest","Constraint":"^0.8.0","Version":"v0.8.0","Revision":"ff2948a2ac8f538c4ecd55962e919d1e13e74baf","Latest":"3f4c3bea144e112a69bbe5d8d01c1b09a544253f","PackageCount":1},{"ProjectRoot":"github.com/sdboyer/deptestdos","Constraint":"v2.0.0","Version":"v2.0.0","Revision":"5c607206be5decd28e6263ffffdcee067266015e","Latest":"5c607206be5decd28e6263ffffdcee067266015e","PackageCount":1}]
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
github.com/sdboyer/deptest ^0.8.0 v0.8.0 ff2948a 3f4c3be 1
github.com/sdboyer/deptestdos * v2.0.0 5c60720 5c60720 1
github.com/sdboyer/deptestdos v2.0.0 v2.0.0 5c60720 5c60720 1
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
github.com/sdboyer/deptest * (override) v0.8.1 3f4c3be ff2948a 1
github.com/sdboyer/deptestdos * v2.0.0 5c60720 5c60720 1
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
github.com/sdboyer/deptest v0.8.1 (override) v0.8.1 3f4c3be 3f4c3be 1
github.com/sdboyer/deptestdos v2.0.0 v2.0.0 5c60720 5c60720 1

0 comments on commit 26f91c7

Please sign in to comment.