Merge pull request #458 from Masterminds/feat/get-wizard

Adding wizard and version detection to glide get
diff --git a/action/get.go b/action/get.go
index 58384de..5d4e143 100644
--- a/action/get.go
+++ b/action/get.go
@@ -12,12 +12,13 @@
 	gpath "github.com/Masterminds/glide/path"
 	"github.com/Masterminds/glide/repo"
 	"github.com/Masterminds/glide/util"
+	"github.com/Masterminds/semver"
 )
 
 // Get fetches one or more dependencies and installs.
 //
 // This includes resolving dependency resolution and re-generating the lock file.
-func Get(names []string, installer *repo.Installer, insecure, skipRecursive, strip, stripVendor bool) {
+func Get(names []string, installer *repo.Installer, insecure, skipRecursive, strip, stripVendor, nonInteract bool) {
 	if installer.UseCache {
 		cache.SystemLock()
 	}
@@ -32,8 +33,8 @@
 	}
 
 	// Add the packages to the config.
-	if count, err := addPkgsToConfig(conf, names, insecure); err != nil {
-		msg.Die("Failed to get new packages: %s", err)
+	if count, err2 := addPkgsToConfig(conf, names, insecure, nonInteract); err2 != nil {
+		msg.Die("Failed to get new packages: %s", err2)
 	} else if count == 0 {
 		msg.Warn("Nothing to do")
 		return
@@ -126,10 +127,13 @@
 // - separates repo from packages
 // - sets up insecure repo URLs where necessary
 // - generates a list of subpackages
-func addPkgsToConfig(conf *cfg.Config, names []string, insecure bool) (int, error) {
+func addPkgsToConfig(conf *cfg.Config, names []string, insecure, nonInteract bool) (int, error) {
 
-	msg.Info("Preparing to install %d package.", len(names))
-
+	if len(names) == 1 {
+		msg.Info("Preparing to install %d package.", len(names))
+	} else {
+		msg.Info("Preparing to install %d packages.", len(names))
+	}
 	numAdded := 0
 	for _, name := range names {
 		var version string
@@ -139,6 +143,8 @@
 			version = parts[1]
 		}
 
+		msg.Info("Attempting to get package %s", name)
+
 		root, subpkg := util.NormalizeName(name)
 		if len(root) == 0 {
 			return 0, fmt.Errorf("Package name is required for %q.", name)
@@ -150,20 +156,20 @@
 			if subpkg != "" {
 				dep := conf.Imports.Get(root)
 				if dep.HasSubpackage(subpkg) {
-					msg.Warn("Package %q is already in glide.yaml. Skipping", name)
+					msg.Warn("--> Package %q is already in glide.yaml. Skipping", name)
 				} else {
 					dep.Subpackages = append(dep.Subpackages, subpkg)
-					msg.Info("Adding sub-package %s to existing import %s", subpkg, root)
+					msg.Info("--> Adding sub-package %s to existing import %s", subpkg, root)
 					numAdded++
 				}
 			} else {
-				msg.Warn("Package %q is already in glide.yaml. Skipping", root)
+				msg.Warn("--> Package %q is already in glide.yaml. Skipping", root)
 			}
 			continue
 		}
 
 		if conf.HasIgnore(root) {
-			msg.Warn("Package %q is set to be ignored in glide.yaml. Skipping", root)
+			msg.Warn("--> Package %q is set to be ignored in glide.yaml. Skipping", root)
 			continue
 		}
 
@@ -171,24 +177,26 @@
 			Name: root,
 		}
 
-		if version != "" {
-			dep.Reference = version
-		}
-
 		// When retriving from an insecure location set the repo to the
 		// insecure location.
 		if insecure {
 			dep.Repository = "http://" + root
 		}
 
+		if version != "" {
+			dep.Reference = version
+		} else if !nonInteract {
+			getWizard(dep)
+		}
+
 		if len(subpkg) > 0 {
 			dep.Subpackages = []string{subpkg}
 		}
 
 		if dep.Reference != "" {
-			msg.Info("Importing %s with the version %s", dep.Name, dep.Reference)
+			msg.Info("--> Adding %s to your configuration with the version %s", dep.Name, dep.Reference)
 		} else {
-			msg.Info("Importing %s", dep.Name)
+			msg.Info("--> Adding %s to your configuration %s", dep.Name)
 		}
 
 		conf.Imports = append(conf.Imports, dep)
@@ -196,3 +204,34 @@
 	}
 	return numAdded, nil
 }
+
+func getWizard(dep *cfg.Dependency) {
+	var remote string
+	if dep.Repository != "" {
+		remote = dep.Repository
+	} else {
+		remote = "https://" + dep.Name
+	}
+
+	// Lookup dependency info and store in cache.
+	msg.Info("--> Gathering release information for %s", dep.Name)
+	wizardFindVersions(dep)
+
+	memlatest := cache.MemLatest(remote)
+	if memlatest != "" {
+		dres := wizardAskLatest(memlatest, dep)
+		if dres {
+			dep.Reference = memlatest
+
+			sv, err := semver.NewVersion(dep.Reference)
+			if err == nil {
+				res := wizardAskRange(sv, dep)
+				if res == "m" {
+					dep.Reference = "^" + sv.String()
+				} else if res == "p" {
+					dep.Reference = "~" + sv.String()
+				}
+			}
+		}
+	}
+}
diff --git a/action/get_test.go b/action/get_test.go
index 94d18c7..b61490d 100644
--- a/action/get_test.go
+++ b/action/get_test.go
@@ -24,7 +24,7 @@
 		"github.com/Masterminds/semver",
 	}
 
-	addPkgsToConfig(conf, names, false)
+	addPkgsToConfig(conf, names, false, true)
 
 	if !conf.HasDependency("github.com/Masterminds/semver") {
 		t.Error("addPkgsToConfig failed to add github.com/Masterminds/semver")
diff --git a/cache/memory.go b/cache/memory.go
index 3809331..2cd5d51 100644
--- a/cache/memory.go
+++ b/cache/memory.go
@@ -100,7 +100,7 @@
 	latest, found := m.latest[name]
 	if found {
 		lv, err := semver.NewVersion(latest)
-		if err != nil {
+		if err == nil {
 			if sv.GreaterThan(lv) {
 				m.latest[name] = version
 			}
diff --git a/glide.go b/glide.go
index 5bd2894..61b6e2b 100644
--- a/glide.go
+++ b/glide.go
@@ -246,6 +246,10 @@
 					Name:  "strip-vendor, v",
 					Usage: "Removes nested vendor and Godeps/_workspace directories. Requires --strip-vcs.",
 				},
+				cli.BoolFlag{
+					Name:  "non-interactive",
+					Usage: "Disable interactive prompts.",
+				},
 			},
 			Action: func(c *cli.Context) {
 				if c.Bool("strip-vendor") && !c.Bool("strip-vcs") {
@@ -271,7 +275,7 @@
 				inst.ResolveAllFiles = c.Bool("all-dependencies")
 				packages := []string(c.Args())
 				insecure := c.Bool("insecure")
-				action.Get(packages, inst, insecure, c.Bool("no-recursive"), c.Bool("strip-vcs"), c.Bool("strip-vendor"))
+				action.Get(packages, inst, insecure, c.Bool("no-recursive"), c.Bool("strip-vcs"), c.Bool("strip-vendor"), c.Bool("non-interactive"))
 			},
 		},
 		{