xref: /aosp_15_r20/external/tink/java_src/tools/java_single_jar.bzl (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1# Copyright 2020 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15""" Definition of java_single_jar. """
16
17def _check_non_empty(value, name):
18    if not value:
19        fail("%s must be non-empty" % name)
20
21def _java_single_jar(ctx):
22    _check_non_empty(ctx.attr.root_packages, "root_packages")
23
24    inputs = depset()
25    if ctx.attr.source_jar:
26        inputs = depset(transitive = [dep[JavaInfo].transitive_source_jars for dep in ctx.attr.deps])
27    else:
28        inputs = depset(transitive = [dep[JavaInfo].transitive_runtime_jars for dep in ctx.attr.deps])
29
30    args = ctx.actions.args()
31    args.add_all("--sources", inputs)
32    args.use_param_file(
33        "@%s",
34        use_always = True,
35    )
36    args.set_param_file_format("multiline")
37    args.add("--output", ctx.outputs.jar)
38    args.add("--normalize")
39
40    resource_files = depset(
41        transitive = [resource.files for resource in ctx.attr.resources],
42    ).to_list()
43    args.add("--resources")
44    for resource_file in resource_files:
45        if not resource_file.path.startswith("src/main/resources"):
46            fail("resource %s must be stored in src/main/resources/" % resource_file.path)
47        relative_path = resource_file.path.replace("src/main/resources/", "")
48
49        # Map src/main/resources/a/b/c.txt to a/b/c.txt.
50        args.add(resource_file.path, format = "%s:" + relative_path)
51
52    # Maybe compress code.
53    if not ctx.attr.source_jar:
54        # Deal with limitation of singlejar flags: tool's default behavior is
55        # "no", but you get that behavior only by absence of compression flags.
56        if ctx.attr.compress == "preserve":
57            args.add("--dont_change_compression")
58        elif ctx.attr.compress == "yes":
59            args.add("--compression")
60        elif ctx.attr.compress == "no":
61            pass
62        else:
63            fail("\"compress\" attribute (%s) must be: yes, no, preserve." % ctx.attr.compress)
64
65    # Each package prefix has to be specified in its own --include_prefixes arg.
66    for p in ctx.attr.root_packages:
67        args.add("--include_prefixes", p.replace(".", "/"))
68
69    if ctx.attr.exclude_build_data:
70        args.add("--exclude_build_data")
71
72    args.add_all("--deploy_manifest_lines", ctx.attr.manifest_lines, format_each = "\"%s\"")
73
74    ctx.actions.run(
75        inputs = inputs.to_list() + resource_files,
76        outputs = [ctx.outputs.jar],
77        arguments = [args],
78        progress_message = "Merging into %s" % ctx.outputs.jar.short_path,
79        mnemonic = "JavaSingleJar",
80        executable = ctx.executable._singlejar,
81    )
82
83java_single_jar = rule(
84    attrs = {
85        "deps": attr.label_list(providers = [JavaInfo]),
86        "resources": attr.label_list(
87            providers = [JavaInfo],
88            allow_files = True,
89        ),
90        "_singlejar": attr.label(
91            default = Label("@bazel_tools//tools/jdk:singlejar"),
92            cfg = "exec",
93            allow_single_file = True,
94            executable = True,
95        ),
96        "source_jar": attr.bool(default = False),
97        "compress": attr.string(default = "preserve"),
98        "root_packages": attr.string_list(),
99        "exclude_build_data": attr.bool(default = True),
100        "manifest_lines": attr.string_list(),
101    },
102    outputs = {
103        "jar": "%{name}.jar",
104    },
105    implementation = _java_single_jar,
106    doc = """
107Collects Java dependencies and jar files into a single jar
108
109Args:
110  deps: The Java targets (including java_import and java_library) to collect
111      transitive dependencies from. Both compile-time dependencies (deps,
112      exports) and runtime dependencies (runtime_deps) are collected.
113      Resources are also collected. Native cc_library or java_wrap_cc
114      dependencies are not.
115  resources: A combination of resource files. Files must be stored in
116      src/main/resources. Mapping rules: src/main/resources/a/b/c.txt will be
117      copied to a/b/c.txt in the output jar.
118  compress: Whether to always deflate ("yes"), always store ("no"), or pass
119      through unmodified ("preserve"). The default is "preserve", and is the
120      most efficient option -- no extra work is done to inflate or deflate.
121  source_jar: Whether to combine only the source jars of input to create a single
122      output source jar. The compiled code jars of input will be ignored.
123  root_packages: Java packages to include in generated jar.
124  exclude_build_data: Whether to omit the build-data.properties file generated
125      by default.
126  manifest_lines: lines to put in the output manifest file (manifest
127      files in the input jars are ignored)
128
129Outputs:
130  {name}.jar: A single jar containing all of the input.
131""",
132)
133