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

Commit

Permalink
Fleshing out first pass of -update path
Browse files Browse the repository at this point in the history
  • Loading branch information
sdboyer committed Apr 30, 2017
1 parent d3bf178 commit 895330a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
53 changes: 50 additions & 3 deletions cmd/dep/ensure.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project

solver, err := gps.Prepare(params, sm)
if err != nil {
return errors.Wrap(err, "ensure Prepare")
return errors.Wrap(err, "prepare solver")
}

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

// When -update is specified without args, allow every project to change versions, regardless of the lock file
// We'll need to discard this prepared solver as later work changes params,
// but solver preparation is cheap and worth doing up front in order to
// perform the fastpath check of hash comparison.
solver, err := gps.Prepare(params, sm)
if err != nil {
return errors.Wrap(err, "fastpath solver prepare")
}

// Compare the hashes. If they're not equal, bail out and ask the user to
// run a straight `dep ensure` before updating. This is handholding the
// user a bit, but the extra effort required is minimal, and it ensures the
// user is isolating variables in the event of solve problems (was it the
// existing changes, or the -update that caused the problem?).
if bytes.Equal(p.Lock.InputHash(), solver.HashInputs()) {
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)
}

// When -update is specified without args, allow every dependency 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
// Allow any of specified project versions to change, regardless of the lock
// file.
for _, arg := range args {
// Ensure the provided path has a deducible project root
// TODO(sdboyer) do these concurrently
Expand All @@ -308,6 +327,10 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
return err
}

if !p.Lock.HasProjectWithRoot(pc.Ident.ProjectRoot) {
return errors.Errorf("%s is not present in %s, cannot -update it", pc.Ident.ProjectRoot, dep.LockName)
}

if !gps.IsAny(pc.Constraint) {
// TODO(sdboyer) constraints should be allowed to allow solves that
// target particular versions while remaining within declared constraints
Expand All @@ -316,6 +339,28 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,

params.ToChange = append(params.ToChange, gps.ProjectRoot(arg))
}

// Re-prepare a solver now that our params are complete.
solver, err = gps.Prepare(params, sm)
if err != nil {
return errors.Wrap(err, "fastpath solver prepare")
}
solution, err := solver.Solve()
if err != nil {
handleAllTheFailuresOfTheWorld(err)
return errors.Wrap(err, "ensure Solve()")
}

var sw dep.SafeWriter
sw.Prepare(nil, p.Lock, dep.LockFromInterface(solution), dep.VendorOnChanged)
// TODO(sdboyer) special handling for warning cases as described in spec -
// e.g., named projects did not upgrade even though newer versions were
// available.
if cmd.dryRun {
return sw.PrintPreparedActions()
}

return errors.Wrap(sw.Write(p.AbsRoot, sm, true), "grouped write of manifest, lock and vendor")
}

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

func getProjectConstraint(arg string, sm *gps.SourceMgr) (gps.ProjectConstraint, error) {
// TODO(sdboyer) this func needs to be broken out, now that we admit
// different info in specs
constraint := gps.ProjectConstraint{
Constraint: gps.Any(), // default to any; avoids panics later
}
Expand Down
16 changes: 15 additions & 1 deletion lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
package dep

import (
"bytes"
"encoding/hex"
"io"
"sort"

"bytes"
"github.com/pelletier/go-toml"
"github.com/pkg/errors"
"github.com/sdboyer/gps"
Expand Down Expand Up @@ -95,6 +95,20 @@ func (l *Lock) Projects() []gps.LockedProject {
return l.P
}

// HasProjectWithRoot checks if the lock contains a project with the provided
// ProjectRoot.
//
// This check is O(n) in the number of projects.
func (l *Lock) HasProjectWithRoot(root gps.ProjectRoot) bool {
for _, p := range l.P {
if p.Ident().ProjectRoot == root {
return true
}
}

return root
}

// toRaw converts the manifest into a representation suitable to write to the lock file
func (l *Lock) toRaw() rawLock {
raw := rawLock{
Expand Down

0 comments on commit 895330a

Please sign in to comment.