Merge pull request #420 from Masterminds/fix/skip-glide-lock-write
Fixed #396: Don't update the lock file if nothing has changed
diff --git a/action/update.go b/action/update.go
index 4b0da7b..defaf07 100644
--- a/action/update.go
+++ b/action/update.go
@@ -1,6 +1,7 @@
package action
import (
+ "io/ioutil"
"path/filepath"
"github.com/Masterminds/glide/cfg"
@@ -85,9 +86,27 @@
msg.Die("Failed to generate config hash. Unable to generate lock file.")
}
lock := cfg.NewLockfile(confcopy.Imports, hash)
- if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil {
- msg.Err("Could not write lock file to %s: %s", base, err)
- return
+ wl := true
+ if gpath.HasLock(base) {
+ yml, err := ioutil.ReadFile(filepath.Join(base, gpath.LockFile))
+ if err == nil {
+ l2, err := cfg.LockfileFromYaml(yml)
+ if err == nil {
+ f1, err := l2.Fingerprint()
+ f2, err2 := lock.Fingerprint()
+ if err == nil && err2 == nil && f1 == f2 {
+ wl = false
+ }
+ }
+ }
+ }
+ if wl {
+ if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil {
+ msg.Err("Could not write lock file to %s: %s", base, err)
+ return
+ }
+ } else {
+ msg.Info("Versions did not change. Skipping glide.lock update.")
}
msg.Info("Project relies on %d dependencies.", len(confcopy.Imports))
diff --git a/cfg/lock.go b/cfg/lock.go
index 46f0753..517d3ba 100644
--- a/cfg/lock.go
+++ b/cfg/lock.go
@@ -1,6 +1,7 @@
package cfg
import (
+ "crypto/sha256"
"io/ioutil"
"sort"
"strings"
@@ -45,9 +46,44 @@
return ioutil.WriteFile(lockpath, o, 0666)
}
+// Clone returns a clone of Lockfile
+func (lf *Lockfile) Clone() *Lockfile {
+ n := &Lockfile{}
+ n.Hash = lf.Hash
+ n.Updated = lf.Updated
+ n.Imports = lf.Imports.Clone()
+ n.DevImports = lf.DevImports.Clone()
+
+ return n
+}
+
+// Fingerprint returns a hash of the contents minus the date. This allows for
+// two lockfiles to be compared irrespective of their updated times.
+func (lf *Lockfile) Fingerprint() ([32]byte, error) {
+ c := lf.Clone()
+ c.Updated = time.Time{} // Set the time to be the nil equivalent
+ sort.Sort(c.Imports)
+ sort.Sort(c.DevImports)
+ yml, err := c.Marshal()
+ if err != nil {
+ return [32]byte{}, err
+ }
+
+ return sha256.Sum256(yml), nil
+}
+
// Locks is a slice of locked dependencies.
type Locks []*Lock
+// Clone returns a Clone of Locks.
+func (l Locks) Clone() Locks {
+ n := make(Locks, 0, len(l))
+ for _, v := range l {
+ n = append(n, v.Clone())
+ }
+ return n
+}
+
// Len returns the length of the Locks. This is needed for sorting with
// the sort package.
func (l Locks) Len() int {
@@ -81,6 +117,19 @@
Os []string `yaml:"os,omitempty"`
}
+// Clone creates a clone of a Lock.
+func (l *Lock) Clone() *Lock {
+ return &Lock{
+ Name: l.Name,
+ Version: l.Version,
+ Repository: l.Repository,
+ VcsType: l.VcsType,
+ Subpackages: l.Subpackages,
+ Arch: l.Arch,
+ Os: l.Os,
+ }
+}
+
// NewLockfile is used to create an instance of Lockfile.
func NewLockfile(ds Dependencies, hash string) *Lockfile {
lf := &Lockfile{