Manage Go dependencies using Glide
Tags: go, glide
Published: 2018-01-16 02:46:57

---
title: "Manage Go dependencies using Glide"
published: true
description: "An example showing how to manage Go packages using Glide."
tags: [Golang, Glide]
cover_image: https://thepracticaldev.s3.amazonaws.com/i/v397kgihw6hbs3kmb9t3.png
---

_Originally posted on [Boatswain Blog](https://blog.boatswain.io/post/manage-go-dependencies-using-glide/)._

---

**Update @ 2018-01-17**

You might want to consider using a new dependency management tool called [dep][dep] as suggested by [nasa9084](https://dev.to/nasa9084/comment/2317).

---

[Glide][glide] is a [Go][golang] package management tool, like [npm][npm] in [NodeJS][nodejs]. Let's create a simple example and see how it works.

## Create the project inside $GOPATH

The project folder has to be under _$GOPATH_ in order to resolve the [Go][golang] package paths. In this example, the project root folder is _$GOPATH/src/gitlab.com/ykyuen/glide-example_.

## A hello world Go program

Let's create a simple [Go][golang] program.

`main.go`

```go
package main

import "fmt"

func main() {
  fmt.Println("hello world")
}
```

## Build and run

```
[ykyuen@camus glide-example]$ go build -o hello
[ykyuen@camus glide-example]$ ./hello
hello world
```

## Add a Go dependency

[dustin/go-humanize][humanize] is a helpful [Go][golang] package to format number, string and time. Let's update our [Go][golang] program as follow.

`main.go`

```go
package main

import humanize "github.com/dustin/go-humanize"
import "fmt"

func main() {
  fmt.Println("hello world")
  fmt.Printf("That file is %s.\n", humanize.Bytes(82854982)) // That file is 83 MB.
  fmt.Printf("You're my %s best friend.\n", humanize.Ordinal(193)) // You are my 193rd best friend.
  fmt.Printf("You owe $%s.\n", humanize.Comma(6582491)) // You owe $6,582,491.
}
```

Now if we try to build it, it will throws the following error.

```
[ykyuen@camus glide-example]$ go build -o hello
main.go:3:8: cannot find package "github.com/dustin/go-humanize" in any of:
  /home/ykyuen/tools/go1.8.4/src/github.com/dustin/go-humanize (from $GOROOT)
  /home/ykyuen/go/src/github.com/dustin/go-humanize (from $GOPATH)
```

This is because we haven't downloaded the [dustin/go-humanize][humanize]. Without using [Glide][glide], we could solve this build error by running the _go get_ command.

```
go get github.com/dustin/go-humanize
```

But in this case, anyone who checkouts the project has no idea what packages are needed in order to build the program. If you have already run the _go get_ command, delete the package before proceeding.

## The Glide way

### Create the glide.yaml

The _glide.yaml_ could be generated by the _glide create_ command. It will scan the [Go][golang] src files and include all the dependencies needed. Here is the output of this example.

```
[ykyuen@camus glide-example]$ glide create
[INFO]  Generating a YAML configuration file and guessing the dependencies
[INFO]  Attempting to import from other package managers (use --skip-import to skip)
[INFO]  Scanning code to look for dependencies
[INFO]  --> Found reference to github.com/dustin/go-humanize
[INFO]  Writing configuration file (glide.yaml)
[INFO]  Would you like Glide to help you find ways to improve your glide.yaml configuration?
[INFO]  If you want to revisit this step you can use the config-wizard command at any time.
[INFO]  Yes (Y) or No (N)?
Y
[INFO]  Looking for dependencies to make suggestions on
[INFO]  --> Scanning for dependencies not using version ranges
[INFO]  --> Scanning for dependencies using commit ids
[INFO]  Gathering information on each dependency
[INFO]  --> This may take a moment. Especially on a codebase with many dependencies
[INFO]  --> Gathering release information for dependencies
[INFO]  --> Looking for dependency imports where versions are commit ids
[INFO]  No proposed changes found. Have a nice day.
```

`glide.yaml`

```yaml
package: gitlab.com/ykyuen/glide-example
import:
- package: github.com/dustin/go-humanize
```

### Download the Go dependencies to the vendor folder

Next, we execute the _glide install_ command to download the dependencies.

```
[ykyuen@camus glide-example]$ glide install
[INFO]  Lock file (glide.lock) does not exist. Performing update.
[INFO]  Downloading dependencies. Please wait...
[INFO]  --> Fetching updates for github.com/dustin/go-humanize
[INFO]  Resolving imports
[INFO]  Downloading dependencies. Please wait...
[INFO]  Setting references for remaining imports
[INFO]  Exporting resolved dependencies...
[INFO]  --> Exporting github.com/dustin/go-humanize
[INFO]  Replacing existing vendor dependencies
[INFO]  Project relies on 1 dependencies.
```

This will generated the _glide.lock_ files and the _vendor_ folder which contains the [dustin/go-humanize][humanize] package. The _glide.lock_ file contains the version of the package. It could be a **tag** or a **git commit hash**.

`glide.lock`

```yaml
hash: de8aada0e0453f13dc438db5fb412db797d701d6afeadcc052c477fd55e01aa8
updated: 2017-12-04T23:20:53.616704682+08:00
imports:
- name: github.com/dustin/go-humanize
  version: 8929fe90cee4b2cb9deb468b51fb34eba64d1bf0
testImports: []
```

### Update dependency's version

The [8929fe9][8929fe9] commit is quite outdated. We could modify version in the _glide.lock_ file and run _glide install_ again to get the desired version of your package.

`glide.lock`

```yaml
hash: de8aada0e0453f13dc438db5fb412db797d701d6afeadcc052c477fd55e01aa8
updated: 2017-12-04T23:20:53.616704682+08:00
imports:
- name: github.com/dustin/go-humanize
  version: bb3d318650d48840a39aa21a027c6630e198e626
testImports: []
```

```
[ykyuen@camus glide-example]$ glide install
[INFO]  Downloading dependencies. Please wait...
[INFO]  --> Found desired version locally github.com/dustin/go-humanize bb3d318650d48840a39aa21a027c6630e198e626!
[INFO]  Setting references.
[INFO]  --> Setting version for github.com/dustin/go-humanize to bb3d318650d48840a39aa21a027c6630e198e626.
[INFO]  Exporting resolved dependencies...
[INFO]  --> Exporting github.com/dustin/go-humanize
[INFO]  Replacing existing vendor dependencies
```

### Build and run again

```
[ykyuen@camus glide-example]$ go build -o hello
[ykyuen@camus glide-example]$ ./hello
hello world
That file is 83 MB.
You're my 193rd best friend.
You owe $6,582,491.
```

### Check in the vendor folder?

For [NodeJS][nodejs] projects there is a common practice that we will ignore the *node_modules* folder in the code repository. On the other hand, the [Go][golang] community has a different point of view.

- [Should I add "vendor" directory into .gitignore if I am using tools like glide or godep?](https://www.reddit.com/r/golang/comments/6b9817/should_i_add_vendor_directory_into_gitignore_if_i/)

There isn't an absolute answer. Pick the option which you feel more comfortable.

### Other concerns

When the project is getting bigger, [glide][glide] might take quite a while to work as the dependency tree is getting bigger and bigger. In addition, it's hard to manage to the dependency's version.

As [nasa9084](https://dev.to/nasa9084/comment/2317) suggested, you might want to consider using a new dependency management tool called [dep][dep] as suggested by the [Glide][glide] team. [dep][dep] has a [growing popularity and in active development](https://go.libhunt.com/project/dep/vs/glide). Do take a look on the [dep's project status](https://github.com/golang/dep#current-status) and pick the one which you feel more comfortable.

## Summary

- Project folder has to be under _$GOPATH_.
- Dependencies would be included automatically by scanning all the source code.
- Dependency's version is managed by _glide.lock_.
- Commit the _vendor_ folder or not is still an open question.
- Performance issue when dependency tree getting bigger.
- Complete example is available on [gitlab.com](https://gitlab.com/ykyuen/glide-example).





[glide]: https://glide.sh/
[golang]: https://golang.org/
[npm]: https://www.npmjs.com/
[nodejs]: https://nodejs.org/en/
[humanize]: https://github.com/dustin/go-humanize
[8929fe9]: https://github.com/dustin/go-humanize/commit/8929fe90cee4b2cb9deb468b51fb34eba64d1bf0
[dep]: https://github.com/golang/dep