Pants 2.11 adds Go Protobuf codegen, Pex lockfiles for Python, and parametrization
We're pleased to announce Pants 2.11.0, the latest release of Pantsbuild, the scalable and ergonomic build system.
To update, set pants_version = "2.11.0"
in your pants.toml
. See upgrade tips, including the update-build-files
goal to automate some of the upgrade.
Protobuf codegen for Golang
Pants now can generate Go from Protobuf!
For example, given:
syntax = "proto3";
package simple_example.v1;
option go_package = "github.com/pantsbuild/example-codegen/gen";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
}
Pants will detect whenever your first party code uses the package set by option go_package
, and then generate and compile the precise code for you using Protoc.
package examples
import "testing"
import "github.com/pantsbuild/example-codegen/gen"
func TestGenerateUuid(t *testing.T) {
person := gen.Person{
Name: "Thomas the Train",
Id: 1,
Email: "[email protected]",
}
if person.Name != "Thomas the Train" {
t.Fail()
}
}
There's no need to manually regenerate your code or check generated files into version control. Pants will ensure you are always using up-to-date files in your builds.
We are excited that this is our first instance of code generation for a compiled language. With this foundation, we are adding codegen for Scala and Java. (Pants already supports Thrift and Protobuf for Python.)
For instructions, see our docs.
Protobuf formatting and linting
Pants now integrates with the Buf Protobuf formatter and linter. This means that you can easily lint your Protobuf files in parallel to the rest of your languages, e.g.:
$ ./pants lint ::
✓ black succeeded.
✓ buf-format succeeded.
✓ buf-lint succeeded.
✓ flake8 succeeded.
✓ gofmt succeeded.
✓ google-java-format succeeded.
✓ isort succeeded.
✓ shellcheck succeeded.
✓ shfmt succeeded.
To use, add pants.backend.codegen.protobuf.lint.buf
to [GLOBAL].backend_packages
in pants.toml
.
Thank you to Pants's new Contributor Jonas Stendahl for adding this integration (only one day after it was released!)
Pex lockfiles
Pants 2.11 expands on the lockfile support added in 2.10 by allowing you to use to the new lockfile mechanism from the Pex tool, as an alternative to generating the lockfile with Poetry.
This change brings several improvements:
- Support for VCS (Git) requirements, with support for local file requirements coming soon.
- Support for private indexes, including pip's
--find-links
. - Faster lockfile installation. Before: Pants would install your entire lockfile, but then quickly extract out the specific third-party dependencies you need for a particular task like running
test
. That gave you fine-grained caching. Now: we directly install only the dependencies you need without having to first install the entire lockfile. That gives you fine-grained caching, and avoids installing irrelevant dependencies.
We appreciate feedback on how this new locking mechanism is working in your repository. It is plausible there are edge cases we are not yet accounting for, given how vast the Python packaging ecosystem is.
Stay tuned for a blog explaining why we made the decision to add first-class lockfile support to Pex.
Target parametrization
In Pants, a target is an addressable set of metadata describing some of your code.
python_tests(
name="tests",
timeout=120,
)
Sometimes, you may want conflicting metadata to describe the same entity. For example, to run the same Python tests with both Python 2 and Python 3.
Pants 2.11 add the parametrize
mechanism to make it more ergonomic to set conflicting metadata for the same entity:
shunit2_tests(
name="tests",
shell=parametrize("bash", "zsh", "ksh"),
)
Each parameter creates a uniquely identifiable target, so that you can, for example, run only one of the test variations. But you can also reference them all together. For example, ./pants test ::
will run every test in parallel.
This feature pairs particularly well with the multiple resolves (lockfiles) feature added in Pants 2.10. You can now more easily declare that some code should work with multiple lockfiles.
python_sources(
resolve=parametrize("web-app", "data-science"),
)
For more information, see our updated docs.
Dependency inference for assets/resources
Pants can now detect in some cases when your Python code depends on a resource file. For example:
# Uses: project/data/logo.svg
pkgutil.get_data(__name__, "data/logo.svg")
$ ./pants dependencies project/app.py
project/data/logo.svg
As explained in our blog on dependency inference, this granular dependency information unlocks benefits like fine-grained cache invalidation.
To try this out, set [python-infer].assets = true
in pants.toml
.
This dependency inference is not fully comprehensive and you may still need to manually declare some dependencies. You must also still manually declare resource
and file
targets. We are excited that with this foundation, we will continue to improve inference in future versions.
Performance improvements
The 2.11.0
release also includes several performance enhancements:
- Builds will capture 15x less tracing information by default (although the level can still be increased, which reduces memory usage and improves performance slightly.
- Filesystem operations used to prepare running processes require significantly less IO due to holding more state in memory-efficient data structures.
- MyPy and Pylint have reduced startup overhead.
- Finally (as mentioned above): PEX lockfiles significantly improve the performance of running tests locally after a lockfile has changed.
Collectively, some 2.11.x
testers observed a 30-40% speedup for warm (fully cached) of larger repositories due to the first two changes, and local test and lint runs were significantly improved by the latter two.
Other changes
python_distribution
has a new fieldlong_description_path
. When Pants generatessetup.py
for you, it can now read the description from a file likeREADME.md
../pants export
now includespip
when creating virtual environments, e.g. for IDE integrations.- Target generators like
python_sources
now only show with./pants dependencies
their dependencies on their generated targets, even if you set thedependencies
field explicitly. Those explicit dependencies are moved to the generated targets directly, as before. This better reflects how Pants target generators work and unlocks some necessary semantics forparametrize
. - Pants no longer defaults to your code working with Python 3.6 (
[python].interpreter_constraints
). - New
build_file_dir()
symbol in BUILD files.
See the full changelog for more changes, along with our plugin upgrade guide.
Try out one of our example repositories:
And let us know what you think in Slack!