| """ Definition of _java_single_jar. """ |
| |
| load("//java/common:java_common.bzl", "java_common") |
| load("//java/common:java_info.bzl", "JavaInfo") |
| |
| def _java_single_jar(ctx): |
| transitive_inputs = [] |
| for dep in ctx.attr.deps: |
| if JavaInfo in dep: |
| info = dep[JavaInfo] |
| transitive_inputs.append(info.transitive_runtime_jars) |
| if hasattr(info, "compilation_info"): |
| compilation_info = info.compilation_info |
| if hasattr(compilation_info, "runtime_classpath"): |
| transitive_inputs.append(compilation_info.runtime_classpath) |
| else: |
| files = [] |
| for f in dep[DefaultInfo].files.to_list(): |
| if not f.extension == "jar": |
| fail("unexpected file type in java_single_jar.deps: %s" % f.path) |
| files.append(f) |
| transitive_inputs.append(depset(files)) |
| inputs = depset(transitive = transitive_inputs) |
| |
| if hasattr(java_common, "JavaRuntimeClasspathInfo"): |
| deploy_env_jars = depset(transitive = [ |
| dep[java_common.JavaRuntimeClasspathInfo].runtime_classpath |
| for dep in ctx.attr.deploy_env |
| ]) |
| excluded_jars = {jar: None for jar in deploy_env_jars.to_list()} |
| if excluded_jars: |
| inputs = depset([jar for jar in inputs.to_list() if jar not in excluded_jars]) |
| |
| args = ctx.actions.args() |
| args.add_all("--sources", inputs) |
| args.use_param_file("@%s") |
| args.set_param_file_format("multiline") |
| args.add_all("--deploy_manifest_lines", ctx.attr.deploy_manifest_lines) |
| args.add("--output", ctx.outputs.jar) |
| args.add("--normalize") |
| |
| # 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) |
| |
| if ctx.attr.exclude_build_data: |
| args.add("--exclude_build_data") |
| if ctx.attr.multi_release: |
| args.add("--multi_release") |
| |
| ctx.actions.run( |
| inputs = inputs, |
| outputs = [ctx.outputs.jar], |
| arguments = [args], |
| progress_message = "Merging into %s" % ctx.outputs.jar.short_path, |
| mnemonic = "JavaSingleJar", |
| executable = ctx.executable._singlejar, |
| ) |
| |
| files = depset([ctx.outputs.jar]) |
| providers = [DefaultInfo( |
| files = files, |
| runfiles = ctx.runfiles(transitive_files = files), |
| )] |
| if hasattr(java_common, "JavaRuntimeClasspathInfo"): |
| providers.append(java_common.JavaRuntimeClasspathInfo(runtime_classpath = inputs)) |
| return providers |
| |
| java_single_jar = rule( |
| attrs = { |
| "deps": attr.label_list( |
| allow_files = True, |
| doc = """ |
| The Java targets (including java_import and java_library) to collect |
| transitive dependencies from. Runtime dependencies are collected via |
| deps, exports, and runtime_deps. Resources are also collected. |
| Native cc_library or java_wrap_cc dependencies are not.""", |
| ), |
| "deploy_manifest_lines": attr.string_list(doc = """ |
| A list of lines to add to the <code>META-INF/manifest.mf</code> file."""), |
| "deploy_env": attr.label_list( |
| providers = [java_common.JavaRuntimeClasspathInfo] if hasattr(java_common, "JavaRuntimeClasspathInfo") else [], |
| allow_files = False, |
| doc = """ |
| A list of `java_binary` or `java_single_jar` targets which represent |
| the deployment environment for this binary. |
| |
| Set this attribute when building a plugin which will be loaded by another |
| `java_binary`. |
| |
| `deploy_env` dependencies are excluded from the jar built by this rule.""", |
| ), |
| "compress": attr.string(default = "preserve", doc = """ |
| 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."""), |
| "exclude_build_data": attr.bool(default = True, doc = """ |
| Whether to omit the build-data.properties file generated |
| by default."""), |
| "multi_release": attr.bool(default = True, doc = """Whether to enable Multi-Release output jars."""), |
| "_singlejar": attr.label( |
| default = Label("//toolchains:singlejar"), |
| cfg = "exec", |
| allow_single_file = True, |
| executable = True, |
| ), |
| }, |
| outputs = { |
| "jar": "%{name}.jar", |
| }, |
| implementation = _java_single_jar, |
| doc = """ |
| Collects Java dependencies and jar files into a single jar |
| |
| `java_single_jar` collects Java dependencies and jar files into a single jar. |
| This is similar to java_binary with everything related to executables disabled, |
| and provides an alternative to the java_binary "deploy jar hack". |
| |
| ## Example |
| |
| ```skylark |
| load("//tools/build_defs/java_single_jar:java_single_jar.bzl", "java_single_jar") |
| |
| java_single_jar( |
| name = "my_single_jar", |
| deps = [ |
| "//java/com/google/foo", |
| "//java/com/google/bar", |
| ], |
| ) |
| ``` |
| |
| Outputs: |
| {name}.jar: A single jar containing all of the inputs. |
| """, |
| ) |