Merge pull request #334 from Masterminds/exclude-dirs

Issue #297: Adds exclude property for directories in local codebase to exclude from scanning.
diff --git a/action/install.go b/action/install.go
index 8608dc8..bed3744 100644
--- a/action/install.go
+++ b/action/install.go
@@ -12,7 +12,7 @@
 )
 
 // Install installs a vendor directory based on an existing Glide configuration.
-func Install(installer *repo.Installer) {
+func Install(installer *repo.Installer, strip bool) {
 	base := "."
 	// Ensure GOPATH
 	EnsureGopath()
@@ -22,7 +22,7 @@
 	// Lockfile exists
 	if !gpath.HasLock(base) {
 		msg.Info("Lock file (glide.lock) does not exist. Performing update.")
-		Update(installer, false)
+		Update(installer, false, strip)
 		return
 	}
 	// Load lockfile
@@ -53,9 +53,16 @@
 	}
 
 	// VendoredCleanup. This should ONLY be run if UpdateVendored was specified.
-	if installer.UpdateVendored {
+	// When stripping VCS happens this will happen as well. No need for double
+	// effort.
+	if installer.UpdateVendored && !strip {
 		repo.VendoredCleanup(newConf)
 	}
+
+	if strip {
+		msg.Info("Removing version control data from vendor directory...")
+		gpath.StripVcs()
+	}
 }
 
 // LoadLockfile loads the contents of a glide.lock file.
diff --git a/action/update.go b/action/update.go
index e86e04a..cf87b28 100644
--- a/action/update.go
+++ b/action/update.go
@@ -11,7 +11,7 @@
 )
 
 // Update updates repos and the lock file from the main glide yaml.
-func Update(installer *repo.Installer, skipRecursive bool) {
+func Update(installer *repo.Installer, skipRecursive, strip bool) {
 	base := "."
 	EnsureGopath()
 	EnsureVendorDir()
@@ -58,7 +58,9 @@
 	}
 	// Vendored cleanup
 	// VendoredCleanup. This should ONLY be run if UpdateVendored was specified.
-	if installer.UpdateVendored {
+	// When stripping VCS happens this will happen as well. No need for double
+	// effort.
+	if installer.UpdateVendored && !strip {
 		repo.VendoredCleanup(confcopy)
 	}
 
@@ -87,4 +89,9 @@
 	} else {
 		msg.Warn("Skipping lockfile generation because full dependency tree is not being calculated")
 	}
+
+	if strip {
+		msg.Info("Removing version control data from vendor directory...")
+		gpath.StripVcs()
+	}
 }
diff --git a/glide.go b/glide.go
index 6d4bed5..a1b6f64 100644
--- a/glide.go
+++ b/glide.go
@@ -404,6 +404,10 @@
 					Name:  "use-gopath",
 					Usage: "Copy dependencies from the GOPATH if they exist there.",
 				},
+				cli.BoolFlag{
+					Name:  "strip-vcs",
+					Usage: "Removes version control metada (e.g, .git directory) from the vendor folder.",
+				},
 			},
 			Action: func(c *cli.Context) {
 				installer := repo.NewInstaller()
@@ -415,7 +419,7 @@
 				installer.Home = gpath.Home()
 				installer.DeleteUnused = c.Bool("deleteOptIn")
 
-				action.Install(installer)
+				action.Install(installer, c.Bool("strip-vcs"))
 			},
 		},
 		{
@@ -488,6 +492,10 @@
 					Name:  "resolve-current",
 					Usage: "Resolve dependencies for only the current system rather than all build modes.",
 				},
