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

Commit 26f91c7

Browse files
authored
Merge pull request #962 from darkowlzz/status-transitive-constraint
fix(status): add constraint for locked projects
2 parents 7ccbfed + 1814fc3 commit 26f91c7

File tree

5 files changed

+177
-12
lines changed

5 files changed

+177
-12
lines changed

cmd/dep/status.go

+53-7
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/golang/dep"
2020
"github.com/golang/dep/gps"
2121
"github.com/golang/dep/gps/paths"
22-
"github.com/golang/dep/gps/pkgtree"
2322
"github.com/pkg/errors"
2423
)
2524

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

392-
cm := collectConstraints(ptree, p, sm)
391+
cm := collectConstraints(ctx, p, sm)
393392

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

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

642-
func collectConstraints(ptree pkgtree.PackageTree, p *dep.Project, sm gps.SourceManager) map[string][]gps.Constraint {
643-
// TODO
644-
return map[string][]gps.Constraint{}
646+
// projectConstraint stores ProjectRoot and Constraint for that project.
647+
type projectConstraint struct {
648+
Project gps.ProjectRoot
649+
Constraint gps.Constraint
650+
}
651+
652+
// constraintsCollection is a map of ProjectRoot(dependency) and a collection of
653+
// projectConstraint for the dependencies. This can be used to find constraints
654+
// on a dependency and the projects that apply those constraints.
655+
type constraintsCollection map[string][]projectConstraint
656+
657+
// collectConstraints collects constraints declared by all the dependencies.
658+
func collectConstraints(ctx *dep.Ctx, p *dep.Project, sm gps.SourceManager) constraintsCollection {
659+
constraintCollection := make(constraintsCollection)
660+
661+
// Get direct deps of the root project.
662+
_, directDeps, err := getDirectDependencies(sm, p)
663+
if err != nil {
664+
ctx.Err.Println("Error getting direct deps:", err)
665+
}
666+
// Create a root analyzer.
667+
rootAnalyzer := newRootAnalyzer(false, ctx, directDeps, sm)
668+
669+
// Iterate through the locked projects and collect constraints of all the projects.
670+
for _, proj := range p.Lock.Projects() {
671+
manifest, _, err := sm.GetManifestAndLock(proj.Ident(), proj.Version(), rootAnalyzer)
672+
if err != nil {
673+
ctx.Err.Println("Error getting manifest and lock:", err)
674+
continue
675+
}
676+
677+
// Get project constraints.
678+
pc := manifest.DependencyConstraints()
679+
680+
// Iterate through the project constraints to get individual dependency
681+
// project and constraint values.
682+
for pr, pp := range pc {
683+
constraintCollection[string(pr)] = append(
684+
constraintCollection[string(pr)],
685+
projectConstraint{proj.Ident().ProjectRoot, pp.Constraint},
686+
)
687+
}
688+
}
689+
690+
return constraintCollection
645691
}

cmd/dep/status_test.go

+119
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ package main
66

77
import (
88
"bytes"
9+
"io/ioutil"
10+
"log"
11+
"reflect"
912
"testing"
1013
"text/tabwriter"
1114

1215
"strings"
1316

1417
"github.com/golang/dep"
1518
"github.com/golang/dep/gps"
19+
"github.com/golang/dep/internal/test"
1620
)
1721

1822
func TestStatusFormatVersion(t *testing.T) {
@@ -287,3 +291,118 @@ func TestBasicStatusGetConsolidatedLatest(t *testing.T) {
287291
})
288292
}
289293
}
294+
295+
func TestCollectConstraints(t *testing.T) {
296+
ver1, _ := gps.NewSemverConstraintIC("v1.0.0")
297+
ver08, _ := gps.NewSemverConstraintIC("v0.8.0")
298+
ver2, _ := gps.NewSemverConstraintIC("v2.0.0")
299+
300+
cases := []struct {
301+
name string
302+
project dep.Project
303+
wantConstraints constraintsCollection
304+
}{
305+
{
306+
name: "without any constraints",
307+
project: dep.Project{
308+
Lock: &dep.Lock{
309+
P: []gps.LockedProject{
310+
gps.NewLockedProject(
311+
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/sdboyer/deptest")},
312+
gps.NewVersion("v1.0.0"),
313+
[]string{"."},
314+
),
315+
},
316+
},
317+
},
318+
wantConstraints: constraintsCollection{},
319+
},
320+
{
321+
name: "with multiple constraints",
322+
project: dep.Project{
323+
Lock: &dep.Lock{
324+
P: []gps.LockedProject{
325+
gps.NewLockedProject(
326+
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/sdboyer/deptest")},
327+
gps.NewVersion("v1.0.0"),
328+
[]string{"."},
329+
),
330+
gps.NewLockedProject(
331+
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-1")},
332+
gps.NewVersion("v0.1.0"),
333+
[]string{"."},
334+
),
335+
gps.NewLockedProject(
336+
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-2")},
337+
gps.NewBranch("master").Pair(gps.Revision("824a8d56a4c6b2f4718824a98cd6d70d3dbd4c3e")),
338+
[]string{"."},
339+
),
340+
},
341+
},
342+
},
343+
wantConstraints: constraintsCollection{
344+
"github.com/sdboyer/deptest": []projectConstraint{
345+
{"github.com/darkowlzz/deptest-project-1", ver1},
346+
{"github.com/darkowlzz/deptest-project-2", ver08},
347+
},
348+
"github.com/sdboyer/deptestdos": []projectConstraint{
349+
{"github.com/darkowlzz/deptest-project-2", ver2},
350+
},
351+
"github.com/sdboyer/dep-test": []projectConstraint{
352+
{"github.com/darkowlzz/deptest-project-2", ver1},
353+
},
354+
},
355+
},
356+
{
357+
name: "skip projects with invalid versions",
358+
project: dep.Project{
359+
Lock: &dep.Lock{
360+
P: []gps.LockedProject{
361+
gps.NewLockedProject(
362+
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-1")},
363+
gps.NewVersion("v0.1.0"),
364+
[]string{"."},
365+
),
366+
gps.NewLockedProject(
367+
gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/darkowlzz/deptest-project-2")},
368+
gps.NewVersion("v1.0.0"),
369+
[]string{"."},
370+
),
371+
},
372+
},
373+
},
374+
wantConstraints: constraintsCollection{
375+
"github.com/sdboyer/deptest": []projectConstraint{
376+
{"github.com/darkowlzz/deptest-project-1", ver1},
377+
},
378+
},
379+
},
380+
}
381+
382+
h := test.NewHelper(t)
383+
defer h.Cleanup()
384+
385+
h.TempDir("src")
386+
pwd := h.Path(".")
387+
discardLogger := log.New(ioutil.Discard, "", 0)
388+
389+
ctx := &dep.Ctx{
390+
GOPATH: pwd,
391+
Out: discardLogger,
392+
Err: discardLogger,
393+
}
394+
395+
sm, err := ctx.SourceManager()
396+
h.Must(err)
397+
defer sm.Release()
398+
399+
for _, c := range cases {
400+
t.Run(c.name, func(t *testing.T) {
401+
gotConstraints := collectConstraints(ctx, &c.project, sm)
402+
403+
if !reflect.DeepEqual(gotConstraints, c.wantConstraints) {
404+
t.Fatalf("Unexpected collected constraints: \n\t(GOT): %v\n\t(WNT): %v", gotConstraints, c.wantConstraints)
405+
}
406+
})
407+
}
408+
}
Original file line numberDiff line numberDiff line change
@@ -1 +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}]
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 numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
22
github.com/sdboyer/deptest ^0.8.0 v0.8.0 ff2948a 3f4c3be 1
3-
github.com/sdboyer/deptestdos * v2.0.0 5c60720 5c60720 1
3+
github.com/sdboyer/deptestdos v2.0.0 v2.0.0 5c60720 5c60720 1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
2-
github.com/sdboyer/deptest * (override) v0.8.1 3f4c3be ff2948a 1
3-
github.com/sdboyer/deptestdos * v2.0.0 5c60720 5c60720 1
1+
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
2+
github.com/sdboyer/deptest v0.8.1 (override) v0.8.1 3f4c3be 3f4c3be 1
3+
github.com/sdboyer/deptestdos v2.0.0 v2.0.0 5c60720 5c60720 1

0 commit comments

Comments
 (0)