Merge pull request #545 from Masterminds/fix/517
Fixed #517 failed to install testImport from lock
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fac8d08..68828a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,8 @@
This skips unnecessary network requests (thanks @hori-ryota)
## Fixed
+- #517: Fixed failure to install testImport from lock when no imports present
+ or when same dependency on both import and testImport
- #440: Fixed panic in `glide tree` when walking the filesystem (thanks @abhin4v)
- #529: --delete flag deleted and re-downloaded transitive dependencies
- #535: Resolve vendor directory symlinks (thanks @Fugiman)
diff --git a/action/get.go b/action/get.go
index 5c34d5e..009d90d 100644
--- a/action/get.go
+++ b/action/get.go
@@ -115,7 +115,10 @@
if err != nil {
msg.Die("Failed to generate config hash. Unable to generate lock file.")
}
- lock := cfg.NewLockfile(confcopy.Imports, confcopy.DevImports, hash)
+ lock, err := cfg.NewLockfile(confcopy.Imports, confcopy.DevImports, hash)
+ if err != nil {
+ msg.Die("Failed to generate lock file: %s", err)
+ }
if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil {
msg.Die("Failed to write glide lock file: %s", err)
}
diff --git a/action/update.go b/action/update.go
index bdd3c62..9712ebb 100644
--- a/action/update.go
+++ b/action/update.go
@@ -87,7 +87,10 @@
if err != nil {
msg.Die("Failed to generate config hash. Unable to generate lock file.")
}
- lock := cfg.NewLockfile(confcopy.Imports, confcopy.DevImports, hash)
+ lock, err := cfg.NewLockfile(confcopy.Imports, confcopy.DevImports, hash)
+ if err != nil {
+ msg.Die("Failed to generate lock file: %s", err)
+ }
wl := true
if gpath.HasLock(base) {
yml, err := ioutil.ReadFile(filepath.Join(base, gpath.LockFile))
diff --git a/cfg/lock.go b/cfg/lock.go
index 8a26e24..62d08ef 100644
--- a/cfg/lock.go
+++ b/cfg/lock.go
@@ -2,6 +2,7 @@
import (
"crypto/sha256"
+ "fmt"
"io/ioutil"
"sort"
"strings"
@@ -40,6 +41,27 @@
for _, imp := range lf.Imports {
sort.Strings(imp.Subpackages)
}
+
+ // Ensure elements on testImport don't already exist on import.
+ var newDI Locks
+ var found bool
+ for _, imp := range lf.DevImports {
+ found = false
+ for i := 0; i < len(lf.Imports); i++ {
+ if lf.Imports[i].Name == imp.Name {
+ found = true
+ if lf.Imports[i].Version != imp.Version {
+ return lf, fmt.Errorf("Generating lock YAML produced conflicting versions of %s. import (%s), testImport (%s)", imp.Name, lf.Imports[i].Version, imp.Version)
+ }
+ }
+ }
+
+ if !found {
+ newDI = append(newDI, imp)
+ }
+ }
+ lf.DevImports = newDI
+
for _, imp := range lf.DevImports {
sort.Strings(imp.Subpackages)
}
@@ -169,7 +191,7 @@
}
// NewLockfile is used to create an instance of Lockfile.
-func NewLockfile(ds, tds Dependencies, hash string) *Lockfile {
+func NewLockfile(ds, tds Dependencies, hash string) (*Lockfile, error) {
lf := &Lockfile{
Hash: hash,
Updated: time.Now(),
@@ -183,13 +205,26 @@
sort.Sort(lf.Imports)
+ var found bool
for i := 0; i < len(tds); i++ {
- lf.DevImports[i] = LockFromDependency(tds[i])
+ found = false
+ for ii := 0; ii < len(ds); ii++ {
+ if ds[ii].Name == tds[i].Name {
+ found = true
+ if ds[ii].Reference != tds[i].Reference {
+ return &Lockfile{}, fmt.Errorf("Generating lock produced conflicting versions of %s. import (%s), testImport (%s)", tds[i].Name, ds[ii].Reference, tds[i].Reference)
+ }
+ break
+ }
+ }
+ if !found {
+ lf.DevImports[i] = LockFromDependency(tds[i])
+ }
}
sort.Sort(lf.DevImports)
- return lf
+ return lf, nil
}
// LockfileFromMap takes a map of dependencies and generates a lock Lockfile instance.
diff --git a/repo/installer.go b/repo/installer.go
index 13d3fb0..5fd8562 100644
--- a/repo/installer.go
+++ b/repo/installer.go
@@ -104,8 +104,8 @@
newConf.DeDupe()
- if len(newConf.Imports) == 0 {
- msg.Info("No dependencies found. Nothing installed.\n")
+ if len(newConf.Imports) == 0 && len(newConf.DevImports) == 0 {
+ msg.Info("No dependencies found. Nothing installed.")
return newConf, nil
}
diff --git a/repo/set_reference.go b/repo/set_reference.go
index 4363459..f5891ac 100644
--- a/repo/set_reference.go
+++ b/repo/set_reference.go
@@ -3,9 +3,11 @@
import (
"sync"
+ "github.com/Masterminds/glide/cache"
"github.com/Masterminds/glide/cfg"
"github.com/Masterminds/glide/msg"
gpath "github.com/Masterminds/glide/path"
+ "github.com/codegangsta/cli"
)
// SetReference is a command to set the VCS reference (commit id, tag, etc) for
@@ -25,15 +27,39 @@
done := make(chan struct{}, concurrentWorkers)
in := make(chan *cfg.Dependency, concurrentWorkers)
var wg sync.WaitGroup
+ var lock sync.Mutex
+ var returnErr error
for i := 0; i < concurrentWorkers; i++ {
go func(ch <-chan *cfg.Dependency) {
for {
select {
case dep := <-ch:
+ var loc string
+ if dep.Repository != "" {
+ loc = dep.Repository
+ } else {
+ loc = "https://" + dep.Name
+ }
+ key, err := cache.Key(loc)
+ if err != nil {
+ msg.Die(err.Error())
+ }
+ cache.Lock(key)
if err := VcsVersion(dep, cwd); err != nil {
msg.Err("Failed to set version on %s to %s: %s\n", dep.Name, dep.Reference, err)
+
+ // Capture the error while making sure the concurrent
+ // operations don't step on each other.
+ lock.Lock()
+ if returnErr == nil {
+ returnErr = err
+ } else {
+ returnErr = cli.NewMultiError(returnErr, err)
+ }
+ lock.Unlock()
}
+ cache.Unlock(key)
wg.Done()
case <-done:
return
@@ -66,5 +92,5 @@
// close(done)
// close(in)
- return nil
+ return returnErr
}