Merge pull request #582 from kelcecil/remove-verbose

Remove verbose flag
diff --git a/CHANGELOG.md b/CHANGELOG.md
index acaf08b..b254449 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+# Release 0.12.1 (2016-08-31)
+
+## Fixed
+- #578: Not resolving parent project packages in some cases
+- #580: cross-device error handling failed on Windows in some cases
+- #590: When exit signal received remove global lock
+
+Note, Plan 9 is an experimental OS for Go. Due to some issues we are not going
+to be supporting builds for it at this time.
+
 # Release 0.12.0 (2016-08-23)
 
 ## Added
diff --git a/Makefile b/Makefile
index 05fcaeb..a71b9db 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@
 build-all:
 	gox -verbose \
 	-ldflags "-X main.version=${VERSION}" \
-	-os="linux darwin windows freebsd openbsd netbsd plan9" \
+	-os="linux darwin windows freebsd openbsd netbsd" \
 	-arch="amd64 386 armv5 armv6 armv7 arm64" \
 	-osarch="!darwin/arm64" \
 	-output="dist/{{.OS}}-{{.Arch}}/{{.Dir}}" .
diff --git a/cache/global_lock.go b/cache/global_lock.go
index 52cf841..d85283d 100644
--- a/cache/global_lock.go
+++ b/cache/global_lock.go
@@ -4,6 +4,7 @@
 	"encoding/json"
 	"io/ioutil"
 	"os"
+	"os/signal"
 	"path/filepath"
 	"time"
 
@@ -13,6 +14,9 @@
 
 var isStarted bool
 
+// If the global cache lock file should be written
+var shouldWriteLock = true
+
 // SystemLock starts a system rather than application lock. This way multiple
 // app instances don't cause race conditions when working in the cache.
 func SystemLock() error {
@@ -46,6 +50,13 @@
 
 // Write a lock for now.
 func writeLock() error {
+
+	// If the lock should not be written exit immediately. This happens in cases
+	// where shutdown/clean is happening.
+	if !shouldWriteLock {
+		return nil
+	}
+
 	ld := &lockdata{
 		Comment: "File managed by Glide (https://glide.sh)",
 		Pid:     os.Getpid(),
@@ -81,6 +92,24 @@
 		}
 	}()
 
+	// Capture ctrl-c or other interruptions then clean up the global lock.
+	ch := make(chan os.Signal)
+	signal.Notify(ch, os.Interrupt, os.Kill)
+	go func(cc <-chan os.Signal) {
+		s := <-cc
+		shouldWriteLock = false
+		SystemUnlock()
+
+		// Exiting with the expected exit codes when we can.
+		if s == os.Interrupt {
+			os.Exit(130)
+		} else if s == os.Kill {
+			os.Exit(137)
+		} else {
+			os.Exit(1)
+		}
+	}(ch)
+
 	return nil
 }
 
@@ -104,8 +133,7 @@
 			msg.Info("Waiting on Glide global cache access")
 		}
 
-		// Check on the lock file every 15 seconds.
-		// TODO(mattfarina): should this be a different length?
+		// Check on the lock file every second.
 		time.Sleep(time.Second)
 	}
 }
diff --git a/dependency/resolver.go b/dependency/resolver.go
index e237564..ddcb69d 100644
--- a/dependency/resolver.go
+++ b/dependency/resolver.go
@@ -483,7 +483,7 @@
 		}
 		r.VersionHandler.Process(dep)
 		// Here, we want to import the package and see what imports it has.
