Merge pull request #265 from mhoglan/skip_cache

Do not try to cache branch if caching is disabled
diff --git a/.travis.yml b/.travis.yml
index 0a42c0e..f54bf18 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,8 @@
 # against tip which has the features.
 go:
   - 1.5
+  - 1.6
+  - tip
 
 # Setting sudo access to false will let Travis CI use containers rather than
 # VMs to run the tests. For more details see:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5fdc968..df6963a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
-# Release 0.9.0 (xxxx-xx-xx)
+# Release 0.9.1 (xxxx-xx-xx)
 
+- Issue #267: Added `os` and `arch` import properties to the documentation.
+- Fixed #267: Glide was only walking the import tree based on build flags for
+  the current OS and Arch. This is a problem for systems like docker that have
+  variation built in.
+
+# Release 0.9.0 (2016-02-17)
+
+- Fixed #262: Using correct query string merging for go-get queries (thanks gdm85).
+- Fixed #251: Fixed warning message (thanks james-lawrence).
 - Adding support for IBM JazzHub.
 - Fixes #250: When unable to retrieve or set version on a dependency now erroring
   and exiting with non-0 exit code.
diff --git a/README.md b/README.md
index 2abe0ac..6ab8cde 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 # Glide: Vendor Package Management for Golang
 
