Skip to content

Commit

Permalink
Add support for resources in javadoc jars and make variable substitut…
Browse files Browse the repository at this point in the history
…ion in javadoc arguments (bazel-contrib#1238)
  • Loading branch information
vinnybod authored Sep 9, 2024
1 parent 0a8dd11 commit 9f2291c
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 42 deletions.
5 changes: 5 additions & 0 deletions private/rules/java_export.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def java_export(
javadocopts = kwargs.pop("javadocopts", [])
doc_deps = kwargs.pop("doc_deps", [])
doc_url = kwargs.pop("doc_url", "")
doc_resources = kwargs.pop("doc_resources", [])
toolchains = kwargs.pop("toolchains", [])

# Construct the java_library we'll export from here.
Expand All @@ -112,6 +113,7 @@ def java_export(
classifier_artifacts = classifier_artifacts,
doc_deps = doc_deps,
doc_url = doc_url,
doc_resources = doc_resources,
toolchains = toolchains,
)

Expand All @@ -131,6 +133,7 @@ def maven_export(
*,
doc_deps = [],
doc_url = "",
doc_resources = [],
toolchains = None):
"""
All arguments are the same as java_export with the addition of:
Expand Down Expand Up @@ -189,6 +192,7 @@ def maven_export(
(if not using `tags = ["no-javadoc"]`)
doc_url: The URL at which the generated `javadoc` will be hosted (if not using
`tags = ["no-javadoc"]`).
doc_resources: Resources to be included in the javadoc jar.
visibility: The visibility of the target
kwargs: These are passed to [`java_library`](https://bazel.build/reference/be/java#java_library),
and so may contain any valid parameter for that rule.
Expand Down Expand Up @@ -257,6 +261,7 @@ def maven_export(
javadocopts = javadocopts,
doc_deps = doc_deps,
doc_url = doc_url,
doc_resources = doc_resources,
excluded_workspaces = excluded_workspaces.keys(),
additional_dependencies = additional_dependencies,
visibility = visibility,
Expand Down
16 changes: 16 additions & 0 deletions private/rules/javadoc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def generate_javadoc(
classpath,
javadocopts,
doc_deps,
doc_resources,
output,
element_list):
inputs = []
Expand All @@ -33,14 +34,22 @@ def generate_javadoc(
args.add("--element-list", element_list)
args.add_all(source_jars, before_each = "--in")
inputs.extend(source_jars)
args.add_all(ctx.files.doc_resources, before_each = "--resources")
inputs.extend(ctx.files.doc_resources)
args.add_all(classpath, before_each = "--cp")
transitive_inputs.append(classpath)

for dep in doc_deps:
dep_info = dep[_JavadocInfo]
args.add("-linkoffline")
args.add(dep_info.url)
args.add(dep_info.element_list.dirname)
inputs.append(dep_info.element_list)

javadocopts = [
ctx.expand_make_variables("javadocopts", opt, ctx.var)
for opt in javadocopts
]
args.add_all(javadocopts)

ctx.actions.run(
Expand Down Expand Up @@ -80,6 +89,7 @@ def _javadoc_impl(ctx):
classpath,
ctx.attr.javadocopts,
ctx.attr.doc_deps,
ctx.attr.doc_resources,
jar_file,
element_list,
)
Expand Down Expand Up @@ -137,6 +147,12 @@ javadoc = rule(
This information is only used by javadoc targets depending on this target.
""",
),
"doc_resources": attr.label_list(
doc = "Resources to include in the javadoc jar.",
allow_empty = True,
allow_files = True,
default = [],
),
"excluded_workspaces": attr.string_list(
doc = "A list of bazel workspace names to exclude from the generated jar",
allow_empty = True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class JavadocJarMaker {

public static void main(String[] args) throws IOException {
Set<Path> sourceJars = new HashSet<>();
Set<Path> resources = new HashSet<>();
Path out = null;
Path elementList = null;
Set<Path> classpath = new HashSet<>();
Expand Down Expand Up @@ -89,6 +90,11 @@ public static void main(String[] args) throws IOException {
elementList = Paths.get(next);
break;

case "--resources":
next = args[++i];
resources.add(Paths.get(next));
break;

default:
options.add(flag);
break;
Expand Down Expand Up @@ -173,6 +179,12 @@ public static void main(String[] args) throws IOException {

sources.forEach(obj -> options.add(obj.getName()));

for (Path resource : resources) {
Path target = outputTo.resolve(resource.getFileName());
Files.createDirectories(target.getParent());
Files.copy(resource, target);
}

Writer writer = new StringWriter();
DocumentationTool.DocumentationTask task =
tool.getTask(writer, fileManager, null, null, options, sources);
Expand Down
11 changes: 11 additions & 0 deletions tests/com/github/bazelbuild/rules_jvm_external/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,14 @@ java_test(
artifact("org.hamcrest:hamcrest"),
],
)

java_library(
name = "zip_utils",
testonly = 1,
srcs = ["ZipUtils.java"],
visibility = ["//:__subpackages__"],
deps = [
artifact("com.google.guava:guava"),
"//private/tools/java/com/github/bazelbuild/rules_jvm_external/zip",
],
)
52 changes: 52 additions & 0 deletions tests/com/github/bazelbuild/rules_jvm_external/ZipUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.github.bazelbuild.rules_jvm_external;

import com.github.bazelbuild.rules_jvm_external.zip.StableZipEntry;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import static java.nio.charset.StandardCharsets.UTF_8;

public class ZipUtils {
public static void createJar(Path outputTo, Map<String, String> pathToContents) throws IOException {
try (OutputStream os = Files.newOutputStream(outputTo);
ZipOutputStream zos = new ZipOutputStream(os)) {

for (Map.Entry<String, String> entry : pathToContents.entrySet()) {
ZipEntry ze = new StableZipEntry(entry.getKey());
zos.putNextEntry(ze);
if (!ze.isDirectory()) {
zos.write(entry.getValue().getBytes(UTF_8));
}
zos.closeEntry();
}
}
}

public static Map<String, String> readJar(Path jar) throws IOException {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();

try (InputStream is = Files.newInputStream(jar);
ZipInputStream zis = new ZipInputStream(is)) {

for (ZipEntry entry = zis.getNextEntry(); entry != null; entry = zis.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}

builder.put(entry.getName(), new String(ByteStreams.toByteArray(zis), UTF_8));
}
}

return builder.build();
}
}
2 changes: 1 addition & 1 deletion tests/com/github/bazelbuild/rules_jvm_external/jar/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ java_test(
deps = [
"//private/tools/java/com/github/bazelbuild/rules_jvm_external",
"//private/tools/java/com/github/bazelbuild/rules_jvm_external/jar:MergeJars",
"//private/tools/java/com/github/bazelbuild/rules_jvm_external/zip",
"//tests/com/github/bazelbuild/rules_jvm_external:zip_utils",
artifact("com.google.guava:guava"),
artifact(
"junit:junit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@

package com.github.bazelbuild.rules_jvm_external.jar;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.*;

import com.github.bazelbuild.rules_jvm_external.zip.StableZipEntry;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -37,9 +36,13 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static com.github.bazelbuild.rules_jvm_external.ZipUtils.createJar;
import static com.github.bazelbuild.rules_jvm_external.ZipUtils.readJar;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class MergeJarsTest {

Expand Down Expand Up @@ -683,39 +686,6 @@ public void mergedJarKeepsNonClassFilesFirstWinsStrategy() throws IOException {
assertEquals("log4j.rootLogger=ERROR,stdout", contents.get("log4j.properties"));
}

private void createJar(Path outputTo, Map<String, String> pathToContents) throws IOException {
try (OutputStream os = Files.newOutputStream(outputTo);
ZipOutputStream zos = new ZipOutputStream(os)) {

for (Map.Entry<String, String> entry : pathToContents.entrySet()) {
ZipEntry ze = new StableZipEntry(entry.getKey());
zos.putNextEntry(ze);
if (!ze.isDirectory()) {
zos.write(entry.getValue().getBytes(UTF_8));
}
zos.closeEntry();
}
}
}

private Map<String, String> readJar(Path jar) throws IOException {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();

try (InputStream is = Files.newInputStream(jar);
ZipInputStream zis = new ZipInputStream(is)) {

for (ZipEntry entry = zis.getNextEntry(); entry != null; entry = zis.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}

builder.put(entry.getName(), new String(ByteStreams.toByteArray(zis), UTF_8));
}
}

return builder.build();
}

private Map<String, Long> readJarTimeStamps(Path jar) throws IOException {
ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder();

Expand Down
17 changes: 17 additions & 0 deletions tests/com/github/bazelbuild/rules_jvm_external/javadoc/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
load("//:defs.bzl", "artifact")

java_test(
name = "ResourceTest",
srcs = ["ResourceTest.java"],
test_class = "com.github.bazelbuild.rules_jvm_external.javadoc.ResourceTest",
deps = [
"//private/tools/java/com/github/bazelbuild/rules_jvm_external",
"//private/tools/java/com/github/bazelbuild/rules_jvm_external/javadoc",
"//tests/com/github/bazelbuild/rules_jvm_external:zip_utils",
artifact(
"junit:junit",
repository_name = "regression_testing_coursier",
),
artifact("com.google.guava:guava"),
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.github.bazelbuild.rules_jvm_external.javadoc;

import com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;

import static com.github.bazelbuild.rules_jvm_external.ZipUtils.createJar;
import static com.github.bazelbuild.rules_jvm_external.ZipUtils.readJar;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;

public class ResourceTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void shouldIncludeResourceFiles() throws Exception {
Path inputJar = temp.newFile("in.jar").toPath();
Path outputJar = temp.newFile("out.jar").toPath();
Path elementList = temp.newFile("element-list").toPath();
// deleting the file since JavadocJarMaker fails on existing files, we just need to supply the path.
elementList.toFile().delete();

Path license = temp.newFile("LICENSE").toPath();
Files.write(license, List.of("Apache License 2.0"), UTF_8);

createJar(
inputJar,
ImmutableMap.of("com/example/Main.java", "public class Main { public static void main(String[] args) {} }")
);

JavadocJarMaker.main(new String[]{
"--resources",
license.toAbsolutePath().toString(),
"--in",
inputJar.toAbsolutePath().toString(),
"--out",
outputJar.toAbsolutePath().toString(),
"--element-list",
elementList.toAbsolutePath().toString()
});

Map<String, String> contents = readJar(outputJar);
assertEquals("Apache License 2.0".strip(), contents.get("LICENSE").strip());
}
}

0 comments on commit 9f2291c

Please sign in to comment.