Go overview
Pants's support for Golang.
We are done implementing the initial core functionality for Pants's initial Go support (tracked here). However, there may be some edge cases we aren't yet handling. There are also some features that are not yet supported like vendoring, which we'd love your input on how to prioritize!
Please share feedback for what you need to use Pants with your Go project by either opening a GitHub issue or joining our Slack!
Go's builtin tooling is already excellent! Many projects may be fine only using Go's tooling, although Pants offers some unique benefits:
- A consistent interface for all languages/tools in your repository, such as being able to run
pants fmt lint check test package
. - Integration with Git, such as running
pants --changed-since=HEAD test
. - Caching, such as caching test results on a per-package basis.
- Remote execution and remote caching.
- Advanced project introspection, such as finding all code that transitively depends on a certain package.
Check out github.com/pantsbuild/example-golang to try out Pants's Go support.
Initial setup
First, activate the Go backend in pants.toml
:
[GLOBAL]
backend_packages = ["pants.backend.experimental.go"]
You may want to set the option [golang].minimum_expected_version
to a value like "1.17"
. Pants will use this to find a Go distribution that is the same version or newer. You still set your projects' Go version with go.mod
with the go
directive; this option is only used for Pants to discover a compatible Go distribution.
You can also set [golang].go_search_paths
to influence where Pants looks for Go, e.g. ["/usr/bin"]
. It defaults to your PATH
.
Then run pants tailor ::
to generate BUILD files. This will add a go_mod
target where you have your go.mod
file, a go_package
target for every directory with a .go
file, and a go_binary
target in every directory where you have package main
.
❯ pants tailor ::
Created BUILD:
- Add go_mod target root
Created cmd/deploy/BUILD:
- Add go_binary target bin
- Add go_package target deploy
Created cmd/runner/BUILD:
- Add go_binary target bin
- Add go_package target runner
Created pkg/deploy/BUILD:
- Add go_package target deploy
Created pkg/runner/BUILD:
- Add go_package target runner
Each go_package
target allows you to set metadata for that directory, such as the test_timeout
field. However, Pants uses sensible defaults so, usually, you can simply use what was generated by tailor
.
The go_mod
target generates a go_third_party_package
target for each package belonging to the modules declared in your go.mod
. You will rarely need to interact with these directly, thanks to dependency inference.
You can run pants list ::
to see all targets in your project, including generated go_third_party_package
targets:
❯ pants list
...
//:root#golang.org/x/net/ipv4
//:root#golang.org/x/net/ipv6
...
cmd/deploy:bin
cmd/deploy:deploy
cmd/runner:bin
cmd/runner:runner
pkg/deploy:deploy
pkg/runner:runner
go.mod
and go.sum
need to be up-to-datePants does not yet update your go.mod
and go.sum
for you; it only reads these files when downloading modules. Run go mod download all
to make sure these files are correct.
The embed
directive and resource
targets
To use the embed
directive, you must first teach Pants about the files with the resource
/ resources
targets:
- Add a
resource
orresources
target with the embedded files in thesource
/sources
field, respectively. - Add that target to the
dependencies
field of the relevantgo_package
target.
For example:
go_package(dependencies=[":embeds"])
resources(name="embeds", sources=["hello.txt"])
package runner
import _ "embed"
//go:embed hello.txt
var s string
print(s)
Hello world!
Package and run binaries
To run a binary, use pants run path/to/main_pkg:
(note the colon). You can pass through arguments with --
, like this:
❯ pants run cmd/deploy: -- --help
Usage of /Users/pantsbuild/example/.pants.d/tmpzfh33ggu/cmd.deploy/bin:
--allow-insecure-auth allow credentials to be passed unencrypted (i.e., no TLS)
-A, --auth-token-env string name of environment variable with auth bearer token
...
pflag: help requested
You can also package your binaries (aka go build
) by using pants package
. package ::
will build all your project's binaries, whereas package path/to/main_pkg:
will build only the binary in that directory.
❯ pants package ::
[INFO] Wrote dist/cmd.deploy/bin
[INFO] Wrote dist/cmd.runner/bin
By default, Pants names the binary with the scheme path.to.directory/target_name
, e.g. cmd.deploy/bin
. You can set the field output_path
to use a different name:
go_binary(name="bin", output_path="deploy")