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.
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
go version go1.12.5 linux/amd64