Support RunfilesGroupInfo - #368
Conversation
eb1d207 to
a0618f8
Compare
|
I discussed with @fmeum that it's possible to make this provider a lot more memory efficient. I'll also add a global flag to enable/disable the emition of this provider for memory conscious users. |
a0618f8 to
2b9068c
Compare
f989530 to
705d909
Compare
I will, but it's referencing a prerelease version of EDIT: done. Now pointing at |
Teach the Java rules to describe their runfiles as named, ordered groups
so that downstream packaging rules can build more efficient artifacts.
`java_binary`, `java_test`, `java_library`, and `java_import` now return
`RunfilesGroupInfo` from the `rules_runfiles_group` ruleset alongside
`DefaultInfo`. Instead of seeing a single flat runfiles tree, a packaging rule
(e.g. a container-image or archive rule) can split a binary's runfiles into
layers and order them so that the content that changes least often lands in the
most cacheable layers:
* the JDK / java_runtime at the foundation tier (never merged),
* `java_import` targets (typically third-party jars) at the shared-deps tier,
* `java_library` code, the binary's own jars, and the executable at the
executable tier, marked `first_party` only for targets in the main
repository -- plenty of Java code Bazel builds from source belongs to
somebody else.
Libraries propagate fine-grained per-target groups up through their dependents
as a depset of group entries, each carrying its own metadata, so what a target
retains does not grow with the size of its closure. The binary collects them,
adds its own groups, and tags every group it produces with the `rules_java`
merge affinity so that JVM-shaped groups stay together when a packager has to
merge groups to fit a layer limit. A dependency that returns `JavaInfo` but no
`RunfilesGroupInfo` -- a custom rule, or `rules_jvm_external`'s `jvm_import` --
gets a synthesized group covering its transitive runtime jars and its default
runfiles, so a packager never silently loses its files. `java_import` gains a
`runfiles_weight` attribute so dependency-management rulesets can hint at
relative sizes to guide those merge decisions.
Emission is off by default and gated on the ruleset-wide
`--@rules_runfiles_group//runfiles_group:enabled` flag, so a build that packages
nothing pays nothing for the providers. Consumers that don't understand
`RunfilesGroupInfo` are unaffected and keep using
`DefaultInfo.default_runfiles`.
Adds a dependency on `rules_runfiles_group` for both Bzlmod and WORKSPACE
setups.
705d909 to
1ad4ccc
Compare
|
Instead of making changes to various rules repos, have you considered achieving this with an aspect? ISTM this is the exactly kind of thing aspects were designed for. |
|
@hvadehra I have considered it, but I haven't found a good way to do this so far. Or to make this more concrete: In the implementation function of an aspect, I can inspect the If we figure out a way to do the same work efficiently in an Aspect, I'd be happy to do so. |
|
I could imagine having a with tests ensuring the rule implementations and the function stay in sync (at least in the ways we care about). |
|
@hvadehra I like your proposal. Let me rephrase it in my own words to ensure we are on the same page:
Can you confirm if I understand your idea correctly? If we agree on that, I can implement your proposal. |
Teach the Java rules to describe their runfiles as named, ordered groups so that downstream packaging rules can build more efficient artifacts.
java_binary,java_test,java_library, andjava_importnow returnRunfilesGroupInfo(andRunfilesGroupMetadataInfo) from therules_runfiles_groupruleset alongsideDefaultInfo. Instead of seeing a single flat runfiles tree, a packaging rule (e.g. a container-image or archive rule) can split a binary's runfiles into layers and order them so that the content that changes least often lands in the most cacheable layers:java_importtargets (typically third-party jars) at the shared-deps tier,java_librarycode, the binary's own jars, and the executable at the executable tier.Libraries propagate fine-grained per-target groups up through their dependents; the binary collects them, adds its own groups, and tags every group it produces with the
rules_javamerge affinity so that JVM-shaped groups stay together when a packager has to merge groups to fit a layer limit.java_importgains arunfiles_weightattribute so dependency-management rulesets can hint at relative sizes to guide those merge decisions.Consumers that don't understand
RunfilesGroupInfoare unaffected and keep usingDefaultInfo.default_runfiles.Adds a dependency on
rules_runfiles_groupfor both Bzlmod and WORKSPACE setups.Validation
I took the liberty to host a BCR mirror that has support enabled for rules_java and rules_img. I also created a demo repo to show the effect.
This shows two
java_binarytargets with overlapping dependencies. Both are packaged as container images.Without
RunfilesGroupInfo, the wholejava_binaryis stored as a single layer and there is no sharing (only the base image layer is shared):With
RunfilesGroupInfo, individual runfiles fromjava_librarytargets get their own layers and most of the content is shared across the container images: