mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 20:55:44 +00:00
60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
"""Split a JVM binary's runtime classpath into first-party and third-party jar sets.
|
|
|
|
This exists so the Docker image can place rarely-changing third-party jars in a
|
|
lower OCI layer and frequently-changing first-party jars in a small top layer,
|
|
so most pushes only re-upload the small layer.
|
|
"""
|
|
|
|
load("@rules_java//java/common:java_info.bzl", "JavaInfo")
|
|
|
|
def _unique_name(jar):
|
|
# short_path is unique per jar and stable across commits (it depends only on
|
|
# the jar's own package/coordinate, not on unrelated targets), so the deps
|
|
# layer's tar entries stay byte-identical and its blob digest stays cached.
|
|
path = jar.short_path
|
|
if path.startswith("../"):
|
|
path = path[3:]
|
|
return path.replace("+", "_").replace("/", "_").replace("~", "_")
|
|
|
|
def _impl(ctx):
|
|
info = ctx.attr.binary[JavaInfo]
|
|
|
|
app = []
|
|
deps = []
|
|
seen = {}
|
|
for jar in sorted(info.transitive_runtime_jars.to_list(), key = lambda f: f.path):
|
|
workspace = jar.owner.workspace_name if jar.owner else ""
|
|
bucket = "app" if workspace == "" else "deps"
|
|
out_name = _unique_name(jar)
|
|
|
|
key = bucket + "/" + out_name
|
|
if key in seen:
|
|
fail("jar_split: duplicate output name %r for %s and %s" % (
|
|
key,
|
|
seen[key],
|
|
jar.path,
|
|
))
|
|
seen[key] = jar.path
|
|
|
|
link = ctx.actions.declare_file(ctx.label.name + "/" + key)
|
|
ctx.actions.symlink(output = link, target_file = jar)
|
|
(app if bucket == "app" else deps).append(link)
|
|
|
|
return [
|
|
DefaultInfo(files = depset(app + deps)),
|
|
OutputGroupInfo(app = depset(app), deps = depset(deps)),
|
|
]
|
|
|
|
jar_split = rule(
|
|
implementation = _impl,
|
|
doc = "Partitions a JVM binary's transitive runtime jars into 'app' " +
|
|
"(first-party, empty workspace) and 'deps' (third-party) output groups.",
|
|
attrs = {
|
|
"binary": attr.label(
|
|
mandatory = True,
|
|
providers = [[JavaInfo]],
|
|
doc = "A jvm binary/library target whose runtime classpath to split.",
|
|
),
|
|
},
|
|
)
|