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

Commit 89669d9

Browse files
committed
gps/verify: Add tests for LockSatisfaction
Also better prepare it for public consumption by exporting its members, renaming some methods and improving docs.
1 parent 4b02ee0 commit 89669d9

File tree

5 files changed

+391
-54
lines changed

5 files changed

+391
-54
lines changed

cmd/dep/ensure.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,19 +282,19 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project
282282
lock := p.ChangedLock
283283
if lock != nil {
284284
lsat := verify.LockSatisfiesInputs(p.Lock, p.Manifest, params.RootPackageTree)
285-
if !lsat.Passed() {
285+
if !lsat.Satisfied() {
286286
if ctx.Verbose {
287287
ctx.Out.Println("Gopkg.lock is out of sync with Gopkg.toml and project code:")
288-
for _, missing := range lsat.MissingImports() {
288+
for _, missing := range lsat.MissingImports {
289289
ctx.Out.Printf("\t%s is missing from input-imports\n", missing)
290290
}
291-
for _, excess := range lsat.ExcessImports() {
291+
for _, excess := range lsat.ExcessImports {
292292
ctx.Out.Printf("\t%s is in input-imports, but isn't imported\n", excess)
293293
}
294-
for pr, unmatched := range lsat.UnmatchedOverrides() {
294+
for pr, unmatched := range lsat.UnmetOverrides {
295295
ctx.Out.Printf("\t%s is at %s, which is not allowed by override %s\n", pr, unmatched.V, unmatched.C)
296296
}
297-
for pr, unmatched := range lsat.UnmatchedConstraints() {
297+
for pr, unmatched := range lsat.UnmetConstraints {
298298
ctx.Out.Printf("\t%s is at %s, which is not allowed by constraint %s\n", pr, unmatched.V, unmatched.C)
299299
}
300300
ctx.Out.Println()

cmd/dep/status.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ func (cmd *statusCommand) runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Proje
925925
})
926926

927927
lsat := verify.LockSatisfiesInputs(p.Lock, p.Manifest, params.RootPackageTree)
928-
if lsat.Passed() {
928+
if lsat.Satisfied() {
929929
// If these are equal, we're guaranteed that the lock is a transitively
930930
// complete picture of all deps. That eliminates the need for at least
931931
// some checks.

gps/verify/helper_types_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package verify
6+
7+
import (
8+
"github.com/golang/dep/gps"
9+
"github.com/golang/dep/gps/pkgtree"
10+
)
11+
12+
// mkPI creates a ProjectIdentifier with the ProjectRoot as the provided
13+
// string, and the Source unset.
14+
//
15+
// Call normalize() on the returned value if you need the Source to be be
16+
// equal to the ProjectRoot.
17+
func mkPI(root string) gps.ProjectIdentifier {
18+
return gps.ProjectIdentifier{
19+
ProjectRoot: gps.ProjectRoot(root),
20+
}
21+
}
22+
23+
type safeLock struct {
24+
p []gps.LockedProject
25+
i []string
26+
}
27+
28+
func (sl safeLock) InputImports() []string {
29+
return sl.i
30+
}
31+
32+
func (sl safeLock) Projects() []gps.LockedProject {
33+
return sl.p
34+
}
35+
36+
// simpleRootManifest exists so that we have a safe value to swap into solver
37+
// params when a nil Manifest is provided.
38+
type simpleRootManifest struct {
39+
c, ovr gps.ProjectConstraints
40+
ig *pkgtree.IgnoredRuleset
41+
req map[string]bool
42+
}
43+
44+
func (m simpleRootManifest) DependencyConstraints() gps.ProjectConstraints {
45+
return m.c
46+
}
47+
func (m simpleRootManifest) Overrides() gps.ProjectConstraints {
48+
return m.ovr
49+
}
50+
func (m simpleRootManifest) IgnoredPackages() *pkgtree.IgnoredRuleset {
51+
return m.ig
52+
}
53+
func (m simpleRootManifest) RequiredPackages() map[string]bool {
54+
return m.req
55+
}
56+
57+
func (m simpleRootManifest) dup() simpleRootManifest {
58+
m2 := simpleRootManifest{
59+
c: make(gps.ProjectConstraints),
60+
ovr: make(gps.ProjectConstraints),
61+
ig: pkgtree.NewIgnoredRuleset(m.ig.ToSlice()),
62+
req: make(map[string]bool),
63+
}
64+
65+
for k, v := range m.c {
66+
m2.c[k] = v
67+
}
68+
69+
for k, v := range m.ovr {
70+
m2.ovr[k] = v
71+
}
72+
73+
for k := range m.req {
74+
m2.req[k] = true
75+
}
76+
77+
return m2
78+
}

gps/verify/locksat.go

Lines changed: 41 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,26 @@ import (
99

1010
// LockSatisfaction holds the compound result of LockSatisfiesInputs, allowing
1111
// the caller to inspect each of several orthogonal possible types of failure.
12+
//
13+
// The zero value assumes that there was no input lock, which necessarily means
14+
// the inputs were not satisfied. This zero value means we err on the side of
15+
// failure.
1216
type LockSatisfaction struct {
13-
nolock bool
14-
missingPkgs, excessPkgs []string
15-
badovr, badconstraint map[gps.ProjectRoot]ConstraintMismatch
17+
// If LockExisted is false, it indicates that a nil gps.Lock was passed to
18+
// LockSatisfiesInputs().
19+
LockExisted bool
20+
// MissingImports is the set of import paths that were present in the
21+
// inputs but missing in the Lock.
22+
MissingImports []string
23+
// ExcessImports is the set of import paths that were present in the Lock
24+
// but absent from the inputs.
25+
ExcessImports []string
26+
// UnmatchedConstraints reports any normal, non-override constraint rules that
27+
// were not satisfied by the corresponding LockedProject in the Lock.
28+
UnmetConstraints map[gps.ProjectRoot]ConstraintMismatch
29+
// UnmatchedOverrides reports any override rules that were not satisfied by the
30+
// corresponding LockedProject in the Lock.
31+
UnmetOverrides map[gps.ProjectRoot]ConstraintMismatch
1632
}
1733

1834
// ConstraintMismatch is a two-tuple of a gps.Version, and a gps.Constraint that
@@ -30,9 +46,15 @@ type ConstraintMismatch struct {
3046
// compute package imports that may have been removed. Figuring out that
3147
// negative space would require exploring the entire graph to ensure there are
3248
// no in-edges for particular imports.
33-
func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree) LockSatisfaction {
49+
func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, ptree pkgtree.PackageTree) LockSatisfaction {
3450
if l == nil {
35-
return LockSatisfaction{nolock: true}
51+
return LockSatisfaction{}
52+
}
53+
54+
lsat := LockSatisfaction{
55+
LockExisted: true,
56+
UnmetOverrides: make(map[gps.ProjectRoot]ConstraintMismatch),
57+
UnmetConstraints: make(map[gps.ProjectRoot]ConstraintMismatch),
3658
}
3759

3860
var ig *pkgtree.IgnoredRuleset
@@ -42,7 +64,7 @@ func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree
4264
req = m.RequiredPackages()
4365
}
4466

45-
rm, _ := rpt.ToReachMap(true, true, false, ig)
67+
rm, _ := ptree.ToReachMap(true, true, false, ig)
4668
reach := rm.FlattenFn(paths.IsStandardImportPath)
4769

4870
inlock := make(map[string]bool, len(l.InputImports()))
@@ -68,11 +90,6 @@ func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree
6890
inlock[imp] = true
6991
}
7092

71-
lsat := LockSatisfaction{
72-
badovr: make(map[gps.ProjectRoot]ConstraintMismatch),
73-
badconstraint: make(map[gps.ProjectRoot]ConstraintMismatch),
74-
}
75-
7693
for ip := range ininputs {
7794
if !inlock[ip] {
7895
pkgDiff[ip] = missingFromLock
@@ -96,9 +113,9 @@ func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree
96113

97114
for ip, typ := range pkgDiff {
98115
if typ == missingFromLock {
99-
lsat.missingPkgs = append(lsat.missingPkgs, ip)
116+
lsat.MissingImports = append(lsat.MissingImports, ip)
100117
} else {
101-
lsat.excessPkgs = append(lsat.excessPkgs, ip)
118+
lsat.ExcessImports = append(lsat.ExcessImports, ip)
102119
}
103120
}
104121

@@ -110,7 +127,7 @@ func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree
110127

111128
if pp, has := ovr[pr]; has {
112129
if !pp.Constraint.Matches(lp.Version()) {
113-
lsat.badovr[pr] = ConstraintMismatch{
130+
lsat.UnmetOverrides[pr] = ConstraintMismatch{
114131
C: pp.Constraint,
115132
V: lp.Version(),
116133
}
@@ -121,7 +138,7 @@ func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree
121138
}
122139

123140
if pp, has := constraints[pr]; has && eff[string(pr)] && !pp.Constraint.Matches(lp.Version()) {
124-
lsat.badconstraint[pr] = ConstraintMismatch{
141+
lsat.UnmetConstraints[pr] = ConstraintMismatch{
125142
C: pp.Constraint,
126143
V: lp.Version(),
127144
}
@@ -131,57 +148,33 @@ func LockSatisfiesInputs(l gps.Lock, m gps.RootManifest, rpt pkgtree.PackageTree
131148
return lsat
132149
}
133150

134-
// Passed is a shortcut method that indicates whether there were any ways in
135-
// which the Lock did not satisfy the inputs. It will return true only if no
136-
// problems were found.
137-
func (ls LockSatisfaction) Passed() bool {
138-
if ls.nolock {
151+
// Satisfied is a shortcut method that indicates whether there were any ways in
152+
// which the Lock did not satisfy the inputs. It will return true only if the
153+
// Lock was satisfactory in all respects vis-a-vis the inputs.
154+
func (ls LockSatisfaction) Satisfied() bool {
155+
if !ls.LockExisted {
139156
return false
140157
}
141158

142-
if len(ls.missingPkgs) > 0 {
159+
if len(ls.MissingImports) > 0 {
143160
return false
144161
}
145162

146-
if len(ls.excessPkgs) > 0 {
163+
if len(ls.ExcessImports) > 0 {
147164
return false
148165
}
149166

150-
if len(ls.badovr) > 0 {
167+
if len(ls.UnmetOverrides) > 0 {
151168
return false
152169
}
153170

154-
if len(ls.badconstraint) > 0 {
171+
if len(ls.UnmetConstraints) > 0 {
155172
return false
156173
}
157174

158175
return true
159176
}
160177

161-
// MissingImports reports the set of import paths that were present in the
162-
// inputs but missing in the Lock.
163-
func (ls LockSatisfaction) MissingImports() []string {
164-
return ls.missingPkgs
165-
}
166-
167-
// ExcessImports reports the set of import paths that were present in the Lock
168-
// but absent from the inputs.
169-
func (ls LockSatisfaction) ExcessImports() []string {
170-
return ls.excessPkgs
171-
}
172-
173-
// UnmatchedOverrides reports any override rules that were not satisfied by the
174-
// corresponding LockedProject in the Lock.
175-
func (ls LockSatisfaction) UnmatchedOverrides() map[gps.ProjectRoot]ConstraintMismatch {
176-
return ls.badovr
177-
}
178-
179-
// UnmatchedConstraints reports any normal, non-override constraint rules that
180-
// were not satisfied by the corresponding LockedProject in the Lock.
181-
func (ls LockSatisfaction) UnmatchedConstraints() map[gps.ProjectRoot]ConstraintMismatch {
182-
return ls.badconstraint
183-
}
184-
185178
func findEffectualConstraints(m gps.Manifest, imports map[string]bool) map[string]bool {
186179
eff := make(map[string]bool)
187180
xt := radix.New()

0 commit comments

Comments
 (0)