-		msg.Debug("Trying to open %s", vdep)
+		msg.Debug("Trying to open %s (%s)", dep, r.Handler.PkgPath(dep))
 		var imps []string
 		pkg, err := r.BuildContext.ImportDir(r.Handler.PkgPath(dep), 0)
 		if err != nil && strings.HasPrefix(err.Error(), "found packages ") {
@@ -621,6 +621,10 @@
 		t := r.Stripv(e.Value.(string))
 		root, sp := util.NormalizeName(t)
 
+		if root == r.Config.Name {
+			continue
+		}
+
 		// Skip ignored packages
 		if r.Config.HasIgnore(e.Value.(string)) {
 			msg.Debug("Ignoring: %s", e.Value.(string))
@@ -718,6 +722,10 @@
 		t := strings.TrimPrefix(e.Value.(string), r.VendorDir+string(os.PathSeparator))
 		root, sp := util.NormalizeName(t)
 
+		if root == r.Config.Name {
+			continue
+		}
+
 		existing := r.Config.Imports.Get(root)
 		if existing == nil && addTest {
 			existing = r.Config.DevImports.Get(root)
diff --git a/path/path.go b/path/path.go
index 48e95fb..953d851 100644
--- a/path/path.go
+++ b/path/path.go
@@ -235,7 +235,11 @@
 		return err
 	}
 
-	d, _ := os.Open(source)
+	d, err := os.Open(source)
+	if err != nil {
+		return err
+	}
+	defer d.Close()
 
 	objects, err := d.Readdir(-1)
 
diff --git a/repo/installer.go b/repo/installer.go
index 324e4eb..c8f6922 100644
--- a/repo/installer.go
+++ b/repo/installer.go
@@ -5,8 +5,10 @@
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"sync"
+	"syscall"
 	"time"
 
 	"github.com/Masterminds/glide/cache"
@@ -359,12 +361,29 @@
 
 	err = os.Rename(vp, i.VendorPath())
 
-	// When there are different physical devices we cannot rename cross device.
-	// Fall back to manual copy.
-	if err != nil && strings.Contains(err.Error(), "cross-device link") {
-		msg.Debug("Cross link err, trying manual copy: %s", err)
-
-		err = gpath.CopyDir(vp, i.VendorPath())
+	if err != nil {
+		// When there are different physical devices we cannot rename cross device.
+		// Instead we copy.
+		switch terr := err.(type) {
+		case *os.LinkError:
+			// syscall.EXDEV is the common name for the cross device link error
+			// which has varying output text across different operating systems.
+			if terr.Err == syscall.EXDEV {
+				msg.Debug("Cross link err, trying manual copy: %s", err)
+				return gpath.CopyDir(vp, i.VendorPath())
+			} else if runtime.GOOS == "windows" {
+				// In windows it can drop down to an operating system call that
+				// returns an operating system error with a different number and
+				// message. Checking for that as a fall back.
+				noerr, ok := terr.Err.(syscall.Errno)
+				// 0x11 (ERROR_NOT_SAME_DEVICE) is the windows error.
+				// See https://msdn.microsoft.com/en-us/library/cc231199.aspx
+				if ok && noerr == 0x11 {
+					msg.Debug("Cross link err on Windows, trying manual copy: %s", err)
+					return gpath.CopyDir(vp, i.VendorPath())
+				}
+			}
+		}
 	}
 
 	return err
@@ -583,6 +602,12 @@
 func (m *MissingPackageHandler) PkgPath(pkg string) string {
 	root, sub := util.NormalizeName(pkg)
 
+	// For the parent applications source skip the cache.
+	if root == m.Config.Name {
+		pth := gpath.Basepath()
+		return filepath.Join(pth, filepath.FromSlash(sub))
+	}
+
 	d := m.Config.Imports.Get(root)
 	if d == nil {
 		d = m.Config.DevImports.Get(root)
@@ -601,7 +626,7 @@
 		msg.Die("Error generating cache key for %s", d.Name)
 	}
 
-	return filepath.Join(cache.Location(), "src", key, sub)
+	return filepath.Join(cache.Location(), "src", key, filepath.FromSlash(sub))
 }
 
 func (m *MissingPackageHandler) fetchToCache(pkg string, addTest bool) error {
@@ -767,6 +792,12 @@
 func (d *VersionHandler) pkgPath(pkg string) string {
 	root, sub := util.NormalizeName(pkg)
 
+	// For the parent applications source skip the cache.
+	if root == d.Config.Name {
+		pth := gpath.Basepath()
+		return filepath.Join(pth, filepath.FromSlash(sub))
+	}
+
 	dep := d.Config.Imports.Get(root)
 	if dep == nil {
 		dep = d.Config.DevImports.Get(root)
@@ -785,7 +816,7 @@
 		msg.Die("Error generating cache key for %s", dep.Name)
 	}
 
-	return filepath.Join(cache.Location(), "src", key, sub)
+	return filepath.Join(cache.Location(), "src", key, filepath.FromSlash(sub))
 }
 
 func determineDependency(v, dep *cfg.Dependency, dest, req string) *cfg.Dependency {