diff --git a/cmd/dep/ensure.go b/cmd/dep/ensure.go index 2190770836..ea07f0cd9d 100644 --- a/cmd/dep/ensure.go +++ b/cmd/dep/ensure.go @@ -52,6 +52,12 @@ dep ensure -update ignoring any versions specified in the lock file. Update the lock file with any changes. +dep ensure -update github.com/pkg/foo github.com/pkg/bar + + Update a list of dependencies to the latest versions allowed by the manifest, + ignoring any versions specified in the lock file. Update the lock file with + any changes. + dep ensure github.com/pkg/foo@^1.0.1 Constrain pkg/foo to the latest release matching >= 1.0.1, < 2.0.0, and @@ -82,7 +88,7 @@ func (cmd *ensureCommand) Hidden() bool { return false } func (cmd *ensureCommand) Register(fs *flag.FlagSet) { fs.BoolVar(&cmd.examples, "examples", false, "print detailed usage examples") - fs.BoolVar(&cmd.update, "update", false, "ensure all dependencies are at the latest version allowed by the manifest") + fs.BoolVar(&cmd.update, "update", false, "ensure dependencies are at the latest version allowed by the manifest") fs.BoolVar(&cmd.dryRun, "n", false, "dry run, don't actually ensure anything") fs.Var(&cmd.overrides, "override", "specify an override constraint spec (repeatable)") } @@ -100,10 +106,6 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error { return nil } - if cmd.update && len(args) > 0 { - return errors.New("Cannot pass -update and itemized project list (for now)") - } - p, err := ctx.LoadProject("") if err != nil { return err @@ -116,9 +118,72 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error { sm.UseDefaultSignalHandling() defer sm.Release() + params := p.MakeParams() + if *verbose { + params.Trace = true + params.TraceLogger = log.New(os.Stderr, "", 0) + } + params.RootPackageTree, err = gps.ListPackages(p.AbsRoot, string(p.ImportRoot)) + if err != nil { + return errors.Wrap(err, "ensure ListPackage for project") + } + + if cmd.update { + applyUpdateArgs(args, ¶ms) + } else { + err := applyEnsureArgs(args, cmd.overrides, p, sm, ¶ms) + if err != nil { + return err + } + } + + solver, err := gps.Prepare(params, sm) + if err != nil { + return errors.Wrap(err, "ensure Prepare") + } + solution, err := solver.Solve() + if err != nil { + handleAllTheFailuresOfTheWorld(err) + return errors.Wrap(err, "ensure Solve()") + } + + sw := dep.SafeWriter{ + Root: p.AbsRoot, + Lock: p.Lock, + NewLock: solution, + SourceManager: sm, + } + if !cmd.update { + sw.Manifest = p.Manifest + } + + // check if vendor exists, because if the locks are the same but + // vendor does not exist we should write vendor + vendorExists, err := dep.IsNonEmptyDir(filepath.Join(sw.Root, "vendor")) + if err != nil { + return errors.Wrap(err, "ensure vendor is a directory") + } + writeV := !vendorExists && solution != nil + + return errors.Wrap(sw.WriteAllSafe(writeV), "grouped write of manifest, lock and vendor") +} + +func applyUpdateArgs(args []string, params *gps.SolveParameters) { + // When -update is specified without args, allow every project to change versions, regardless of the lock file + if len(args) == 0 { + params.ChangeAll = true + return + } + + // Allow any of specified project versions to change, regardless of the lock file + for _, arg := range args { + params.ToChange = append(params.ToChange, gps.ProjectRoot(arg)) + } +} + +func applyEnsureArgs(args []string, overrides stringSlice, p *dep.Project, sm *gps.SourceMgr, params *gps.SolveParameters) error { var errs []error for _, arg := range args { - // default persist to manifest pc, err := getProjectConstraint(arg, sm) if err != nil { errs = append(errs, err) @@ -144,18 +209,9 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error { Source: pc.Ident.Source, Constraint: pc.Constraint, } - - if p.Lock != nil { - for i, lp := range p.Lock.P { - if lp.Ident() == pc.Ident { - p.Lock.P = append(p.Lock.P[:i], p.Lock.P[i+1:]...) - break - } - } - } } - for _, ovr := range cmd.overrides { + for _, ovr := range overrides { pc, err := getProjectConstraint(ovr, sm) if err != nil { errs = append(errs, err) @@ -170,15 +226,6 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error { Source: pc.Ident.Source, Constraint: pc.Constraint, } - - if p.Lock != nil { - for i, lp := range p.Lock.P { - if lp.Ident() == pc.Ident { - p.Lock.P = append(p.Lock.P[:i], p.Lock.P[i+1:]...) - break - } - } - } } if len(errs) > 0 { @@ -190,46 +237,7 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error { return errors.New(buf.String()) } - params := p.MakeParams() - // If -update was passed, we want the solver to allow all versions to change - params.ChangeAll = cmd.update - - if *verbose { - params.Trace = true - params.TraceLogger = log.New(os.Stderr, "", 0) - } - - params.RootPackageTree, err = gps.ListPackages(p.AbsRoot, string(p.ImportRoot)) - if err != nil { - return errors.Wrap(err, "ensure ListPackage for project") - } - solver, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "ensure Prepare") - } - solution, err := solver.Solve() - if err != nil { - handleAllTheFailuresOfTheWorld(err) - return errors.Wrap(err, "ensure Solve()") - } - - sw := dep.SafeWriter{ - Root: p.AbsRoot, - Manifest: p.Manifest, - Lock: p.Lock, - NewLock: solution, - SourceManager: sm, - } - - // check if vendor exists, because if the locks are the same but - // vendor does not exist we should write vendor - vendorExists, err := dep.IsNonEmptyDir(filepath.Join(sw.Root, "vendor")) - if err != nil { - return errors.Wrap(err, "ensure vendor is a directory") - } - writeV := !vendorExists && solution != nil - - return errors.Wrap(sw.WriteAllSafe(writeV), "grouped write of manifest, lock and vendor") + return nil } type stringSlice []string diff --git a/cmd/dep/ensure_test.go b/cmd/dep/ensure_test.go index d362481884..88311139df 100644 --- a/cmd/dep/ensure_test.go +++ b/cmd/dep/ensure_test.go @@ -21,73 +21,36 @@ func TestEnsureOverrides(t *testing.T) { h.TempDir("src") h.Setenv("GOPATH", h.Path(".")) - m := `package main - -import ( - "github.com/Sirupsen/logrus" - sthing "github.com/sdboyer/dep-test" -) - -type Baz sthing.Foo - -func main() { - logrus.Info("hello world") -}` - - h.TempFile("src/thing/thing.go", m) + h.TempCopy("src/thing/thing.go", "ensure/overrides_main.go") h.Cd(h.Path("src/thing")) h.Run("init") - h.Run("ensure", "-override", "github.com/Sirupsen/logrus@0.11.0") - - expectedManifest := `{ - "overrides": { - "github.com/Sirupsen/logrus": { - "version": "0.11.0" - } - } -} -` - - manifest := h.ReadManifest() - if manifest != expectedManifest { - t.Fatalf("expected %s, got %s", expectedManifest, manifest) + h.Run("ensure", "-override", "github.com/carolynvs/go-dep-test@0.1.1") + + goldenManifest := "ensure/overrides_manifest.golden.json" + wantManifest := h.GetTestFileString(goldenManifest) + gotManifest := h.ReadManifest() + if gotManifest != wantManifest { + if *test.UpdateGolden { + if err := h.WriteTestFile(goldenManifest, string(gotManifest)); err != nil { + t.Fatal(err) + } + } else { + t.Fatalf("expected %s, got %s", wantManifest, gotManifest) + } } - sysCommit := h.GetCommit("go.googlesource.com/sys") - expectedLock := `{ - "memo": "57d20ba0289c2df60025bf6127220a5403483251bd5e523a7f9ea17752bd5482", - "projects": [ - { - "name": "github.com/Sirupsen/logrus", - "version": "v0.11.0", - "revision": "d26492970760ca5d33129d2d799e34be5c4782eb", - "packages": [ - "." - ] - }, - { - "name": "github.com/sdboyer/dep-test", - "version": "1.0.0", - "revision": "2a3a211e171803acb82d1d5d42ceb53228f51751", - "packages": [ - "." - ] - }, - { - "name": "golang.org/x/sys", - "branch": "master", - "revision": "` + sysCommit + `", - "packages": [ - "unix" - ] - } - ] -} -` - lock := h.ReadLock() - if lock != expectedLock { - t.Fatalf("expected %s, got %s", expectedLock, lock) + goldenLock := "ensure/overrides_lock.golden.json" + wantLock := h.GetTestFileString(goldenLock) + gotLock := h.ReadLock() + if gotLock != wantLock { + if *test.UpdateGolden { + if err := h.WriteTestFile(goldenLock, string(gotLock)); err != nil { + t.Fatal(err) + } + } else { + t.Fatalf("expected %s, got %s", wantLock, gotLock) + } } } @@ -100,18 +63,7 @@ func TestEnsureEmptyRepoNoArgs(t *testing.T) { h.TempDir("src") h.Setenv("GOPATH", h.Path(".")) - - m := `package main - -import ( - _ "github.com/jimmysmith95/fixed-version" - _ "golang.org/x/sys/unix" -) - -func main() { -}` - - h.TempFile("src/thing/thing.go", m) + h.TempCopy("src/thing/thing.go", "ensure/bare_main.go") h.Cd(h.Path("src/thing")) h.Run("init") @@ -120,43 +72,30 @@ func main() { // make sure vendor exists h.MustExist(h.Path("src/thing/vendor/github.com/jimmysmith95/fixed-version")) - expectedManifest := `{} -` - - manifest := h.ReadManifest() - if manifest != expectedManifest { - t.Fatalf("expected %s, got %s", expectedManifest, manifest) + goldenManifest := "ensure/bare_manifest.golden.json" + wantManifest := h.GetTestFileString(goldenManifest) + gotManifest := h.ReadManifest() + if gotManifest != wantManifest { + if *test.UpdateGolden { + if err := h.WriteTestFile(goldenManifest, string(gotManifest)); err != nil { + t.Fatal(err) + } + } else { + t.Fatalf("expected %s, got %s", wantManifest, gotManifest) + } } - sysCommit := h.GetCommit("go.googlesource.com/sys") - fixedVersionCommit := h.GetCommit("github.com/jimmysmith95/fixed-version") - - expectedLock := `{ - "memo": "8a7660015b2473d6d2f4bfdfd0508e6aa8178746559d0a9a90cecfbe6aa47a06", - "projects": [ - { - "name": "github.com/jimmysmith95/fixed-version", - "version": "v1.0.0", - "revision": "` + fixedVersionCommit + `", - "packages": [ - "." - ] - }, - { - "name": "golang.org/x/sys", - "branch": "master", - "revision": "` + sysCommit + `", - "packages": [ - "unix" - ] - } - ] -} -` - - lock := h.ReadLock() - if lock != expectedLock { - t.Fatalf("expected %s, got %s", expectedLock, lock) + goldenLock := "ensure/bare_lock.golden.json" + wantLock := h.GetTestFileString(goldenLock) + gotLock := h.ReadLock() + if gotLock != wantLock { + if *test.UpdateGolden { + if err := h.WriteTestFile(goldenLock, string(gotLock)); err != nil { + t.Fatal(err) + } + } else { + t.Fatalf("expected %s, got %s", wantLock, gotLock) + } } } @@ -186,3 +125,44 @@ func TestDeduceConstraint(t *testing.T) { } } } + +func TestEnsureUpdate(t *testing.T) { + test.NeedsExternalNetwork(t) + test.NeedsGit(t) + + h := test.NewHelper(t) + defer h.Cleanup() + + // Setup up a test project + h.TempDir("src") + h.Setenv("GOPATH", h.Path(".")) + h.TempCopy("src/thing/main.go", "ensure/update_main.go") + origManifest := "ensure/update_manifest.json" + h.TempCopy("src/thing/manifest.json", origManifest) + origLock := "ensure/update_lock.json" + h.TempCopy("src/thing/lock.json", origLock) + h.Cd(h.Path("src/thing")) + + h.Run("ensure", "-update", "github.com/carolynvs/go-dep-test") + + // Verify that the manifest wasn't modified by -update + wantManifest := h.GetTestFileString(origManifest) + gotManifest := h.ReadManifest() + if gotManifest != wantManifest { + t.Fatalf("The manifest should not be modified during an update. Expected %s, got %s", origManifest, gotManifest) + } + + // Verify the lock matches the expected golden file + goldenLock := "ensure/update_lock.golden.json" + wantLock := h.GetTestFileString(goldenLock) + gotLock := h.ReadLock() + if gotLock != wantLock { + if *test.UpdateGolden { + if err := h.WriteTestFile(goldenLock, string(gotLock)); err != nil { + t.Fatal(err) + } + } else { + t.Fatalf("expected %s, got %s", wantLock, gotLock) + } + } +} diff --git a/cmd/dep/testdata/ensure/bare_lock.golden.json b/cmd/dep/testdata/ensure/bare_lock.golden.json new file mode 100644 index 0000000000..1ad18c9967 --- /dev/null +++ b/cmd/dep/testdata/ensure/bare_lock.golden.json @@ -0,0 +1,13 @@ +{ + "memo": "671164a61abeac1133d1da7f6bb22ed18e6921dfc5f9247b378833833b5a3aca", + "projects": [ + { + "name": "github.com/jimmysmith95/fixed-version", + "version": "v1.0.0", + "revision": "a2d649e0636403a4693cd928f60c56ba7d9cd299", + "packages": [ + "." + ] + } + ] +} diff --git a/cmd/dep/testdata/ensure/bare_main.go b/cmd/dep/testdata/ensure/bare_main.go new file mode 100644 index 0000000000..4c6b76c019 --- /dev/null +++ b/cmd/dep/testdata/ensure/bare_main.go @@ -0,0 +1,12 @@ +// 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 ( + _ "github.com/jimmysmith95/fixed-version" +) + +func main() { +} diff --git a/cmd/dep/testdata/ensure/bare_manifest.golden.json b/cmd/dep/testdata/ensure/bare_manifest.golden.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/cmd/dep/testdata/ensure/bare_manifest.golden.json @@ -0,0 +1 @@ +{} diff --git a/cmd/dep/testdata/ensure/overrides_lock.golden.json b/cmd/dep/testdata/ensure/overrides_lock.golden.json new file mode 100644 index 0000000000..2bd94fd2f2 --- /dev/null +++ b/cmd/dep/testdata/ensure/overrides_lock.golden.json @@ -0,0 +1,13 @@ +{ + "memo": "80807a008f7d8d26de122a8c6ad1f4c7286950b32e0488660afc57ccbbc037a1", + "projects": [ + { + "name": "github.com/carolynvs/go-dep-test", + "version": "0.1.1", + "revision": "d15fa4b9d1330a469387f2873399d28ea1c463eb", + "packages": [ + "." + ] + } + ] +} diff --git a/cmd/dep/testdata/ensure/overrides_main.go b/cmd/dep/testdata/ensure/overrides_main.go new file mode 100644 index 0000000000..27fa78605c --- /dev/null +++ b/cmd/dep/testdata/ensure/overrides_main.go @@ -0,0 +1,14 @@ +// 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 ( + "fmt" + stuff "github.com/carolynvs/go-dep-test" +) + +func main() { + fmt.Println(stuff.Thing) +} diff --git a/cmd/dep/testdata/ensure/overrides_manifest.golden.json b/cmd/dep/testdata/ensure/overrides_manifest.golden.json new file mode 100644 index 0000000000..3bfeb541e2 --- /dev/null +++ b/cmd/dep/testdata/ensure/overrides_manifest.golden.json @@ -0,0 +1,7 @@ +{ + "overrides": { + "github.com/carolynvs/go-dep-test": { + "version": "0.1.1" + } + } +} diff --git a/cmd/dep/testdata/ensure/update_lock.golden.json b/cmd/dep/testdata/ensure/update_lock.golden.json new file mode 100644 index 0000000000..7239c773c6 --- /dev/null +++ b/cmd/dep/testdata/ensure/update_lock.golden.json @@ -0,0 +1,21 @@ +{ + "memo": "9a5243dd3fa20feeaa20398e7283d6c566532e2af1aae279a010df34793761c5", + "projects": [ + { + "name": "github.com/carolynvs/go-dep-test", + "version": "0.1.1", + "revision": "40691983e4002d3a3f5879cc0f1fe99bedda148c", + "packages": [ + "." + ] + }, + { + "name": "github.com/pkg/errors", + "branch": "v0.7.0", + "revision": "01fa4104b9c248c8945d14d9f128454d5b28d595", + "packages": [ + "." + ] + } + ] +} diff --git a/cmd/dep/testdata/ensure/update_lock.json b/cmd/dep/testdata/ensure/update_lock.json new file mode 100644 index 0000000000..907c0372e0 --- /dev/null +++ b/cmd/dep/testdata/ensure/update_lock.json @@ -0,0 +1,21 @@ +{ + "memo": "9a5243dd3fa20feeaa20398e7283d6c566532e2af1aae279a010df34793761c5", + "projects": [ + { + "name": "github.com/carolynvs/go-dep-test", + "version": "0.1.0", + "revision": "b9c5511fa463628e6251554db29a4be161d02aed", + "packages": [ + "." + ] + }, + { + "name": "github.com/pkg/errors", + "branch": "v0.7.0", + "revision": "01fa4104b9c248c8945d14d9f128454d5b28d595", + "packages": [ + "." + ] + } + ] +} diff --git a/cmd/dep/testdata/ensure/update_main.go b/cmd/dep/testdata/ensure/update_main.go new file mode 100644 index 0000000000..28e46c204d --- /dev/null +++ b/cmd/dep/testdata/ensure/update_main.go @@ -0,0 +1,20 @@ +// 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 ( + "fmt" + stuff "github.com/carolynvs/go-dep-test" + "github.com/pkg/errors" +) + +func main() { + fmt.Println(stuff.Thing) + TryToDoSomething() +} + +func TryToDoSomething() error { + return errors.New("I tried, Billy. I tried...") +} diff --git a/cmd/dep/testdata/ensure/update_manifest.json b/cmd/dep/testdata/ensure/update_manifest.json new file mode 100644 index 0000000000..fb2ce6c93e --- /dev/null +++ b/cmd/dep/testdata/ensure/update_manifest.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "github.com/carolynvs/go-dep-test": { + "version": "~0.1.0" + } + } +}