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 +}