d2fn/gopack — pull request #48 by mihasya (2013-11-05 17:20:50+00:00)
Title: Providers and sources

### Problem

`gopack` and other tools currently do not help in the case of setting up a completely clean repository from private repos and ensuring their full consistency, including transitive dependencies. Any dependency that cannot be fetched using `go get` in the first place requires pre-massaging, which is an obnoxiously manual process.

### Solution

Introduce the notion of `provider` and `source` to `gopack.config`, where:

* `provider` is a VCS (defaulting to `go get` to preserve backwards compatibility)
* `source` is the location whence the `provider` should clone/checkout from

This effectively bypasses `go get` for repo initialization. Requiring both `provider` and `source` explicitly avoids us having to write code to try to detect what sort of repo is being checked out (see the horror at the relevant `go get` code path [here](http://golang.org/src/cmd/go/vcs.go#L331))

One argument that I'd like to pre-empt is that this requires a lot of extra information in the config.

* These features are completely optional, and `gopack` will continue to work exactly as is
* The cherry-on-top for this pull request is actually the NEXT pull request I'm working on, which will include a `gopack snapshot` command. This command will walk the dependency tree and generate a gopack.config based on the current state of your `GOPATH`, thus completely removing the need for anyone to actually manually edit a `gopack.config`. This pull request lays the groundwork to make that command possible.

### Changes

* Optional pair of `source` and `provider` properties has been added to `gopack.config` entries.
* Some commands have been changed to return an error instead of calling `failf`. I'd generally like to discourage the use of `failf` and anything else that calls `exit` outside of `main.go`, but I only changed the commands that I touched for now which were `Dep.CheckValidity` (now `Validate`) and `Config.LoadDependencyModel` which calls that function. Making this change enabled me to better test that stuff behaved well in error conditions as well (actually capturing an `error` when one was expected).
* `Scm` interface has been expanded to include `Init` and a `Go` implementation has been added, which simply uses `go get` for `Init` and then wraps whatever underlying Scm implementation is set up by `go get`. `Dep.Scm` has been modified accordingly; it returns `Go{nil}` if no provider is specified and the `/src/...` directory has not yet been initialized, then returns the appropriate `Scm` implementation on subsequent runs.
* Again: all of these changes are backwards-compatible. With the exception of capturing an error return value, none of the existing tests had to be modified.

Cheers!