diff --git a/changelog/@unreleased/pr-2137.v2.yml b/changelog/@unreleased/pr-2137.v2.yml new file mode 100644 index 000000000..e1c42db07 --- /dev/null +++ b/changelog/@unreleased/pr-2137.v2.yml @@ -0,0 +1,5 @@ +type: improvement +improvement: + description: Javadoc tasks supporty BaselineModuleJvmArgs + links: + - https://github.com/palantir/gradle-baseline/pull/2137 diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java index c728c6079..f2648cbed 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java @@ -40,7 +40,10 @@ import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.compile.JavaCompile; +import org.gradle.api.tasks.javadoc.Javadoc; import org.gradle.api.tasks.testing.Test; +import org.gradle.external.javadoc.CoreJavadocOptions; +import org.gradle.external.javadoc.MinimalJavadocOptions; import org.gradle.jvm.tasks.Jar; import org.gradle.process.CommandLineArgumentProvider; import org.immutables.value.Value; @@ -61,6 +64,7 @@ public final class BaselineModuleJvmArgs implements Plugin { Splitter.on(' ').trimResults().omitEmptyStrings(); @Override + @SuppressWarnings("checkstyle:MethodLength") public void apply(Project project) { project.getPluginManager().withPlugin("java", unused -> { BaselineModuleJvmArgsExtension extension = @@ -92,6 +96,62 @@ public Iterable asArguments() { return arguments; } }); + + Task maybeJavadocTask = project.getTasks().findByName(sourceSet.getJavadocTaskName()); + if (maybeJavadocTask instanceof Javadoc) { + maybeJavadocTask.doFirst(new Action() { + @Override + public void execute(Task task) { + Javadoc javadoc = (Javadoc) task; + + MinimalJavadocOptions options = javadoc.getOptions(); + if (options instanceof CoreJavadocOptions) { + CoreJavadocOptions coreOptions = (CoreJavadocOptions) options; + ImmutableList info = collectClasspathInfo(project, sourceSet); + List exportValues = Stream.concat( + extension.exports().get().stream(), + info.stream().flatMap(item -> item.exports().stream())) + .distinct() + .sorted() + .map(item -> item + "=ALL-UNNAMED") + .collect(ImmutableList.toImmutableList()); + List opens = Stream.concat( + extension.opens().get().stream(), + info.stream().flatMap(item -> item.opens().stream())) + .distinct() + .sorted() + .map(item -> item + "=ALL-UNNAMED") + .collect(ImmutableList.toImmutableList()); + project.getLogger() + .debug( + "BaselineModuleJvmArgs building {} on {} " + + "with exports: {} and opens: {}", + javadoc.getName(), + project, + exportValues, + opens); + if (!exportValues.isEmpty()) { + coreOptions + // options are automatically prefixed with '-' internally + .addMultilineStringsOption("-add-exports") + .setValue(exportValues); + } + if (!opens.isEmpty()) { + coreOptions + // options are automatically prefixed with '-' internally + .addMultilineStringsOption("-add-opens") + .setValue(opens); + } + } else { + project.getLogger() + .error( + "MinimalJavadocOptions implementation was " + + "not CoreJavadocOptions, rather '{}'", + options.getClass().getName()); + } + } + }); + } }); project.getTasks().withType(Test.class, new Action() { @@ -192,7 +252,29 @@ private static ImmutableList collectAnnotationProcessorArgs( private static ImmutableList collectClasspathArgs( Project project, BaselineModuleJvmArgsExtension extension, FileCollection classpath) { - ImmutableList classpathInfo = classpath.getFiles().stream() + ImmutableList classpathInfo = collectClasspathInfo(project, classpath); + Stream exports = Stream.concat( + extension.exports().get().stream(), + classpathInfo.stream().flatMap(info -> info.exports().stream())) + .distinct() + .sorted() + .flatMap(BaselineModuleJvmArgs::addExportArg); + Stream opens = Stream.concat( + extension.opens().get().stream(), classpathInfo.stream().flatMap(info -> info.opens().stream())) + .distinct() + .sorted() + .flatMap(BaselineModuleJvmArgs::addOpensArg); + return Stream.concat(exports, opens).collect(ImmutableList.toImmutableList()); + } + + private static ImmutableList collectClasspathInfo(Project project, SourceSet sourceSet) { + return collectClasspathInfo( + project, project.getConfigurations().getByName(sourceSet.getAnnotationProcessorConfigurationName())); + } + + private static ImmutableList collectClasspathInfo( + Project project, FileCollection classpath) { + return classpath.getFiles().stream() .map(file -> { try { if (file.getName().endsWith(".jar") && file.isFile()) { @@ -212,18 +294,6 @@ private static ImmutableList collectClasspathArgs( }) .filter(Objects::nonNull) .collect(ImmutableList.toImmutableList()); - Stream exports = Stream.concat( - extension.exports().get().stream(), - classpathInfo.stream().flatMap(info -> info.exports().stream())) - .distinct() - .sorted() - .flatMap(BaselineModuleJvmArgs::addExportArg); - Stream opens = Stream.concat( - extension.opens().get().stream(), classpathInfo.stream().flatMap(info -> info.opens().stream())) - .distinct() - .sorted() - .flatMap(BaselineModuleJvmArgs::addOpensArg); - return Stream.concat(exports, opens).collect(ImmutableList.toImmutableList()); } private static Optional parseModuleInfo(@Nullable java.util.jar.Manifest jarManifest) { diff --git a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy index 9b577be62..283548700 100644 --- a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy +++ b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy @@ -75,6 +75,33 @@ class BaselineModuleJvmArgsIntegrationTest extends IntegrationSpec { runTasksSuccessfully('compileJava') } + def 'Builds javadoc with locally defined exports'() { + when: + buildFile << ''' + application { + mainClass = 'com.Example' + } + moduleJvmArgs { + exports = ['jdk.compiler/com.sun.tools.javac.code'] + } + '''.stripIndent(true) + writeJavaSourceFile(''' + package com; + public class Example { + /** + * Javadoc {@link com.sun.tools.javac.code.Symbol}. + * @param args Program arguments + */ + public static void main(String[] args) { + com.sun.tools.javac.code.Symbol.class.toString(); + } + } + '''.stripIndent(true)) + + then: + runTasksSuccessfully('javadoc') + } + def 'Runs with locally defined exports'() { when: buildFile << '''