Easy Golang Dependency Management
Go dependency management isn't always straightforward, but this tutorial aims to show you how to keep things simple with dep.
Join the DZone community and get the full member experience.
Join For FreeGo dependency management is far from satisfying. In any other commonly used language like Java, JavaScript, Ruby, Python, and Scala, you have state of the art dependency management tools like NPM or Maven.
The Problem
Go Get is the default package manager for Go. However, the problem with it is that Go Get fetches the latest dependency version which is not already on the disk. This means that if you build your projects on two different occasions, you will not get a reproducible set of dependencies. Our problems are:
1. Repeatability: at different times, compile and package exactly the same output.
2. Isolation between projects: one project should not affect another.
Instead of delving deeper into the problem, we are going to go straight into the two most common solutions.
The Leading Dependency Managers for Go
There are currently three leading projects to resolve that problem:
Godep.
Glide.
Dep.
Dep is the one which should take the crown, while glide is currently more stable and feature-rich. If you go the path of dep today, you might have issues, you might miss some features, but in most cases, your most basic use cases would be fulfilled. My recommendation would be to go with dep; if you have issues larger than you can take upon yourself, either contribute a fix or talk to the community, or move to glide. With that aside, let's see the steps to utilize dep in order to manage your Go dependencies!
Our Plan
Step 1: Install Go if you don't already have it.
Step 2: Install dep, our current favorite simple dependency management tool.
Step 3: Create an example Go project.
Step 4: Try to compile (it will fail, but don't worry).
Step 5: Use Godep to fetch the dependency- once without version, and once with version- and run it.
Step 1: Install Go If You Don't Have It
On Ubuntu, that would be (using gvm):
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
vi .bashrc
[[ -s "$HOME/.gvm/scripts/gvm" ]] && source "$HOME/.gvm/scripts/gvm"
# logout and login from shell
$ gvm listall # => list all go available
# if you don't have any prior version of go installed first you need to install 1.4
$ gvm install go1.4.3
Installing go1.4.3...
* Compiling...
go1.4.3 successfully installed!e
$ gvm use go1.4.3 # => you first need to use any go to install a newer version.
$ gvm install 1.8.1 # => install the latest stable (in our case 1.8.1)
$ gvm use 1.8.1 # => use latest stable
$ go --version # => expect to see the latest stable
Step 2: Install dep and Create an Example
We first install dep:
go get -u github.com/golang/dep/...
That's it; this step is super easy and this is all we needed to do in order to install dep. Let's verify that it's installed:
$ dep
dep is a tool for managing dependencies for Go projects
Usage: dep <command>
Commands:
init Initialize a new project with manifest and lock files
status Report the status of the project's dependencies
ensure Ensure a dependency is safely vendored in the project
remove Remove a dependency from the project
Examples:
dep init set up a new project
dep ensure install the project's dependencies
dep ensure -update update the locked versions of all dependencies
dep ensure github.com/pkg/errors add a dependency to the project
Step 3: Create the Example Source Code
We then move on to create example folder and project:
cd $GOPATH/src/github.com/tomer-ben-david
mkdir dep-example
cd dep-example
vi main.go
Enter some code into main.go, which utilizes 3rd party library cookoo
:
package main
import "fmt"
import "github.com/Masterminds/cookoo"
func main() {
// Build a new Cookoo app.
registry, router, context := cookoo.Cookoo()
// Fill the registry.
registry.AddRoutes(
cookoo.Route{
Name: "TEST",
Help: "A test route",
Does: cookoo.Tasks{
cookoo.Cmd{
Name: "hi",
Fn: HelloWorld,
},
},
},
)
// Execute the route.
router.HandleRequest("TEST", context, false)
}
func HelloWorld(cxt cookoo.Context, params *cookoo.Params) (interface{}, cookoo.Interrupt) {
fmt.Println("Hello World")
return true, nil
}
Step 4: Try To Compile (It Won't)
We first try to compile the code, but as we didn't fetch a cookoo library, it will fail:
$ go install
main.go:4:8: cannot find package "github.com/Masterminds/cookoo" in any of:
/home/.gvm/pkgsets/go1.8.1/global/src/github.com/tomer-ben-david/dep-example/vendor/github.com/Masterminds/cookoo (vendor tree)
/home/.gvm/gos/go1.8.1/src/github.com/Masterminds/cookoo (from $GOROOT)
/home/.gvm/pkgsets/go1.8.1/global/src/github.com/Masterminds/cookoo (from $GOPATH)
Step 5: Use Dep To Get The Dependency
We first fetch the dependency. If we don't specify a library version, note that our manifest.json will stay empty, as will our vendor folder, without a specific version of the library we have asked for.
dep ensure github.com/Masterminds/cookoo
dep: No constraint or alternate source specified for "github.com/Masterminds/cookoo", omitting from manifest
$ cat manifest.json # => our manifest json is empty no version specified!
{}
Now let's fetch a specific version of that library, namely 1.2.0! Note that the version below in manifest.json would be stored locally for our project so we can reproduce that project if we compile it.
$ dep ensure github.com/Masterminds/cookoo@^1.2.0
$ cat manifest.json # => as we have requested a specific version manifest.json will hold that version! isn't that just great, a versoin for each project!
{
"dependencies": {
"github.com/Masterminds/cookoo": {
"version": "^1.2.0"
}
}
}
Now we can run compile and run our project.
$ go install
$ $GOPATH/bin/dep-example
Hello World
Dep is a simple tool which is currently in alpha, and not stable in order to help us manage Go dependencies. We need a proper dependency management for Go in order to keep our dependencies rather sane, just as any language supports. We need to be able to reproduce a Go release from its source code and versions libraries, and also to be able to separate in between different projects and their libraries. While there are a few tools to do that, glide
seems to be the most updated and stable one and dep
library is a new one in alpha stage, but does the basic job.
Opinions expressed by DZone contributors are their own.
Comments