+				cli.BoolFlag{
+					Name:  "strip-vcs",
+					Usage: "Removes version control metada (e.g, .git directory) from the vendor folder.",
+				},
 			},
 			Action: func(c *cli.Context) {
 
@@ -506,7 +514,7 @@
 				installer.Home = gpath.Home()
 				installer.DeleteUnused = c.Bool("deleteOptIn")
 
-				action.Update(installer, c.Bool("no-recursive"))
+				action.Update(installer, c.Bool("no-recursive"), c.Bool("strip-vcs"))
 			},
 		},
 		{
diff --git a/glide.lock b/glide.lock
index 8087d1c..5187ded 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,12 +1,12 @@
 hash: 1b76070c56de9f698ebbd32b2f36d2c972888fc0793f7843b0925e4faca65d4b
-updated: 2016-03-07T15:05:34.774169565-05:00
+updated: 2016-03-09T11:00:49.889321962-05:00
 imports:
 - name: github.com/codegangsta/cli
-  version: c31a7975863e7810c92e2e288a9ab074f9a88f29
+  version: aca5b047ed14d17224157c3434ea93bf6cdaadee
 - name: github.com/Masterminds/semver
   version: 513f3dcb3ecfb1248831fb5cb06a23a3cd5935dc
 - name: github.com/Masterminds/vcs
   version: 242477a09d9db06a848c5305525168f042d96871
 - name: gopkg.in/yaml.v2
-  version: f7716cbe52baa25d2e9b0d0da546fcf909fc16b4
+  version: a83829b6f1293c91addabc89d0571c246397bbf4
 devImports: []
diff --git a/path/path.go b/path/path.go
index f79125d..cfa46c2 100644
--- a/path/path.go
+++ b/path/path.go
@@ -1,7 +1,7 @@
 // Package path contains path and environment utilities for Glide.
 //
-//This includes tools to find and manipulate Go path variables, as well as
-//tools for copying from one path to another.
+// This includes tools to find and manipulate Go path variables, as well as
+// tools for copying from one path to another.
 package path
 
 import (
diff --git a/path/strip.go b/path/strip.go
new file mode 100644
index 0000000..e7abe29
--- /dev/null
+++ b/path/strip.go
@@ -0,0 +1,38 @@
+package path
+
+import (
+	"os"
+	"path/filepath"
+
+	"github.com/Masterminds/glide/msg"
+)
+
+// StripVcs removes VCS metadata (.git, .hg, .bzr, .svn) from the vendor/
+// directory.
+func StripVcs() error {
+	if _, err := os.Stat(VendorDir); err != nil {
+		if os.IsNotExist(err) {
+			msg.Debug("Vendor directory does not exist.")
+		}
+
+		return err
+	}
+	return filepath.Walk(VendorDir, stripHandler)
+}
+
+func stripHandler(path string, info os.FileInfo, err error) error {
+
+	name := info.Name()
+	if name == ".git" || name == ".bzr" || name == ".svn" || name == ".hg" {
+		if _, err := os.Stat(path); err == nil {
+			if info.IsDir() {
+				msg.Info("Removing: %s", path)
+				return os.RemoveAll(path)
+			}
+
+			msg.Debug("%s is not a directory. Skipping removal", path)
+			return nil
+		}
+	}
+	return nil
+}
diff --git a/path/strip_test.go b/path/strip_test.go
new file mode 100644
index 0000000..6c11194
--- /dev/null
+++ b/path/strip_test.go
@@ -0,0 +1,67 @@
+package path
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func TestStripVcs(t *testing.T) {
+	tempDir, err := ioutil.TempDir("", "strip-vcs")
+	if err != nil {
+		t.Error(err)
+	}
+
+	defer func() {
+		err = os.RemoveAll(tempDir)
+		if err != nil {
+			t.Error(err)
+		}
+	}()
+
+	// Make VCS directories.
+	gp := filepath.Join(tempDir, ".git")
+	err = os.Mkdir(gp, 0755)
+	if err != nil {
+		t.Error(err)
+	}
+
+	bp := filepath.Join(tempDir, ".bzr")
+	err = os.Mkdir(bp, 0755)
+	if err != nil {
+		t.Error(err)
+	}
+
+	hp := filepath.Join(tempDir, ".hg")
+	err = os.Mkdir(hp, 0755)
+	if err != nil {
+		t.Error(err)
+	}
+
+	sp := filepath.Join(tempDir, ".svn")
+	err = os.Mkdir(sp, 0755)
+	if err != nil {
+		t.Error(err)
+	}
+
+	ov := VendorDir
+	VendorDir = tempDir
+
+	StripVcs()
+
+	VendorDir = ov
+
+	if _, err := os.Stat(gp); !os.IsNotExist(err) {
+		t.Error(".git directory not deleted")
+	}
+	if _, err := os.Stat(hp); !os.IsNotExist(err) {
+		t.Error(".hg directory not deleted")
+	}
+	if _, err := os.Stat(bp); !os.IsNotExist(err) {
+		t.Error(".bzr directory not deleted")
+	}
+	if _, err := os.Stat(sp); !os.IsNotExist(err) {
+		t.Error(".svn directory not deleted")
+	}
+}