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

Commit 895330a

Browse files
committed
Fleshing out first pass of -update path
1 parent d3bf178 commit 895330a

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

cmd/dep/ensure.go

+50-3
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project
241241

242242
solver, err := gps.Prepare(params, sm)
243243
if err != nil {
244-
return errors.Wrap(err, "ensure Prepare")
244+
return errors.Wrap(err, "prepare solver")
245245
}
246246

247247
if p.Lock != nil && bytes.Equal(p.Lock.InputHash(), solver.HashInputs()) {
@@ -290,13 +290,32 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
290290
return errors.New("%s does not exist. nothing to do, as -update works by updating the values in %s.", dep.LockName, dep.LockName)
291291
}
292292

293-
// When -update is specified without args, allow every project to change versions, regardless of the lock file
293+
// We'll need to discard this prepared solver as later work changes params,
294+
// but solver preparation is cheap and worth doing up front in order to
295+
// perform the fastpath check of hash comparison.
296+
solver, err := gps.Prepare(params, sm)
297+
if err != nil {
298+
return errors.Wrap(err, "fastpath solver prepare")
299+
}
300+
301+
// Compare the hashes. If they're not equal, bail out and ask the user to
302+
// run a straight `dep ensure` before updating. This is handholding the
303+
// user a bit, but the extra effort required is minimal, and it ensures the
304+
// user is isolating variables in the event of solve problems (was it the
305+
// existing changes, or the -update that caused the problem?).
306+
if bytes.Equal(p.Lock.InputHash(), solver.HashInputs()) {
307+
return errors.Errorf("%s and %s are out of sync. run a plain `dep ensure` to resync them before attempting an -update.", dep.ManifestName, dep.LockName)
308+
}
309+
310+
// When -update is specified without args, allow every dependency to change
311+
// versions, regardless of the lock file.
294312
if len(args) == 0 {
295313
params.ChangeAll = true
296314
return
297315
}
298316

299-
// Allow any of specified project versions to change, regardless of the lock file
317+
// Allow any of specified project versions to change, regardless of the lock
318+
// file.
300319
for _, arg := range args {
301320
// Ensure the provided path has a deducible project root
302321
// TODO(sdboyer) do these concurrently
@@ -308,6 +327,10 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
308327
return err
309328
}
310329

330+
if !p.Lock.HasProjectWithRoot(pc.Ident.ProjectRoot) {
331+
return errors.Errorf("%s is not present in %s, cannot -update it", pc.Ident.ProjectRoot, dep.LockName)
332+
}
333+
311334
if !gps.IsAny(pc.Constraint) {
312335
// TODO(sdboyer) constraints should be allowed to allow solves that
313336
// target particular versions while remaining within declared constraints
@@ -316,6 +339,28 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
316339

317340
params.ToChange = append(params.ToChange, gps.ProjectRoot(arg))
318341
}
342+
343+
// Re-prepare a solver now that our params are complete.
344+
solver, err = gps.Prepare(params, sm)
345+
if err != nil {
346+
return errors.Wrap(err, "fastpath solver prepare")
347+
}
348+
solution, err := solver.Solve()
349+
if err != nil {
350+
handleAllTheFailuresOfTheWorld(err)
351+
return errors.Wrap(err, "ensure Solve()")
352+
}
353+
354+
var sw dep.SafeWriter
355+
sw.Prepare(nil, p.Lock, dep.LockFromInterface(solution), dep.VendorOnChanged)
356+
// TODO(sdboyer) special handling for warning cases as described in spec -
357+
// e.g., named projects did not upgrade even though newer versions were
358+
// available.
359+
if cmd.dryRun {
360+
return sw.PrintPreparedActions()
361+
}
362+
363+
return errors.Wrap(sw.Write(p.AbsRoot, sm, true), "grouped write of manifest, lock and vendor")
319364
}
320365

321366
func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error {
@@ -395,6 +440,8 @@ func (s *stringSlice) Set(value string) error {
395440
}
396441

397442
func getProjectConstraint(arg string, sm *gps.SourceMgr) (gps.ProjectConstraint, error) {
443+
// TODO(sdboyer) this func needs to be broken out, now that we admit
444+
// different info in specs
398445
constraint := gps.ProjectConstraint{
399446
Constraint: gps.Any(), // default to any; avoids panics later
400447
}

lock.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
package dep
66

77
import (
8+
"bytes"
89
"encoding/hex"
910
"io"
1011
"sort"
1112

12-
"bytes"
1313
"github.com/pelletier/go-toml"
1414
"github.com/pkg/errors"
1515
"github.com/sdboyer/gps"
@@ -95,6 +95,20 @@ func (l *Lock) Projects() []gps.LockedProject {
9595
return l.P
9696
}
9797

98+
// HasProjectWithRoot checks if the lock contains a project with the provided
99+
// ProjectRoot.
100+
//
101+
// This check is O(n) in the number of projects.
102+
func (l *Lock) HasProjectWithRoot(root gps.ProjectRoot) bool {
103+
for _, p := range l.P {
104+
if p.Ident().ProjectRoot == root {
105+
return true
106+
}
107+
}
108+
109+
return root
110+
}
111+
98112
// toRaw converts the manifest into a representation suitable to write to the lock file
99113
func (l *Lock) toRaw() rawLock {
100114
raw := rawLock{

0 commit comments

Comments
 (0)