blob: 80c89b657a1d3af7cad6b27b119aef8bdc0cc119 [file] [log] [blame]
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Definition of java_single_jar. """
def _check_non_empty(value, name):
if not value:
fail("%s must be non-empty" % name)
def _java_single_jar(ctx):
_check_non_empty(ctx.attr.root_packages, "root_packages")
inputs = depset()
if ctx.attr.source_jar:
inputs = depset(transitive = [dep[JavaInfo].transitive_source_jars for dep in ctx.attr.deps])
else:
inputs = depset(transitive = [dep[JavaInfo].transitive_runtime_deps for dep in ctx.attr.deps])
args = ctx.actions.args()
args.add_all("--sources", inputs)
args.use_param_file(
"@%s",
use_always = True,
)
args.set_param_file_format("multiline")
args.add("--output", ctx.outputs.jar)
args.add("--normalize")
resource_files = depset(
transitive = [resource.files for resource in ctx.attr.resources],
).to_list()
args.add("--resources")
for resource_file in resource_files:
if not resource_file.path.startswith("src/main/resources"):
fail("resource %s must be stored in src/main/resources/" % resource_file.path)
relative_path = resource_file.path.replace("src/main/resources/", "")
# Map src/main/resources/a/b/c.txt to a/b/c.txt.
args.add(resource_file.path, format = "%s:" + relative_path)
# Maybe compress code.
if not ctx.attr.source_jar:
# Deal with limitation of singlejar flags: tool's default behavior is
# "no", but you get that behavior only by absence of compression flags.
if ctx.attr.compress == "preserve":
args.add("--dont_change_compression")
elif ctx.attr.compress == "yes":
args.add("--compression")
elif ctx.attr.compress == "no":
pass
else:
fail("\"compress\" attribute (%s) must be: yes, no, preserve." % ctx.attr.compress)
# Each package prefix has to be specified in its own --include_prefixes arg.
for p in ctx.attr.root_packages:
args.add("--include_prefixes", p.replace(".", "/"))
if ctx.attr.exclude_build_data:
args.add("--exclude_build_data")
args.add_all("--deploy_manifest_lines", ctx.attr.manifest_lines, format_each = "\"%s\"")
ctx.actions.run(
inputs = inputs.to_list() + resource_files,
outputs = [ctx.outputs.jar],
arguments = [args],
progress_message = "Merging into %s" % ctx.outputs.jar.short_path,
mnemonic = "JavaSingleJar",
executable = ctx.executable._singlejar,
)
java_single_jar = rule(
attrs = {
"deps": attr.label_list(providers = [JavaInfo]),
"resources": attr.label_list(
providers = [JavaInfo],
allow_files = True,
),
"_singlejar": attr.label(
default = Label("@bazel_tools//tools/jdk:singlejar"),
cfg = "host",
allow_single_file = True,
executable = True,
),
"source_jar": attr.bool(default = False),
"compress": attr.string(default = "preserve"),
"root_packages": attr.string_list(),
"exclude_build_data": attr.bool(default = True),
"manifest_lines": attr.string_list(),
},
outputs = {
"jar": "%{name}.jar",
},
implementation = _java_single_jar,
doc = """
Collects Java dependencies and jar files into a single jar
Args:
deps: The Java targets (including java_import and java_library) to collect
transitive dependencies from. Both compile-time dependencies (deps,
exports) and runtime dependencies (runtime_deps) are collected.
Resources are also collected. Native cc_library or java_wrap_cc
dependencies are not.
resources: A combination of resource files. Files must be stored in
src/main/resources. Mapping rules: src/main/resources/a/b/c.txt will be
copied to a/b/c.txt in the output jar.
compress: Whether to always deflate ("yes"), always store ("no"), or pass
through unmodified ("preserve"). The default is "preserve", and is the
most efficient option -- no extra work is done to inflate or deflate.
source_jar: Whether to combine only the source jars of input to create a single
output source jar. The compiled code jars of input will be ignored.
root_packages: Java packages to include in generated jar.
exclude_build_data: Whether to omit the build-data.properties file generated
by default.
manifest_lines: lines to put in the output manifest file (manifest
files in the input jars are ignored)
Outputs:
{name}.jar: A single jar containing all of the input.
""",
)