From a9836df57c505f2635934ef6a17d61746bd837b0 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 18 Oct 2016 00:39:37 -0400 Subject: [PATCH 1/2] Add basic Lock implementation --- lock.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lock_test.go | 68 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 lock.go create mode 100644 lock_test.go diff --git a/lock.go b/lock.go new file mode 100644 index 0000000000..05db30b321 --- /dev/null +++ b/lock.go @@ -0,0 +1,84 @@ +// Copyright 2016 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 main + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io" + + "github.com/sdboyer/gps" +) + +type Lock struct { + Memo []byte + P []gps.LockedProject +} + +type rawLock struct { + Memo string `json:"memo"` + P []lockedDep `json:"projects"` +} + +type lockedDep struct { + Name string `json:"name"` + Version string `json:"version,omitempty"` + Branch string `json:"branch,omitempty"` + Revision string `json:"revision"` + Repository string `json:"repo,omitempty"` + Packages []string `json:"packages"` +} + +func ReadLock(r io.Reader) (*Lock, error) { + rl := rawLock{} + err := json.NewDecoder(r).Decode(&rl) + if err != nil { + return nil, err + } + + b, err := hex.DecodeString(rl.Memo) + if err != nil { + return nil, fmt.Errorf("invalid hash digest in lock's memo field") + } + l := &Lock{ + Memo: b, + P: make([]gps.LockedProject, len(rl.P)), + } + + for k, ld := range rl.P { + r := gps.Revision(ld.Revision) + + var v gps.Version + if ld.Version != "" { + if ld.Branch != "" { + return nil, fmt.Errorf("lock file specified both a branch (%s) and version (%s) for %s", ld.Branch, ld.Version, ld.Name) + } + v = gps.NewVersion(ld.Version).Is(r) + } else if ld.Branch != "" { + v = gps.NewBranch(ld.Branch).Is(r) + } else if r == "" { + return nil, fmt.Errorf("lock file has entry for %s, but specifies no version", ld.Name) + } else { + v = r + } + + id := gps.ProjectIdentifier{ + ProjectRoot: gps.ProjectRoot(ld.Name), + NetworkName: ld.Repository, + } + l.P[k] = gps.NewLockedProject(id, v, ld.Packages) + } + + return l, nil +} + +func (l *Lock) InputHash() []byte { + return l.Memo +} + +func (l *Lock) Projects() []gps.LockedProject { + return l.P +} diff --git a/lock_test.go b/lock_test.go new file mode 100644 index 0000000000..ddaa68f015 --- /dev/null +++ b/lock_test.go @@ -0,0 +1,68 @@ +// Copyright 2016 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 main + +import ( + "encoding/hex" + "reflect" + "strings" + "testing" + + "github.com/sdboyer/gps" +) + +func TestReadLock(t *testing.T) { + const le = `{ + "memo": "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e", + "projects": [ + { + "name": "github.com/sdboyer/gps", + "branch": "master", + "version": "v0.12.0", + "revision": "d05d5aca9f895d19e9265839bffeadd74a2d2ecb", + "packages": ["."] + } + ] +}` + const lg = `{ + "memo": "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e", + "projects": [ + { + "name": "github.com/sdboyer/gps", + "branch": "master", + "revision": "d05d5aca9f895d19e9265839bffeadd74a2d2ecb", + "packages": ["."] + } + ] +}` + + _, err := ReadLock(strings.NewReader(le)) + if err == nil { + t.Error("Reading lock with invalid props should have caused error, but did not") + } else if !strings.Contains(err.Error(), "both a branch") { + t.Errorf("Unexpected error %q; expected multiple version error", err) + } + + l, err := ReadLock(strings.NewReader(lg)) + if err != nil { + t.Fatalf("Should have read Lock correctly, but got err %q", err) + } + + b, _ := hex.DecodeString("2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e") + l2 := &Lock{ + Memo: b, + P: []gps.LockedProject{ + gps.NewLockedProject( + gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/sdboyer/gps")}, + gps.NewBranch("master").Is(gps.Revision("d05d5aca9f895d19e9265839bffeadd74a2d2ecb")), + []string{"."}, + ), + }, + } + + if !reflect.DeepEqual(l, l2) { + t.Error("Valid lock did not parse as expected") + } +} From f5699901cfcbf8d1cc0bd1964ba725c96673b087 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 18 Oct 2016 01:18:18 -0400 Subject: [PATCH 2/2] i is better than k for indexes --- lock.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lock.go b/lock.go index 05db30b321..2b8fb9b652 100644 --- a/lock.go +++ b/lock.go @@ -48,7 +48,7 @@ func ReadLock(r io.Reader) (*Lock, error) { P: make([]gps.LockedProject, len(rl.P)), } - for k, ld := range rl.P { + for i, ld := range rl.P { r := gps.Revision(ld.Revision) var v gps.Version @@ -69,7 +69,7 @@ func ReadLock(r io.Reader) (*Lock, error) { ProjectRoot: gps.ProjectRoot(ld.Name), NetworkName: ld.Repository, } - l.P[k] = gps.NewLockedProject(id, v, ld.Packages) + l.P[i] = gps.NewLockedProject(id, v, ld.Packages) } return l, nil