Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

219 lines (157 sloc) 5 KB

Tools as dependencies

Go modules support tools (commands) as dependencies. For example, you might need to install a tool to help with code generation, or to lint/vet your code. See the wiki for more details and background.

This example shows you how to add tools dependencies to your Go module, specifically the code generator stringer.

The resulting code can be found at https://github.com/go-modules-by-example/tools.

Walk-through

Create a module:

$ mkdir -p /home/gopher/scratchpad/tools
$ cd /home/gopher/scratchpad/tools
$ git init -q
$ git remote add origin https://github.com/go-modules-by-example/tools
$ go mod init
go: creating new go.mod: module github.com/go-modules-by-example/tools

Set GOBIN (see go help environment) to define where tool dependencies will be installed:

$ export GOBIN=$PWD/bin
$ export PATH=$GOBIN:$PATH

Add stringer as a dependency by importing the package in a build constraint-ignored file. This file will never be compiled (nor will it compile, because we are importing a main package); it is used simply to record the dependency. The file and the build constraint names are not particularly important, but we choose tools for the sake of consistency:

$ cat tools.go
// +build tools

package tools

import (
	_ "golang.org/x/tools/cmd/stringer"
)

Install stringer:

$ go install golang.org/x/tools/cmd/stringer
go: finding golang.org/x/tools v0.0.0-20190511041617-99f201b6807e
go: downloading golang.org/x/tools v0.0.0-20190511041617-99f201b6807e
go: extracting golang.org/x/tools v0.0.0-20190511041617-99f201b6807e
go: finding golang.org/x/sync v0.0.0-20190423024810-112230192c58
go: finding golang.org/x/net v0.0.0-20190311183353-d8887717615a
go: finding golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
go: finding golang.org/x/text v0.3.0
go: finding golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a

Our module reflects the dependency:

$ go list -m all
github.com/go-modules-by-example/tools
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
golang.org/x/net v0.0.0-20190311183353-d8887717615a
golang.org/x/sync v0.0.0-20190423024810-112230192c58
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
golang.org/x/text v0.3.0
golang.org/x/tools v0.0.0-20190511041617-99f201b6807e

Verify stringer is available on our PATH:

$ which stringer
/home/gopher/scratchpad/tools/bin/stringer

Use stringer via a go:generate directive:

$ cat painkiller.go
package main

import "fmt"

//go:generate stringer -type=Pill

type Pill int

const (
	Placebo Pill = iota
	Aspirin
	Ibuprofen
	Paracetamol
	Acetaminophen = Paracetamol
)

func main() {
	fmt.Printf("For headaches, take %v\n", Ibuprofen)
}

go generate and run the result:

$ go generate
$ go run .
For headaches, take Ibuprofen

Commit and push the results:

$ cat <<EOD >.gitignore
/bin
EOD
$ git add -A
$ git commit -q -am 'Initial commit'
$ git push -q origin

Version details

go version go1.12.5 linux/amd64
You can’t perform that action at this time.