Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Easy Golang Dependency Management

DZone's Guide to

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.

· Integration Zone
Free Resource

Discover how Microservices are a type of software architecture where large applications are made up of small, self-contained units working together through APIs that are not dependent on a specific language. Brought to you in partnership with AppDynamics.

Go 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.

Image title

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:

  1. Godep.

  2. Glide.

  3. 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. 

Discover the six challenges and best practices in managing microservice performance, brought to you in partnership with AppDynamics.

Topics:
go ,golang ,dependency management ,coding ,source code ,integration

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}