The open source Pants build system adds experimental Golang support to Pants 2.8, in addition to already supporting Python, Shell, and Docker!
What is Pants?
Pants is a state-of-the-art software workflow system. It orchestrates the various tools you use during iterative development and CI—compilers, testing frameworks, linters, formatters, and packagers—installing, configuring, sequencing, and invoking them in just the right way to create the desired outputs.
Pants applies fine-grained invalidation, caching, and concurrency to speed up your builds and other workflows, and it uses static analysis to minimize the amount of metadata and other boilerplate required to achieve this.
Why Pants for Go?
Go's built-in tooling is already excellent! Many projects may be fine using only Go's tooling, although Pants offers some unique benefits:
- A consistent interface for all languages and tools in your repository.
- Integration with Git + advanced project management.
- Remote caching and execution.
- Unlike legacy build systems, these benefits all come with minimal boilerplate.
A consistent interface for all languages & tools in your repository
./pants fmt ::runs all formatters.
./pants lint ::runs all linters and formatters (in check-mode) in parallel.
./pants test ::runs all tests in parallel, regardless of language and test framework.
./pants check ::runs all compilation and type checkers like MyPy in parallel.
./pants package ::builds all binaries, e.g. Go binaries and Python wheels. (Also see Streamline your Docker builds with Pants)
❯ ./pants lint :: 16:28:34.37 [ERROR] Completed: Lint with gofmt - gofmt failed (exit code 1). The following Go files require formatting: testprojects/src/go/pants_test/bar/bar.go testprojects/src/go/pants_test/foo.go 16:28:36.70 [INFO] Completed: Lint with Shellcheck - Shellcheck succeeded. 16:28:42.69 [INFO] Completed: Lint with Black - Black succeeded. All done! ✨ 🍰 ✨ 747 files would be left unchanged. 16:28:53.63 [INFO] Completed: Lint with Flake8 - Flake8 succeeded. ✓ Black succeeded. ✓ Flake8 succeeded. ✓ Shellcheck succeeded. 𐄂 gofmt failed.
Integration with Git + advanced project introspection
Pants integrates with Git to allow you to, for example, only format and lint changed files:
./pants --changed-since=HEAD fmt ./pants --changed-since=upstream/main lint
Pants can combine this integration with Git with its advanced project introspection. For example, to only run tests that could have possibly been changed:
./pants --changed-since=HEAD --changed-dependees=transitive test
That is, Pants will only run tests when their package or any transitive dependency was changed.
You can also use Pants's project introspection to better understand your dependency graph, such as identifying which code will be impacted by updating a third-party dependency:
❯ ./pants dependees --transitive //:mod#github.com/google/uuid cmd/greeter_en cmd/greeter_es pkg/greeter pkg/uuid
Remote caching and execution
Like Go, Pants locally caches each step of your build so that once you compile a package or run a package's tests, for example, you don't need to run it again unless that package or any of its transitive dependencies have changed.
Remote caching allows you to share this same cache amongst your CI runs and amongst your local team so that you don't have to redo work that others on your team have already done—like running tests and downloading third-party dependencies.
Remote execution allows you to run your builds directly in the cloud with low-latency workers for extreme parallelism, such as running your entire test suite in total parallelism.
Unlike previous-generation build tools like Bazel, Pants 2's benefits come with minimal boilerplate.
To get set up, add just four lines to the
pants.toml config file:
[GLOBAL] backend_packages = ["pants.backend.experimental.go"] [golang] expected_version = "1.17"
./pants tailor to generate a couple of one-line
❯ ./pants tailor Created BUILD: - Added go_mod target root Created cmd/deploy/BUILD: - Added go_binary target bin Created cmd/runner/BUILD: - Added go_binary target bin # BUILD go_mod() # cmd/deploy/BUILD go_binary(name="bin")
In contrast, Bazel
BUILD files often have 30-100+ lines per-directory, requiring you to enumerate every import your package has and every package provided by your third-party modules.
With Bazel, whenever you change your code's imports or your third-party dependencies, you have to update your
BUILD files saved on-disk, usually by running a different tool called Gazelle.
Instead, with Pants, there is no need to update
BUILD files. Pants uses this initial setup to analyze dependencies on startup, based on your
require directives in
go.sum, and the import statements in first-party
.go files in your project.
Trying out Go support
We plan to make Pants's Go support more comprehensive in Pants 2.9, before the end of 2021. Some features we have planned:
- The embed directive / resources
- Finalizing the layout of target definitions in BUILD files
We would love your feedback on what features your project needs to build with Pants, along with any bug reports. For example, while these features are not yet currently on the roadmap, they can be bumped based on community input:
- Cgo files
- Non-Go file types, like
.sassembly files are already supported)
go.modprojects in the same repository
- Protobuf support