diff options
author | cushon <cushon@google.com> | 2018-07-25 22:28:00 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-07-25 22:29:29 -0700 |
commit | 9b29a1bd7bbe37500b28a6508cb82ca1943c75b5 (patch) | |
tree | 45a017f07610438494c011b0df81554ca9481a48 /src/main/java/com/google/devtools/build/lib/rules/java | |
parent | ca2977c2504df02ca2c8f8b6b2db75c6dad759ef (diff) |
Add support for data dependencies to java_plugin and java_package_configuration
This allows loading data inputs to annotation processors and Error Prone plugins.
Previously the only supported way to do this was using Java resources, but in
the case of per-package configuration that ties any changes to the resources
to JavaBuilder's release process.
PiperOrigin-RevId: 206106802
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/java')
8 files changed, 75 insertions, 11 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java index 861ee0983a..7da5b33810 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java @@ -23,6 +23,7 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.AnalysisEnvironment; +import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.OutputGroupInfo; import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; @@ -427,11 +428,29 @@ public class JavaCommon { /** Returns the per-package configured javacopts. */ public static ImmutableList<String> computePerPackageJavacOpts( RuleContext ruleContext, JavaToolchainProvider toolchain) { + return computePerPackageConfiguration(ruleContext, toolchain) + .stream() + .flatMap(p -> p.javacopts().stream()) + .collect(toImmutableList()); + } + + /** Returns the per-package configured runfiles. */ + public static NestedSet<Artifact> computePerPackageData( + RuleContext ruleContext, JavaToolchainProvider toolchain) { + NestedSetBuilder<Artifact> data = NestedSetBuilder.naiveLinkOrder(); + computePerPackageConfiguration(ruleContext, toolchain) + .stream() + .map(p -> p.data()) + .forEach(data::addTransitive); + return data.build(); + } + + private static ImmutableList<JavaPackageConfigurationProvider> computePerPackageConfiguration( + RuleContext ruleContext, JavaToolchainProvider toolchain) { return toolchain .packageConfiguration() .stream() .filter(p -> p.matches(ruleContext.getLabel())) - .flatMap(p -> p.javacopts().stream()) .collect(toImmutableList()); } @@ -773,8 +792,13 @@ public class JavaCommon { NestedSet<String> processorClasses = NestedSetBuilder.wrap(Order.NAIVE_LINK_ORDER, getProcessorClasses(ruleContext)); NestedSet<Artifact> processorClasspath = getRuntimeClasspath(); + FileProvider dataProvider = ruleContext.getPrerequisite("data", Mode.HOST, FileProvider.class); + NestedSet<Artifact> data = + dataProvider != null + ? dataProvider.getFilesToBuild() + : NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); return JavaPluginInfoProvider.create( - JavaPluginInfo.create(processorClasses, processorClasspath), + JavaPluginInfo.create(processorClasses, processorClasspath, data), ruleContext.attributes().get("generates_api", Type.BOOLEAN)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java index db303aecf0..2c9364c394 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java @@ -230,6 +230,7 @@ public final class JavaCompilationHelper { builder.setTempDirectory(tempDir(classJar)); builder.setClassDirectory(classDir(classJar)); builder.setPlugins(attributes.plugins().plugins()); + builder.setExtraData(JavaCommon.computePerPackageData(ruleContext, javaToolchain)); builder.setStrictJavaDeps(attributes.getStrictJavaDeps()); builder.setFixDepsTool(getJavaConfiguration().getFixDepsTool()); builder.setDirectJars(attributes.getDirectJars()); @@ -405,6 +406,9 @@ public final class JavaCompilationHelper { // only run API-generating annotation processors during header compilation builder.setPlugins(attributes.plugins().apiGeneratingPlugins()); + // Exclude any per-package configured data (see JavaCommon.computePerPackageData). + // It is used to allow Error Prone checks to load additional data, + // and Error Prone doesn't run during header compilation. builder.setJavacOpts(getJavacOpts()); builder.setTempDirectory(tempDir(headerJar)); builder.setOutputJar(headerJar); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java index dc960d7b0d..a7158d306d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java @@ -457,6 +457,7 @@ public final class JavaCompileAction extends SpawnAction { private PathFragment tempDirectory; private PathFragment classDirectory; private JavaPluginInfo plugins = JavaPluginInfo.empty(); + private NestedSet<Artifact> extraData = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); private Label targetLabel; @Nullable private String injectingRuleKind; @@ -572,6 +573,8 @@ public final class JavaCompileAction extends SpawnAction { .addTransitive(classpathEntries) .addTransitive(compileTimeDependencyArtifacts) .addTransitive(plugins.processorClasspath()) + .addTransitive(plugins.data()) + .addTransitive(extraData) .addAll(sourceJars) .addAll(sourceFiles) .addAll(javabaseInputs) @@ -955,6 +958,12 @@ public final class JavaCompileAction extends SpawnAction { return this; } + public void setExtraData(NestedSet<Artifact> extraData) { + checkNotNull(extraData, "extraData must not be null"); + checkState(this.extraData.isEmpty()); + this.extraData = extraData; + } + public Builder setLangtoolsJar(Artifact langtoolsJar) { this.langtoolsJar = langtoolsJar; return this; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java index 5d7d66fd0e..61980483c7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java @@ -437,6 +437,7 @@ public class JavaHeaderCompileAction extends SpawnAction { .addTransitive(baseInputs) .addTransitive(classpathEntries) .addTransitive(plugins.processorClasspath()) + .addTransitive(plugins.data()) .addTransitive(compileTimeDependencyArtifacts); final CommandLines commandLines; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java index 3ea3935878..78964b9cc8 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java @@ -15,8 +15,10 @@ package com.google.devtools.build.lib.rules.java; import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.PackageSpecificationProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; @@ -24,6 +26,7 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.syntax.Type; @@ -39,11 +42,16 @@ public class JavaPackageConfiguration implements RuleConfiguredTargetFactory { ImmutableList.copyOf( ruleContext.getPrerequisites( "packages", Mode.HOST, PackageSpecificationProvider.class)); + FileProvider dataProvider = ruleContext.getPrerequisite("data", Mode.HOST, FileProvider.class); + NestedSet<Artifact> data = + dataProvider != null + ? dataProvider.getFilesToBuild() + : NestedSetBuilder.emptySet(Order.STABLE_ORDER); List<String> javacopts = ruleContext.attributes().get("javacopts", Type.STRING_LIST); return new RuleConfiguredTargetBuilder(ruleContext) .addProvider(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY)) .setFilesToBuild(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) - .addProvider(JavaPackageConfigurationProvider.create(packages, javacopts)) + .addProvider(JavaPackageConfigurationProvider.create(packages, javacopts, data)) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationProvider.java index beebd790a1..86e8883cd0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationProvider.java @@ -16,9 +16,11 @@ package com.google.devtools.build.lib.rules.java; import com.google.auto.value.AutoValue; import com.google.common.collect.Streams; +import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.PackageSpecificationProvider; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import java.util.List; @@ -32,8 +34,10 @@ public abstract class JavaPackageConfigurationProvider implements TransitiveInfo /** Creates a {@link JavaPackageConfigurationProvider}. */ @AutoCodec.Instantiator public static JavaPackageConfigurationProvider create( - List<PackageSpecificationProvider> packageSpecifications, List<String> javacopts) { - return new AutoValue_JavaPackageConfigurationProvider(packageSpecifications, javacopts); + List<PackageSpecificationProvider> packageSpecifications, + List<String> javacopts, + NestedSet<Artifact> data) { + return new AutoValue_JavaPackageConfigurationProvider(packageSpecifications, javacopts, data); } /** Package specifications for which the configuration should be applied. */ @@ -42,6 +46,8 @@ public abstract class JavaPackageConfigurationProvider implements TransitiveInfo /** The javacopts for this configuration. */ abstract List<String> javacopts(); + abstract NestedSet<Artifact> data(); + /** * Returns true if this configuration matches the current label: that is, if the label's package * is contained by any of the {@link #packageSpecifications}. diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationRule.java index 7f6bc8509f..b114ec9f31 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfigurationRule.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.java; import static com.google.devtools.build.lib.packages.Attribute.attr; +import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; import static com.google.devtools.build.lib.packages.BuildType.LICENSE; import com.google.common.collect.ImmutableList; @@ -23,9 +24,9 @@ import com.google.devtools.build.lib.analysis.PackageSpecificationProvider; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.config.HostTransition; -import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.syntax.Type; +import com.google.devtools.build.lib.util.FileTypeSet; /** Rule definition for {@code java_package_configuration} */ public class JavaPackageConfigurationRule implements RuleDefinition { @@ -38,7 +39,7 @@ public class JavaPackageConfigurationRule implements RuleDefinition { the configuration should be applied to. <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add( - attr("packages", BuildType.LABEL_LIST) + attr("packages", LABEL_LIST) .cfg(HostTransition.INSTANCE) .allowedFileTypes() .mandatoryNativeProviders(ImmutableList.of(PackageSpecificationProvider.class))) @@ -46,6 +47,10 @@ public class JavaPackageConfigurationRule implements RuleDefinition { Java compiler flags. <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add(attr("javacopts", Type.STRING_LIST)) + /* <!-- #BLAZE_RULE(java_package_configuration).ATTRIBUTE(data) --> + The list of files needed by this configuration at runtime. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("data", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE).dontCheckConstraints()) .add(attr("output_licenses", LICENSE)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java index 48241d4ccf..0d125f9a6e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java @@ -38,26 +38,31 @@ public abstract class JavaPluginInfoProvider implements TransitiveInfoProvider { public abstract static class JavaPluginInfo { public static JavaPluginInfo create( - NestedSet<String> processorClasses, NestedSet<Artifact> processorClasspath) { + NestedSet<String> processorClasses, + NestedSet<Artifact> processorClasspath, + NestedSet<Artifact> data) { return new AutoValue_JavaPluginInfoProvider_JavaPluginInfo( - processorClasses, processorClasspath); + processorClasses, processorClasspath, data); } @AutoCodec.Instantiator public static JavaPluginInfo empty() { return create( NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); } public static JavaPluginInfo merge(Iterable<JavaPluginInfo> plugins) { NestedSetBuilder<String> processorClasses = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder<Artifact> processorClasspath = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> data = NestedSetBuilder.naiveLinkOrder(); for (JavaPluginInfo plugin : plugins) { processorClasses.addTransitive(plugin.processorClasses()); processorClasspath.addTransitive(plugin.processorClasspath()); + data.addTransitive(plugin.data()); } - return create(processorClasses.build(), processorClasspath.build()); + return create(processorClasses.build(), processorClasspath.build(), data.build()); } /** @@ -69,8 +74,10 @@ public abstract class JavaPluginInfoProvider implements TransitiveInfoProvider { /** Returns the artifacts to add to the runtime classpath for this plugin. */ public abstract NestedSet<Artifact> processorClasspath(); + public abstract NestedSet<Artifact> data(); + public boolean isEmpty() { - return processorClasses().isEmpty() && processorClasspath().isEmpty(); + return processorClasses().isEmpty() && processorClasspath().isEmpty() && data().isEmpty(); } } |