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

Commit 8b6ac9a

Browse files
committed
Fleshing out first pass of -update path
1 parent 76be346 commit 8b6ac9a

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
@@ -247,7 +247,7 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project
247247

248248
solver, err := gps.Prepare(params, sm)
249249
if err != nil {
250-
return errors.Wrap(err, "ensure Prepare")
250+
return errors.Wrap(err, "prepare solver")
251251
}
252252

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

299-
// When -update is specified without args, allow every project to change versions, regardless of the lock file
299+
// We'll need to discard this prepared solver as later work changes params,
300+
// but solver preparation is cheap and worth doing up front in order to
301+
// perform the fastpath check of hash comparison.
302+
solver, err := gps.Prepare(params, sm)
303+
if err != nil {
304+
return errors.Wrap(err, "fastpath solver prepare")
305+
}
306+
307+
// Compare the hashes. If they're not equal, bail out and ask the user to
308+
// run a straight `dep ensure` before updating. This is handholding the
309+
// user a bit, but the extra effort required is minimal, and it ensures the
310+
// user is isolating variables in the event of solve problems (was it the
311+
// existing changes, or the -update that caused the problem?).
312+
if bytes.Equal(p.Lock.InputHash(), solver.HashInputs()) {
313+
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)
314+
}
315+
316+
// When -update is specified without args, allow every dependency to change
317+
// versions, regardless of the lock file.
300318
if len(args) == 0 {
301319
params.ChangeAll = true
302320
return
303321
}
304322

305-
// Allow any of specified project versions to change, regardless of the lock file
323+
// Allow any of specified project versions to change, regardless of the lock
324+
// file.
306325
for _, arg := range args {
307326
// Ensure the provided path has a deducible project root
308327
// TODO(sdboyer) do these concurrently
@@ -314,6 +333,10 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
314333
return err
315334
}
316335

336+
if !p.Lock.HasProjectWithRoot(pc.Ident.ProjectRoot) {
337+
return errors.Errorf("%s is not present in %s, cannot -update it", pc.Ident.ProjectRoot, dep.LockName)
338+
}
339+
317340
if !gps.IsAny(pc.Constraint) {
318341
// TODO(sdboyer) constraints should be allowed to allow solves that
319342
// target particular versions while remaining within declared constraints
@@ -322,6 +345,28 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
322345

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

327372
func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error {
@@ -401,6 +446,8 @@ func (s *stringSlice) Set(value string) error {
401446
}
402447

403448
func getProjectConstraint(arg string, sm *gps.SourceMgr) (gps.ProjectConstraint, error) {
449+
// TODO(sdboyer) this func needs to be broken out, now that we admit
450+
// different info in specs
404451
constraint := gps.ProjectConstraint{
405452
Constraint: gps.Any(), // default to any; avoids panics later
406453
}

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)