verify: Relocate lock diffing and tree hashing

Both of these subsystems make more sense in the verification package
than in gps itself.
This commit is contained in:
sam boyer 2018-06-26 00:30:41 -04:00
Родитель bce4a363ac
Коммит 0b2482d688
6 изменённых файлов: 91 добавлений и 126 удалений

Просмотреть файл

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package pkgtree package verify
import ( import (
"bytes" "bytes"

Просмотреть файл

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package pkgtree package verify
import ( import (
"bytes" "bytes"

Просмотреть файл

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package pkgtree package verify
import ( import (
"os" "os"

Просмотреть файл

@ -1,3 +1,7 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package verify package verify
import ( import (
@ -13,11 +17,9 @@ import (
type VerifiableProject struct { type VerifiableProject struct {
gps.LockedProject gps.LockedProject
PruneOpts gps.PruneOptions PruneOpts gps.PruneOptions
Digest pkgtree.VersionedDigest Digest VersionedDigest
} }
type LockDiff struct{}
type lockUnsatisfy uint8 type lockUnsatisfy uint8
const ( const (

Просмотреть файл

@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package gps package verify
import ( import (
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
"github.com/golang/dep/gps"
) )
// StringDiff represents a modified string value. // StringDiff represents a modified string value.
@ -40,6 +42,21 @@ func (diff *StringDiff) String() string {
return diff.Current return diff.Current
} }
// sortLockedProjects returns a sorted copy of lps, or itself if already sorted.
func sortLockedProjects(lps []gps.LockedProject) []gps.LockedProject {
if len(lps) <= 1 || sort.SliceIsSorted(lps, func(i, j int) bool {
return lps[i].Ident().Less(lps[j].Ident())
}) {
return lps
}
cp := make([]gps.LockedProject, len(lps))
copy(cp, lps)
sort.Slice(cp, func(i, j int) bool {
return cp[i].Ident().Less(cp[j].Ident())
})
return cp
}
// LockDiff is the set of differences between an existing lock file and an updated lock file. // LockDiff is the set of differences between an existing lock file and an updated lock file.
// Fields are only populated when there is a difference, otherwise they are empty. // Fields are only populated when there is a difference, otherwise they are empty.
type LockDiff struct { type LockDiff struct {
@ -51,7 +68,7 @@ type LockDiff struct {
// LockedProjectDiff contains the before and after snapshot of a project reference. // LockedProjectDiff contains the before and after snapshot of a project reference.
// Fields are only populated when there is a difference, otherwise they are empty. // Fields are only populated when there is a difference, otherwise they are empty.
type LockedProjectDiff struct { type LockedProjectDiff struct {
Name ProjectRoot Name gps.ProjectRoot
Source *StringDiff Source *StringDiff
Version *StringDiff Version *StringDiff
Branch *StringDiff Branch *StringDiff
@ -61,13 +78,13 @@ type LockedProjectDiff struct {
// DiffLocks compares two locks and identifies the differences between them. // DiffLocks compares two locks and identifies the differences between them.
// Returns nil if there are no differences. // Returns nil if there are no differences.
func DiffLocks(l1 Lock, l2 Lock) *LockDiff { func DiffLocks(l1, l2 gps.Lock) *LockDiff {
// Default nil locks to empty locks, so that we can still generate a diff // Default nil locks to empty locks, so that we can still generate a diff
if l1 == nil { if l1 == nil {
l1 = &SimpleLock{} l1 = &gps.SimpleLock{}
} }
if l2 == nil { if l2 == nil {
l2 = &SimpleLock{} l2 = &gps.SimpleLock{}
} }
p1, p2 := l1.Projects(), l2.Projects() p1, p2 := l1.Projects(), l2.Projects()
@ -129,7 +146,7 @@ func DiffLocks(l1 Lock, l2 Lock) *LockDiff {
// DiffFor checks to see if there was a diff for the provided ProjectRoot. The // DiffFor checks to see if there was a diff for the provided ProjectRoot. The
// first return value is a 0 if there was no diff, 1 if it was added, 2 if it // first return value is a 0 if there was no diff, 1 if it was added, 2 if it
// was removed, and 3 if it was modified. // was removed, and 3 if it was modified.
func (ld *LockDiff) DiffFor(pr ProjectRoot) (uint8, LockedProjectDiff) { func (ld *LockDiff) DiffFor(pr gps.ProjectRoot) (uint8, LockedProjectDiff) {
for _, lpd := range ld.Add { for _, lpd := range ld.Add {
if lpd.Name == pr { if lpd.Name == pr {
return 1, lpd return 1, lpd
@ -151,9 +168,9 @@ func (ld *LockDiff) DiffFor(pr ProjectRoot) (uint8, LockedProjectDiff) {
return 0, LockedProjectDiff{} return 0, LockedProjectDiff{}
} }
func buildLockedProjectDiff(lp LockedProject) LockedProjectDiff { func buildLockedProjectDiff(lp gps.LockedProject) LockedProjectDiff {
s2 := lp.Ident().Source s2 := lp.Ident().Source
r2, b2, v2 := VersionComponentStrings(lp.Version()) r2, b2, v2 := gps.VersionComponentStrings(lp.Version())
var rev, version, branch, source *StringDiff var rev, version, branch, source *StringDiff
if s2 != "" { if s2 != "" {
@ -185,7 +202,7 @@ func buildLockedProjectDiff(lp LockedProject) LockedProjectDiff {
// DiffProjects compares two projects and identifies the differences between them. // DiffProjects compares two projects and identifies the differences between them.
// Returns nil if there are no differences. // Returns nil if there are no differences.
func DiffProjects(lp1 LockedProject, lp2 LockedProject) *LockedProjectDiff { func DiffProjects(lp1, lp2 gps.LockedProject) *LockedProjectDiff {
diff := LockedProjectDiff{Name: lp1.Ident().ProjectRoot} diff := LockedProjectDiff{Name: lp1.Ident().ProjectRoot}
s1 := lp1.Ident().Source s1 := lp1.Ident().Source
@ -194,8 +211,8 @@ func DiffProjects(lp1 LockedProject, lp2 LockedProject) *LockedProjectDiff {
diff.Source = &StringDiff{Previous: s1, Current: s2} diff.Source = &StringDiff{Previous: s1, Current: s2}
} }
r1, b1, v1 := VersionComponentStrings(lp1.Version()) r1, b1, v1 := gps.VersionComponentStrings(lp1.Version())
r2, b2, v2 := VersionComponentStrings(lp2.Version()) r2, b2, v2 := gps.VersionComponentStrings(lp2.Version())
if r1 != r2 { if r1 != r2 {
diff.Revision = &StringDiff{Previous: r1, Current: r2} diff.Revision = &StringDiff{Previous: r1, Current: r2}
} }

Просмотреть файл

@ -2,13 +2,26 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package gps package verify
import ( import (
"bytes" "bytes"
"testing" "testing"
"github.com/golang/dep/gps"
) )
// mkPI creates a ProjectIdentifier with the ProjectRoot as the provided
// string, and the Source unset.
//
// Call normalize() on the returned value if you need the Source to be be
// equal to the ProjectRoot.
func mkPI(root string) gps.ProjectIdentifier {
return gps.ProjectIdentifier{
ProjectRoot: gps.ProjectRoot(root),
}
}
func TestStringDiff_NoChange(t *testing.T) { func TestStringDiff_NoChange(t *testing.T) {
diff := StringDiff{Previous: "foo", Current: "foo"} diff := StringDiff{Previous: "foo", Current: "foo"}
want := "foo" want := "foo"
@ -45,8 +58,8 @@ func TestStringDiff_Modify(t *testing.T) {
} }
func TestDiffProjects_NoChange(t *testing.T) { func TestDiffProjects_NoChange(t *testing.T) {
p1 := NewLockedProject(mkPI("github.com/golang/dep/gps"), NewVersion("v0.10.0"), []string{"gps"}) p1 := gps.NewLockedProject(mkPI("github.com/golang/dep/gps"), gps.NewVersion("v0.10.0"), []string{"gps"})
p2 := NewLockedProject(mkPI("github.com/golang/dep/gps"), NewVersion("v0.10.0"), []string{"gps"}) p2 := gps.NewLockedProject(mkPI("github.com/golang/dep/gps"), gps.NewVersion("v0.10.0"), []string{"gps"})
diff := DiffProjects(p1, p2) diff := DiffProjects(p1, p2)
if diff != nil { if diff != nil {
@ -55,19 +68,9 @@ func TestDiffProjects_NoChange(t *testing.T) {
} }
func TestDiffProjects_Modify(t *testing.T) { func TestDiffProjects_Modify(t *testing.T) {
p1 := lockedProject{ p1 := gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewBranch("master").Pair("abc123"), []string{"baz", "qux"})
pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, p2 := gps.NewLockedProject(gps.ProjectIdentifier{ProjectRoot: "github.com/foo/bar", Source: "https://github.com/mcfork/gps.git"},
v: NewBranch("master"), gps.NewVersion("v1.0.0").Pair("def456"), []string{"baz", "derp"})
r: "abc123",
pkgs: []string{"baz", "qux"},
}
p2 := lockedProject{
pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar", Source: "https://github.com/mcfork/gps.git"},
v: NewVersion("v1.0.0"),
r: "def456",
pkgs: []string{"baz", "derp"},
}
diff := DiffProjects(p1, p2) diff := DiffProjects(p1, p2)
if diff == nil { if diff == nil {
@ -116,19 +119,9 @@ func TestDiffProjects_Modify(t *testing.T) {
} }
func TestDiffProjects_AddPackages(t *testing.T) { func TestDiffProjects_AddPackages(t *testing.T) {
p1 := lockedProject{ p1 := gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewBranch("master").Pair("abc123"), []string{"foobar"})
pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, p2 := gps.NewLockedProject(gps.ProjectIdentifier{ProjectRoot: "github.com/foo/bar", Source: "https://github.com/mcfork/gps.git"},
v: NewBranch("master"), gps.NewVersion("v1.0.0").Pair("def456"), []string{"bazqux", "foobar", "zugzug"})
r: "abc123",
pkgs: []string{"foobar"},
}
p2 := lockedProject{
pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar", Source: "https://github.com/mcfork/gps.git"},
v: NewVersion("v1.0.0"),
r: "def456",
pkgs: []string{"bazqux", "foobar", "zugzug"},
}
diff := DiffProjects(p1, p2) diff := DiffProjects(p1, p2)
if diff == nil { if diff == nil {
@ -153,19 +146,9 @@ func TestDiffProjects_AddPackages(t *testing.T) {
} }
func TestDiffProjects_RemovePackages(t *testing.T) { func TestDiffProjects_RemovePackages(t *testing.T) {
p1 := lockedProject{ p1 := gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewBranch("master").Pair("abc123"), []string{"athing", "foobar"})
pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, p2 := gps.NewLockedProject(gps.ProjectIdentifier{ProjectRoot: "github.com/foo/bar", Source: "https://github.com/mcfork/gps.git"},
v: NewBranch("master"), gps.NewVersion("v1.0.0").Pair("def456"), []string{"bazqux"})
r: "abc123",
pkgs: []string{"athing", "foobar"},
}
p2 := lockedProject{
pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar", Source: "https://github.com/mcfork/gps.git"},
v: NewVersion("v1.0.0"),
r: "def456",
pkgs: []string{"bazqux"},
}
diff := DiffProjects(p1, p2) diff := DiffProjects(p1, p2)
if diff == nil { if diff == nil {
@ -192,17 +175,11 @@ func TestDiffProjects_RemovePackages(t *testing.T) {
} }
func TestDiffLocks_NoChange(t *testing.T) { func TestDiffLocks_NoChange(t *testing.T) {
l1 := safeLock{ l1 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
},
} }
l2 := safeLock{ l2 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
},
} }
diff := DiffLocks(l1, l2) diff := DiffLocks(l1, l2)
@ -212,24 +189,14 @@ func TestDiffLocks_NoChange(t *testing.T) {
} }
func TestDiffLocks_AddProjects(t *testing.T) { func TestDiffLocks_AddProjects(t *testing.T) {
l1 := safeLock{ l1 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
},
} }
l2 := safeLock{ l2 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(gps.ProjectIdentifier{ProjectRoot: "github.com/baz/qux", Source: "https://github.com/mcfork/bazqux.git"},
p: []LockedProject{ gps.NewVersion("v0.5.0").Pair("def456"), []string{"p1", "p2"}),
lockedProject{ gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
pi: ProjectIdentifier{ProjectRoot: "github.com/baz/qux", Source: "https://github.com/mcfork/bazqux.git"}, gps.NewLockedProject(mkPI("github.com/zug/zug"), gps.NewVersion("v1.0.0"), nil),
v: NewVersion("v0.5.0"),
r: "def456",
pkgs: []string{"p1", "p2"},
},
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/zug/zug"}, v: NewVersion("v1.0.0")},
},
} }
diff := DiffLocks(l1, l2) diff := DiffLocks(l1, l2)
@ -296,23 +263,13 @@ func TestDiffLocks_AddProjects(t *testing.T) {
} }
func TestDiffLocks_RemoveProjects(t *testing.T) { func TestDiffLocks_RemoveProjects(t *testing.T) {
l1 := safeLock{ l1 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(gps.ProjectIdentifier{ProjectRoot: "github.com/a/thing", Source: "https://github.com/mcfork/athing.git"},
p: []LockedProject{ gps.NewBranch("master").Pair("def456"), []string{"p1", "p2"}),
lockedProject{ gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
pi: ProjectIdentifier{ProjectRoot: "github.com/a/thing", Source: "https://github.com/mcfork/athing.git"},
v: NewBranch("master"),
r: "def456",
pkgs: []string{"p1", "p2"},
},
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
},
} }
l2 := safeLock{ l2 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(mkPI("github.com/baz/qux"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/baz/qux"}, v: NewVersion("v1.0.0")},
},
} }
diff := DiffLocks(l1, l2) diff := DiffLocks(l1, l2)
@ -379,22 +336,16 @@ func TestDiffLocks_RemoveProjects(t *testing.T) {
} }
func TestDiffLocks_ModifyProjects(t *testing.T) { func TestDiffLocks_ModifyProjects(t *testing.T) {
l1 := safeLock{ l1 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{ gps.NewLockedProject(mkPI("github.com/foo/bu"), gps.NewVersion("v1.0.0"), nil),
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")}, gps.NewLockedProject(mkPI("github.com/zig/zag"), gps.NewVersion("v1.0.0"), nil),
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bu"}, v: NewVersion("v1.0.0")},
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/zig/zag"}, v: NewVersion("v1.0.0")},
},
} }
l2 := safeLock{ l2 := gps.SimpleLock{
//h: []byte("abc123"), gps.NewLockedProject(mkPI("github.com/baz/qux"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{ gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v2.0.0"), nil),
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/baz/qux"}, v: NewVersion("v1.0.0")}, gps.NewLockedProject(mkPI("github.com/zig/zag"), gps.NewVersion("v2.0.0"), nil),
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v2.0.0")}, gps.NewLockedProject(mkPI("github.com/zug/zug"), gps.NewVersion("v1.0.0"), nil),
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/zig/zag"}, v: NewVersion("v2.0.0")},
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/zug/zug"}, v: NewVersion("v1.0.0")},
},
} }
diff := DiffLocks(l1, l2) diff := DiffLocks(l1, l2)
@ -420,10 +371,8 @@ func TestDiffLocks_ModifyProjects(t *testing.T) {
} }
func TestDiffLocks_EmptyInitialLock(t *testing.T) { func TestDiffLocks_EmptyInitialLock(t *testing.T) {
l2 := safeLock{ l2 := gps.SimpleLock{
p: []LockedProject{ gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
},
} }
diff := DiffLocks(nil, l2) diff := DiffLocks(nil, l2)
@ -434,11 +383,8 @@ func TestDiffLocks_EmptyInitialLock(t *testing.T) {
} }
func TestDiffLocks_EmptyFinalLock(t *testing.T) { func TestDiffLocks_EmptyFinalLock(t *testing.T) {
l1 := safeLock{ l1 := gps.SimpleLock{
//h: h1, gps.NewLockedProject(mkPI("github.com/foo/bar"), gps.NewVersion("v1.0.0"), nil),
p: []LockedProject{
lockedProject{pi: ProjectIdentifier{ProjectRoot: "github.com/foo/bar"}, v: NewVersion("v1.0.0")},
},
} }
diff := DiffLocks(l1, nil) diff := DiffLocks(l1, nil)