Yuen Ying Kit
Posted on January 16, 2018
Originally posted on Boatswain Blog.
Update @ 2018-01-17
You might want to consider using a new dependency management tool called dep as suggested by nasa9084.
Glide is a Go package management tool, like npm in 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 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 program.
main.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 is a helpful Go package to format number, string and time. Let's update our Go program as follow.
main.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. Without using 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 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
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 package. The glide.lock file contains the version of the package. It could be a tag or a git commit hash.
glide.lock
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 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
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 projects there is a common practice that we will ignore the node_modules folder in the code repository. On the other hand, the Go community has a different point of view.
There isn't an absolute answer. Pick the option which you feel more comfortable.
Other concerns
When the project is getting bigger, 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 suggested, you might want to consider using a new dependency management tool called dep as suggested by the Glide team. dep has a growing popularity and in active development. Do take a look on the dep's project 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.
Posted on January 16, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.