+![glide logo](https://glide.sh/assets/logo-small.png)
+
 Are you used to tools such as Cargo, npm, Composer, Nuget, Pip, Maven, Bundler,
 or other modern package managers? If so, Glide is the comparable Go tool.
 
@@ -10,7 +12,7 @@
 installed by a tool (e.g. glide), similar to `go get` or they can be vendored and
 distributed with the package.
 
-[![Build Status](https://travis-ci.org/Masterminds/glide.svg)](https://travis-ci.org/Masterminds/glide) [![Go Report Card](http://goreportcard.com/badge/Masterminds/glide)](http://goreportcard.com/report/Masterminds/glide) [![GoDoc](https://godoc.org/github.com/Masterminds/glide?status.svg)](https://godoc.org/github.com/Masterminds/glide) [![Documentation Status](https://readthedocs.org/projects/glide/badge/?version=latest)](http://glide.readthedocs.org/en/latest/?badge=latest)
+[![Build Status](https://travis-ci.org/Masterminds/glide.svg)](https://travis-ci.org/Masterminds/glide) [![Go Report Card](http://goreportcard.com/badge/Masterminds/glide)](http://goreportcard.com/report/Masterminds/glide) [![GoDoc](https://godoc.org/github.com/Masterminds/glide?status.svg)](https://godoc.org/github.com/Masterminds/glide) [![Documentation Status](https://readthedocs.org/projects/glide/badge/?version=latest)](http://glide.readthedocs.org/en/latest/?badge=latest) [![Join us on #masterminds on Freenode](https://www.irccloud.com/invite-svg?channel=%23masterminds&hostname=irc.freenode.net&port=6697&ssl=1)](https://www.irccloud.com/invite?channel=%23masterminds&hostname=irc.freenode.net&port=6697&ssl=1)
 
 ### Features
 
diff --git a/action/ensure.go b/action/ensure.go
index 0fa529a..8d45bdd 100644
--- a/action/ensure.go
+++ b/action/ensure.go
@@ -50,13 +50,27 @@
 		os.Exit(1)
 	}
 
-	// This works with 1.5 and >=1.6.
-	cmd = exec.Command("go", "env", "GO15VENDOREXPERIMENT")
+	// Check if this is go15, which requires GO15VENDOREXPERIMENT
+	// Any release after go15 does not require that env var.
+	cmd = exec.Command("go", "version")
 	if out, err := cmd.CombinedOutput(); err != nil {
-		msg.Err("Error looking for $GOVENDOREXPERIMENT: %s.\n", err)
+		msg.Err("Error getting version: %s.\n", err)
 		os.Exit(1)
-	} else if strings.TrimSpace(string(out)) != "1" {
-		msg.Warn("To use Glide, you must set GO15VENDOREXPERIMENT=1\n")
+	} else if strings.HasPrefix(string(out), "go version 1.5") {
+		// This works with 1.5 and 1.6.
+		cmd = exec.Command("go", "env", "GO15VENDOREXPERIMENT")
+		if out, err := cmd.CombinedOutput(); err != nil {
+			msg.Err("Error looking for $GOVENDOREXPERIMENT: %s.\n", err)
+			os.Exit(1)
+		} else if strings.TrimSpace(string(out)) != "1" {
+			msg.Err("To use Glide, you must set GO15VENDOREXPERIMENT=1")
+			os.Exit(1)
+		}
+	}
+
+	// In the case where vendoring is explicitly disabled, balk.
+	if os.Getenv("GO15VENDOREXPERIMENT") == "0" {
+		msg.Err("To use Glide, you must set GO15VENDOREXPERIMENT=1")
 		os.Exit(1)
 	}
 
diff --git a/dependency/resolver.go b/dependency/resolver.go
index 1668f23..9f7e59e 100644
--- a/dependency/resolver.go
+++ b/dependency/resolver.go
@@ -307,7 +307,12 @@
 // If one of the passed in packages does not exist in the vendor directory,
 // an error is returned.
 func (r *Resolver) ResolveAll(deps []*cfg.Dependency) ([]string, error) {
-	queue := sliceToQueue(deps, r.VendorDir)
+	var queue *list.List
+	if r.ResolveAllFiles {
+		queue = sliceToQueue(deps, r.VendorDir)
+	} else {
+		queue = list.New()
+	}
 
 	loc, err := r.ResolveLocal(false)
 	if err != nil {
@@ -413,7 +418,7 @@
 		// can locate.
 		for _, imp := range pkg.Imports {
 			pi := r.FindPkg(imp)
-			if pi.Loc != LocCgo && pi.Loc != LocGoroot {
+			if pi.Loc != LocCgo && pi.Loc != LocGoroot && pi.Loc != LocAppengine {
 				msg.Debug("Package %s imports %s", dep, imp)
 			}
 			switch pi.Loc {
@@ -713,6 +718,11 @@
 	LocGoroot
 	// LocCgo indicates that the package is a a CGO package
 	LocCgo
+	// LocAppengine indicates the package is part of the appengine SDK. It's a
+	// special build mode. https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath
+	// Why does a Google product get a special case build mode with a local
+	// package?
+	LocAppengine
 )
 
 // PkgInfo represents metadata about a package found by the resolver.
@@ -793,10 +803,19 @@
 		}
 	}
 
-	// Finally, if this is "C", we're dealing with cgo
+	// If this is "C", we're dealing with cgo
 	if name == "C" {
 		info.Loc = LocCgo
 		r.findCache[name] = info
+	} else if name == "appengine" || name == "appengine_internal" ||
+		strings.HasPrefix(name, "appengine/") ||
+		strings.HasPrefix(name, "appengine_internal/") {
+		// Appengine is a special case when it comes to Go builds. It is a local
+		// looking package only available within appengine. It's a special case
+		// where Google products are playing with each other.
+		// https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath
+		info.Loc = LocAppengine
+		r.findCache[name] = info
 	}
 
 	return info
diff --git a/docs/glide.yaml.md b/docs/glide.yaml.md
index 9937939..85a2172 100644
--- a/docs/glide.yaml.md
+++ b/docs/glide.yaml.md
@@ -35,7 +35,9 @@
   - `package`: The name of the package to import and the only non-optional item. Package names follow the same patterns the `go` tool does. That means:
     - Package names that map to a VCS remote location end in .git, .bzr, .hg, or .svn. For example, `example.com/foo/pkg.git/subpkg`.
     - GitHub, BitBucket, Launchpad, IBM Bluemix Services, and Go on Google Source are special cases that don't need the VCS extension.
-  - `version`: A semantic version, semantic version range, branch, tag, or commit id to use. For more information see the [versioning documentation](versions.md).
-  - `repo`: If the package name isn't the repo location or this is a private repository it can go here. The package will be checked out from the repo and put where the package name specifies. This allows using forks.
-  - `vcs`: A VCS to use such as git, hg, bzr, or svn. This is only needed when the type cannot be detected from the name. For example, a repo ending in .git or on GitHub can be detected to be Git. For a repo on Bitbucket we can contact the API to discover the type.
+    - `version`: A semantic version, semantic version range, branch, tag, or commit id to use. For more information see the [versioning documentation](versions.md).
+    - `repo`: If the package name isn't the repo location or this is a private repository it can go here. The package will be checked out from the repo and put where the package name specifies. This allows using forks.
+    - `vcs`: A VCS to use such as git, hg, bzr, or svn. This is only needed when the type cannot be detected from the name. For example, a repo ending in .git or on GitHub can be detected to be Git. For a repo on Bitbucket we can contact the API to discover the type.
+    - `os`: A list of operating systems used for filtering. If set it will compare the current runtime OS to the one specified and only fetch the dependency if there is a match. If not set filtering is skipped. The names are the same used in build flags and `GOOS` environment variable.
+    - `arch`: A list of architectures used for filtering. If set it will compare the current runtime architecture to the one specified and only fetch the dependency if there is a match. If not set filtering is skipped. The names are the same used in build flags and `GOARCH` environment variable.
 - `devImport`: A list of development packages. Each package has the same details as those listed under import.
diff --git a/glide.go b/glide.go
index 4a29d06..9fe1e47 100644
--- a/glide.go
+++ b/glide.go
@@ -43,6 +43,7 @@
 	"github.com/Masterminds/glide/msg"
 	gpath "github.com/Masterminds/glide/path"
 	"github.com/Masterminds/glide/repo"
+	"github.com/Masterminds/glide/util"
 
 	"github.com/codegangsta/cli"
 
@@ -202,6 +203,10 @@
 					Name:  "use-gopath",
 					Usage: "Copy dependencies from the GOPATH if they exist there.",
 				},
+				cli.BoolFlag{
+					Name:  "resolve-current",
+					Usage: "Resolve dependencies for only the current system rather than all build modes.",
+				},
 			},
 			Action: func(c *cli.Context) {
 				if len(c.Args()) < 1 {
@@ -209,6 +214,11 @@
 					os.Exit(1)
 				}
 
+				if c.Bool("resolve-current") {
+					util.ResolveCurrent = true
+					msg.Warn("Only resolving dependencies for the current OS/Arch")
+				}
+
 				inst := &repo.Installer{
 					Force:           c.Bool("force"),
 					UseCache:        c.Bool("cache"),
@@ -465,8 +475,18 @@
 					Name:  "use-gopath",
 					Usage: "Copy dependencies from the GOPATH if they exist there.",
 				},
+				cli.BoolFlag{
+					Name:  "resolve-current",
+					Usage: "Resolve dependencies for only the current system rather than all build modes.",
+				},
 			},
 			Action: func(c *cli.Context) {
+
+				if c.Bool("resolve-current") {
+					util.ResolveCurrent = true
+					msg.Warn("Only resolving dependencies for the current OS/Arch")
+				}
+
 				installer := &repo.Installer{
 					DeleteUnused:    c.Bool("deleteOptIn"),
 					UpdateVendored:  c.Bool("update-vendored"),
diff --git a/tree/tree.go b/tree/tree.go
index 0ba0d56..1be49a5 100644
--- a/tree/tree.go
+++ b/tree/tree.go
@@ -143,9 +143,17 @@
 		}
 	}
 
-	// Finally, if this is "C", we're dealing with cgo
+	// If this is "C", we're dealing with cgo
 	if name == "C" {
 		info.Loc = dependency.LocCgo
+	} else if name == "appengine" || name == "appengine_internal" ||
+		strings.HasPrefix(name, "appengine/") ||
+		strings.HasPrefix(name, "appengine_internal/") {
+		// Appengine is a special case when it comes to Go builds. It is a local
+		// looking package only available within appengine. It's a special case
+		// where Google products are playing with each other.
+		// https://blog.golang.org/the-app-engine-sdk-and-workspaces-gopath
+		info.Loc = dependency.LocAppengine
 	}
 
 	return info
diff --git a/util/util.go b/util/util.go
index 9a58b04..d73001a 100644
--- a/util/util.go
+++ b/util/util.go
@@ -16,6 +16,12 @@
 	"github.com/Masterminds/vcs"
 )
 
+// ResolveCurrent selects whether the package should only the dependencies for
+// the current OS/ARCH instead of all possible permutations.
+// This is not concurrently safe which is ok for the current application. If
+// other needs arise it may need to be re-written.
+var ResolveCurrent = false
+
 func init() {
 	// Precompile the regular expressions used to check VCS locations.
 	for _, v := range vcsList {
@@ -262,6 +268,15 @@
 // TODO: This should be moved to the `dependency` package.
 func GetBuildContext() (*BuildCtxt, error) {
 	buildContext := &BuildCtxt{build.Default}
+
+	// If we aren't resolving for the current system set to look at all
+	// build modes.
+	if !ResolveCurrent {
+		// This tells the context scanning to skip filtering on +build flags or
+		// file names.
+		buildContext.UseAllFiles = true
+	}
+
 	if goRoot := os.Getenv("GOROOT"); len(goRoot) == 0 {
 		out, err := exec.Command("go", "env", "GOROOT").Output()
 		if goRoot = strings.TrimSpace(string(out)); len(goRoot) == 0 || err != nil {