Add a rebuild command as suggested by @AngerM in #1
diff --git a/README.md b/README.md
index b17f3e5..d46fb98 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,21 @@
Full usage on [GoDoc ](http://godoc.org/github.com/FiloSottile/gvt)
+## Alternative: not checking in vendored source
+
+Some developers prefer not to check in the source of the vendored dependencies. In that case you can add lines like these to e.g. your `.gitignore`
+
+ vendor/**
+ !vendor/manifest
+
+When you check out the source again, you can then run `gvt rebuild` to fetch all the dependencies at the revisions specified in the `vendor/manifest` file.
+
+Please consider that this approach has the following consequences:
+
+ * the package consumer will need gvt to fetch the dependencies
+ * the dependencies will need to remain available from the source repositories: if the original repository goes down or rewrites history, build reproducibility is lost
+ * `go get` won't work on your package
+
## Why
There are many Go vendoring tools, but they all have some subset of the following problems
diff --git a/alldocs.go b/alldocs.go
index b05f1c6..85e106b 100644
--- a/alldocs.go
+++ b/alldocs.go
@@ -10,6 +10,7 @@
The commands are:
fetch fetch a remote dependency
+ rebuild rebuild dependencies from manifest
update update a local dependency
list list dependencies one per line
delete delete a local dependency
@@ -42,6 +43,26 @@
-precaire
allow the use of insecure protocols.
+Rebuild dependencies from manifest
+
+Usage:
+ gvt rebuild
+
+rebuild fetches the dependencies listed in the manifest.
+
+It's meant for workflows that don't include checking in to VCS the vendored
+source, for example if .gitignore includes lines like
+
+ vendor/**
+ !vendor/manifest
+
+Note that such a setup requires "gvt rebuild" to build the source, relies on
+the availability of the dependencies repositories and breaks "go get".
+
+Flags:
+ -precaire
+ allow the use of insecure protocols.
+
Update a local dependency
Usage:
diff --git a/main.go b/main.go
index 89a8dc6..c95d30b 100644
--- a/main.go
+++ b/main.go
@@ -27,6 +27,7 @@
var commands = []*Command{
cmdFetch,
+ cmdRebuild,
cmdUpdate,
cmdList,
cmdDelete,
diff --git a/rebuild.go b/rebuild.go
new file mode 100644
index 0000000..9d4b0fa
--- /dev/null
+++ b/rebuild.go
@@ -0,0 +1,89 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+
+ "github.com/FiloSottile/gvt/gbvendor"
+)
+
+var (
+ rbInsecure bool // Allow the use of insecure protocols
+)
+
+func addRebuildFlags(fs *flag.FlagSet) {
+ fs.BoolVar(&rbInsecure, "precaire", false, "allow the use of insecure protocols")
+}
+
+var cmdRebuild = &Command{
+ Name: "rebuild",
+ UsageLine: "rebuild",
+ Short: "rebuild dependencies from manifest",
+ Long: `rebuild fetches the dependencies listed in the manifest.
+
+It's meant for workflows that don't include checking in to VCS the vendored
+source, for example if .gitignore includes lines like
+
+ vendor/**
+ !vendor/manifest
+
+Note that such a setup requires "gvt rebuild" to build the source, relies on
+the availability of the dependencies repositories and breaks "go get".
+
+Flags:
+ -precaire
+ allow the use of insecure protocols.
+`,
+ Run: func(args []string) error {
+ switch len(args) {
+ case 0:
+ return rebuild()
+ default:
+ return fmt.Errorf("rebuild takes no arguments")
+ }
+ },
+ AddFlags: addRebuildFlags,
+}
+
+func rebuild() error {
+ m, err := vendor.ReadManifest(manifestFile())
+ if err != nil {
+ return fmt.Errorf("could not load manifest: %v", err)
+ }
+
+ for _, dep := range m.Dependencies {
+ dst := filepath.Join(vendorDir(), dep.Importpath)
+ if _, err := os.Stat(dst); err == nil {
+ if err := vendor.RemoveAll(dst); err != nil {
+ // TODO need to apply vendor.cleanpath here too
+ return fmt.Errorf("dependency could not be deleted: %v", err)
+ }
+ }
+
+ log.Printf("fetching %s", dep.Importpath)
+
+ repo, _, err := vendor.DeduceRemoteRepo(dep.Importpath, rbInsecure)
+ if err != nil {
+ return err
+ }
+
+ wc, err := repo.Checkout("", "", dep.Revision)
+ if err != nil {
+ return err
+ }
+
+ src := filepath.Join(wc.Dir(), dep.Path)
+ if err := vendor.Copypath(dst, src); err != nil {
+ return err
+ }
+
+ if err := wc.Destroy(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}