blob: 5ec8324e8428beab97343d3a52ac18dfa8ccec56 [file] [log] [blame]
// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.rules.java;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.ArtifactRoot.RootType;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
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.packages.Info;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.StructProvider;
import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
import com.google.devtools.build.lib.rules.java.JavaPluginInfo.JavaPluginData;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.JavaOutput;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.Path;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.Map;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests JavaInfo API for Starlark. */
@RunWith(JUnit4.class)
public class JavaInfoStarlarkApiTest extends BuildViewTestCase {
@Test
public void buildHelperCreateJavaInfoWithOutputJarOnly() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar']",
")");
assertNoEvents();
JavaCompilationArgsProvider javaCompilationArgsProvider =
fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
}
@Test
public void buildHelperCreateJavaInfoWithOutputJarAndUseIJar() throws Exception {
ruleBuilder().withIJar().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar']",
")");
assertNoEvents();
JavaCompilationArgsProvider javaCompilationArgsProvider =
fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib-ijar.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib-ijar.jar");
}
@Test
public void buildHelperCreateJavaInfoJavaRuleOutputJarsProviderSourceJarOutputJarAndUseIJar()
throws Exception {
ruleBuilder().withIJar().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
")");
assertNoEvents();
JavaRuleOutputJarsProvider javaRuleOutputJarsProvider =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllSrcOutputJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllClassOutputJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(javaRuleOutputJarsProvider.getJavaOutputs()).hasSize(1);
JavaOutput javaOutput = javaRuleOutputJarsProvider.getJavaOutputs().get(0);
assertThat(javaOutput.getCompileJar().prettyPrint())
.isEqualTo("foo/my_starlark_rule_lib-ijar.jar");
}
@Test
public void buildHelperCreateJavaInfoWithDeps() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaCompilationArgsProvider javaCompilationArgsProvider =
fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct-hjar.jar");
}
@Test
public void buildHelperCreateJavaInfoWithRunTimeDeps() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep_runtime = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaCompilationArgsProvider javaCompilationArgsProvider =
fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
}
/** Tests that JavaInfo can be constructed with CC native libraries as dependencies. */
@Test
public void javaInfo_setNativeLibraries() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"cc_library(name = 'my_cc_lib_direct', srcs = ['cc/a.cc'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" cc_dep = [':my_cc_lib_direct']",
")");
assertNoEvents();
JavaInfo javaInfoProvider = fetchJavaInfo();
NestedSet<LibraryToLink> librariesForTopTarget =
javaInfoProvider.getTransitiveNativeLibraries();
assertThat(librariesForTopTarget.toList().stream().map(LibraryToLink::getLibraryIdentifier))
.contains("foo/libmy_cc_lib_direct");
}
@Test
public void buildHelperCreateJavaInfoWithDepsAndNeverLink() throws Exception {
ruleBuilder().withNeverLink().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaCompilationArgsProvider javaCompilationArgsProvider =
fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars())).isEmpty();
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct-hjar.jar");
}
@Test
public void buildHelperCreateJavaInfoSourceJarsProviderWithSourceJars() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar']",
")");
assertNoEvents();
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
}
@Test
public void buildHelperPackSources_repackSingleJar() throws Exception {
ruleBuilder().withSourceFiles().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar']",
")");
assertNoEvents();
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
}
@Test
public void buildHelperCreateJavaInfoWithSourcesFiles() throws Exception {
ruleBuilder().withSourceFiles().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" sources = ['ClassA.java', 'ClassB.java', 'ClassC.java', 'ClassD.java'],",
")");
assertNoEvents();
JavaRuleOutputJarsProvider javaRuleOutputJarsProvider =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllSrcOutputJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
}
@Test
public void buildHelperCreateJavaInfoWithSourcesFilesAndSourcesJars() throws Exception {
ruleBuilder().withSourceFiles().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" sources = ['ClassA.java', 'ClassB.java', 'ClassC.java', 'ClassD.java'],",
" source_jars = ['my_starlark_rule_src-A.jar']",
")");
assertNoEvents();
JavaRuleOutputJarsProvider javaRuleOutputJarsProvider =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllSrcOutputJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly("foo/my_starlark_rule_lib-src.jar");
}
@Test
public void buildHelperCreateJavaInfoSourceJarsProviderWithDeps() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar", "foo/libmy_java_lib_direct-src.jar");
}
@Test
public void buildHelperCreateJavaInfoJavaSourceJarsProviderAndRuntimeDeps() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep_runtime = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar", "foo/libmy_java_lib_direct-src.jar");
}
@Test
public void buildHelperCreateJavaInfoJavaSourceJarsProviderAndTransitiveDeps() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_transitive', srcs = ['java/B.java'])",
"java_library(name = 'my_java_lib_direct',",
" srcs = ['java/A.java'],",
" deps = [':my_java_lib_transitive'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly(
"foo/my_starlark_rule_src.jar",
"foo/libmy_java_lib_direct-src.jar",
"foo/libmy_java_lib_transitive-src.jar");
}
@Test
public void buildHelperCreateJavaInfoJavaSourceJarsProviderAndTransitiveRuntimeDeps()
throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_transitive', srcs = ['java/B.java'])",
"java_library(name = 'my_java_lib_direct',",
" srcs = ['java/A.java'],",
" deps = [':my_java_lib_transitive'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct']",
")");
assertNoEvents();
JavaSourceJarsProvider sourceJarsProvider =
fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);
assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
.containsExactly(
"foo/my_starlark_rule_src.jar",
"foo/libmy_java_lib_direct-src.jar",
"foo/libmy_java_lib_transitive-src.jar");
}
/** Test exports adds dependencies to JavaCompilationArgsProvider. */
@Test
public void buildHelperCreateJavaInfoExportProviderExportsDepsAdded() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_exports', srcs = ['java/A.java'])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" dep_exports = [':my_java_lib_exports']",
")");
assertNoEvents();
JavaInfo javaInfo = fetchJavaInfo();
JavaSourceJarsProvider javaSourceJarsProvider =
javaInfo.getProvider(JavaSourceJarsProvider.class);
assertThat(javaSourceJarsProvider.getSourceJars()).isEmpty();
JavaCompilationArgsProvider javaCompilationArgsProvider =
javaInfo.getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports-hjar.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports-hjar.jar");
}
/** Test exports adds itself and recursive dependencies to JavaCompilationArgsProvider. */
@Test
public void buildHelperCreateJavaInfoExportProvider() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_c', srcs = ['java/C.java'])",
"java_library(name = 'my_java_lib_b', srcs = ['java/B.java'])",
"java_library(name = 'my_java_lib_a', srcs = ['java/A.java'],",
" deps = [':my_java_lib_b', ':my_java_lib_c'],",
" exports = [':my_java_lib_b']",
" )",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" dep_exports = [':my_java_lib_a']",
")");
assertNoEvents();
JavaInfo javaInfo = fetchJavaInfo();
JavaCompilationArgsProvider javaCompilationArgsProvider =
javaInfo.getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar",
"foo/libmy_java_lib_a-hjar.jar",
"foo/libmy_java_lib_b-hjar.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_a.jar", "foo/libmy_java_lib_b.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar",
"foo/libmy_java_lib_a.jar",
"foo/libmy_java_lib_b.jar",
"foo/libmy_java_lib_c.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar",
"foo/libmy_java_lib_a-hjar.jar",
"foo/libmy_java_lib_b-hjar.jar",
"foo/libmy_java_lib_c-hjar.jar");
}
/**
* Tests case: my_lib // \ a c // \\ b d
*
* <p>where single line is normal dependency and double is exports dependency.
*/
@Test
public void buildHelperCreateJavaInfoExportProvider001() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_b', srcs = ['java/B.java'])",
"java_library(name = 'my_java_lib_a', srcs = ['java/A.java'],",
" deps = [':my_java_lib_b'],",
" exports = [':my_java_lib_b']",
" )",
"java_library(name = 'my_java_lib_d', srcs = ['java/D.java'])",
"java_library(name = 'my_java_lib_c', srcs = ['java/C.java'],",
" deps = [':my_java_lib_d'],",
" exports = [':my_java_lib_d']",
" )",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" dep = [':my_java_lib_a', ':my_java_lib_c'],",
" dep_exports = [':my_java_lib_a']",
")");
assertNoEvents();
JavaInfo javaInfo = fetchJavaInfo();
JavaCompilationArgsProvider javaCompilationArgsProvider =
javaInfo.getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar",
"foo/libmy_java_lib_a-hjar.jar",
"foo/libmy_java_lib_b-hjar.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_a.jar", "foo/libmy_java_lib_b.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar",
"foo/libmy_java_lib_a.jar",
"foo/libmy_java_lib_b.jar",
"foo/libmy_java_lib_c.jar",
"foo/libmy_java_lib_d.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly(
"foo/my_starlark_rule_lib.jar",
"foo/libmy_java_lib_a-hjar.jar",
"foo/libmy_java_lib_b-hjar.jar",
"foo/libmy_java_lib_c-hjar.jar",
"foo/libmy_java_lib_d-hjar.jar");
}
@Test
public void buildHelperCreateJavaInfoPluginsFromExports() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'plugin_dep',",
" srcs = [ 'ProcessorDep.java'])",
"java_plugin(name = 'plugin',",
" srcs = ['AnnotationProcessor.java'],",
" processor_class = 'com.google.process.stuff',",
" deps = [ ':plugin_dep' ])",
"java_library(",
" name = 'export',",
" exported_plugins = [ ':plugin'],",
")",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" dep_exports = [':export']",
")");
assertNoEvents();
assertThat(fetchJavaInfo().getJavaPluginInfo().plugins().processorClasses().toList())
.containsExactly("com.google.process.stuff");
}
@Test
public void buildHelperCreateJavaInfoWithPlugins() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'plugin_dep',",
" srcs = [ 'ProcessorDep.java'])",
"java_plugin(name = 'plugin',",
" srcs = ['AnnotationProcessor.java'],",
" processor_class = 'com.google.process.stuff',",
" deps = [ ':plugin_dep' ])",
"my_rule(name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" dep_exported_plugins = [':plugin']",
")");
assertNoEvents();
assertThat(fetchJavaInfo().getJavaPluginInfo().plugins().processorClasses().toList())
.containsExactly("com.google.process.stuff");
}
@Test
public void buildHelperCreateJavaInfoWithOutputJarAndStampJar() throws Exception {
ruleBuilder().withStampJar().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar']",
")");
assertNoEvents();
JavaCompilationArgsProvider javaCompilationArgsProvider =
fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib-stamped.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
.containsExactly("foo/my_starlark_rule_lib-stamped.jar");
}
@Test
public void buildHelperCreateJavaInfoWithJdeps_javaRuleOutputJarsProvider() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct'],",
" jdeps = 'my_jdeps.pb',",
")");
assertNoEvents();
JavaRuleOutputJarsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(prettyArtifactNames(ruleOutputs.getAllClassOutputJars()))
.containsExactly("foo/my_starlark_rule_lib.jar");
assertThat(prettyArtifactNames(ruleOutputs.getAllSrcOutputJars()))
.containsExactly("foo/my_starlark_rule_src.jar");
assertThat(
prettyArtifactNames(
ruleOutputs.getJavaOutputs().stream()
.map(JavaOutput::getJdeps)
.collect(toImmutableList())))
.containsExactly("foo/my_jdeps.pb");
}
@Test
public void buildHelperCreateJavaInfoWithGeneratedJars_javaRuleOutputJarsProvider()
throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct'],",
" generated_class_jar = 'generated_class.jar',",
" generated_source_jar = 'generated_srcs.jar',",
")");
assertNoEvents();
JavaRuleOutputJarsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(
prettyArtifactNames(
ruleOutputs.getJavaOutputs().stream()
.map(JavaOutput::getGeneratedClassJar)
.collect(toImmutableList())))
.containsExactly("foo/generated_class.jar");
assertThat(
prettyArtifactNames(
ruleOutputs.getJavaOutputs().stream()
.map(JavaOutput::getGeneratedSourceJar)
.collect(toImmutableList())))
.containsExactly("foo/generated_srcs.jar");
}
@Test
public void buildHelperCreateJavaInfoWithGeneratedJars_javaGenJarsProvider() throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct'],",
" generated_class_jar = 'generated_class.jar',",
" generated_source_jar = 'generated_srcs.jar',",
")");
assertNoEvents();
JavaGenJarsProvider ruleOutputs = fetchJavaInfo().getProvider(JavaGenJarsProvider.class);
assertThat(ruleOutputs.getGenClassJar().prettyPrint()).isEqualTo("foo/generated_class.jar");
assertThat(ruleOutputs.getGenSourceJar().prettyPrint()).isEqualTo("foo/generated_srcs.jar");
}
@Test
public void buildHelperCreateJavaInfoWithCompileJdeps_javaRuleOutputJarsProvider()
throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct'],",
" compile_jdeps = 'compile.deps',",
")");
assertNoEvents();
JavaRuleOutputJarsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(
prettyArtifactNames(
ruleOutputs.getJavaOutputs().stream()
.map(JavaOutput::getCompileJdeps)
.collect(toImmutableList())))
.containsExactly("foo/compile.deps");
}
@Test
public void buildHelperCreateJavaInfoWithNativeHeaders_javaRuleOutputJarsProvider()
throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct'],",
" native_headers_jar = 'nativeheaders.jar',",
")");
assertNoEvents();
JavaRuleOutputJarsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(
prettyArtifactNames(
ruleOutputs.getJavaOutputs().stream()
.map(JavaOutput::getNativeHeadersJar)
.collect(toImmutableList())))
.containsExactly("foo/nativeheaders.jar");
}
@Test
public void buildHelperCreateJavaInfoWithManifestProto_javaRuleOutputJarsProvider()
throws Exception {
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
"my_rule(",
" name = 'my_starlark_rule',",
" output_jar = 'my_starlark_rule_lib.jar',",
" source_jars = ['my_starlark_rule_src.jar'],",
" dep = [':my_java_lib_direct'],",
" manifest_proto = 'manifest.proto',",
")");
assertNoEvents();
JavaRuleOutputJarsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);
assertThat(
prettyArtifactNames(
ruleOutputs.getJavaOutputs().stream()
.map(JavaOutput::getManifestProto)
.collect(toImmutableList())))
.containsExactly("foo/manifest.proto");
}
@Test
public void buildHelperCreateJavaInfoWithModuleFlags() throws Exception {
setBuildLanguageOptions("--noincompatible_java_info_merge_runtime_module_flags");
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(",
" name = 'my_java_lib_direct',",
" srcs = ['java/A.java'],",
" add_exports = ['java.base/java.lang'],",
" add_opens = ['java.base/java.lang'],",
")",
"java_library(",
" name = 'my_java_lib_runtime',",
" srcs = ['java/A.java'],",
" add_opens = ['java.base/java.util'],",
")",
"java_library(",
" name = 'my_java_lib_exports',",
" srcs = ['java/A.java'],",
" add_opens = ['java.base/java.math'],",
")",
"my_rule(",
" name = 'my_starlark_rule',",
" dep = [':my_java_lib_direct'],",
" dep_runtime = [':my_java_lib_runtime'],",
" dep_exports = [':my_java_lib_exports'],",
" output_jar = 'my_starlark_rule_lib.jar',",
" add_exports = ['java.base/java.lang.invoke'],",
")");
assertNoEvents();
JavaModuleFlagsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaModuleFlagsProvider.class);
if (analysisMock.isThisBazel()) {
assertThat(ruleOutputs.toFlags())
.containsExactly(
"--add-exports=java.base/java.lang=ALL-UNNAMED",
"--add-exports=java.base/java.lang.invoke=ALL-UNNAMED",
// NB: no java.base/java.util as the JavaInfo constructor doesn't
// look at runtime_deps for module flags.
"--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.math=ALL-UNNAMED")
.inOrder();
} else {
// add_exports/add_opens ignored in JavaInfo constructor in #newJavaInfo below
assertThat(ruleOutputs.toFlags())
.containsExactly(
"--add-exports=java.base/java.lang=ALL-UNNAMED",
// NB: no java.base/java.util as the JavaInfo constructor doesn't
// look at runtime_deps for module flags.
"--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.math=ALL-UNNAMED")
.inOrder();
}
}
@Test
public void buildHelperCreateJavaInfoWithModuleFlagsIncompatibleMergeRuntime() throws Exception {
setBuildLanguageOptions("--incompatible_java_info_merge_runtime_module_flags");
ruleBuilder().build();
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(",
" name = 'my_java_lib_direct',",
" srcs = ['java/A.java'],",
" add_exports = ['java.base/java.lang'],",
" add_opens = ['java.base/java.lang'],",
")",
"java_library(",
" name = 'my_java_lib_runtime',",
" srcs = ['java/A.java'],",
" add_opens = ['java.base/java.util'],",
")",
"java_library(",
" name = 'my_java_lib_exports',",
" srcs = ['java/A.java'],",
" add_opens = ['java.base/java.math'],",
")",
"my_rule(",
" name = 'my_starlark_rule',",
" dep = [':my_java_lib_direct'],",
" dep_runtime = [':my_java_lib_runtime'],",
" dep_exports = [':my_java_lib_exports'],",
" output_jar = 'my_starlark_rule_lib.jar',",
" add_exports = ['java.base/java.lang.invoke'],",
")");
assertNoEvents();
JavaModuleFlagsProvider ruleOutputs =
fetchJavaInfo().getProvider(JavaModuleFlagsProvider.class);
if (analysisMock.isThisBazel()) {
assertThat(ruleOutputs.toFlags())
.containsExactly(
"--add-exports=java.base/java.lang=ALL-UNNAMED",
"--add-exports=java.base/java.lang.invoke=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED",
"--add-opens=java.base/java.math=ALL-UNNAMED",
"--add-opens=java.base/java.lang=ALL-UNNAMED")
.inOrder();
} else {
// add_exports/add_opens ignored in JavaInfo constructor in #newJavaInfo below
assertThat(ruleOutputs.toFlags())
.containsExactly(
"--add-exports=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED",
"--add-opens=java.base/java.math=ALL-UNNAMED",
"--add-opens=java.base/java.lang=ALL-UNNAMED")
.inOrder();
}
}
@Test
public void starlarkJavaOutputsCanBeAddedToJavaPluginInfo() throws Exception {
Artifact classJar = createArtifact("foo.jar");
StarlarkInfo starlarkJavaOutput =
makeStruct(ImmutableMap.of("source_jars", Starlark.NONE, "class_jar", classJar));
StarlarkInfo starlarkPluginInfo =
makeStruct(
ImmutableMap.of(
"java_outputs", StarlarkList.immutableOf(starlarkJavaOutput),
"plugins", JavaPluginData.empty(),
"api_generating_plugins", JavaPluginData.empty()));
JavaPluginInfo pluginInfo = JavaPluginInfo.PROVIDER.wrap(starlarkPluginInfo);
assertThat(pluginInfo).isNotNull();
assertThat(pluginInfo.getJavaOutputs()).hasSize(1);
assertThat(pluginInfo.getJavaOutputs().get(0).getClassJar()).isEqualTo(classJar);
}
@Test
public void javaOutputSourceJarsReturnsListWithIncompatibleFlagDisabled() throws Exception {
setBuildLanguageOptions("--noincompatible_depset_for_java_output_source_jars");
scratch.file(
"foo/extension.bzl",
"MyInfo = provider()",
"",
"def _impl(ctx):",
" return MyInfo(source_jars = ctx.attr.dep[JavaInfo].java_outputs[0].source_jars)",
"",
"my_rule = rule(",
" implementation = _impl,",
" attrs = {'dep' : attr.label()}",
")");
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'lib')",
"my_rule(name = 'my_starlark_rule', dep = ':lib')");
ConfiguredTarget target = getConfiguredTarget("//foo:my_starlark_rule");
StarlarkInfo info =
(StarlarkInfo)
target.get(
new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "MyInfo"));
assertThat(info).isNotNull();
assertThat(info.getValue("source_jars")).isInstanceOf(StarlarkList.class);
}
@Test
public void javaOutputSourceJarsReturnsDepsetWithIncompatibleFlagEnabled() throws Exception {
setBuildLanguageOptions("--incompatible_depset_for_java_output_source_jars");
scratch.file(
"foo/extension.bzl",
"MyInfo = provider()",
"",
"def _impl(ctx):",
" return MyInfo(source_jars = ctx.attr.dep[JavaInfo].java_outputs[0].source_jars)",
"",
"my_rule = rule(",
" implementation = _impl,",
" attrs = {'dep' : attr.label()}",
")");
scratch.file(
"foo/BUILD",
"load(':extension.bzl', 'my_rule')",
"java_library(name = 'lib')",
"my_rule(name = 'my_starlark_rule', dep = ':lib')");
ConfiguredTarget target = getConfiguredTarget("//foo:my_starlark_rule");
StarlarkInfo info =
(StarlarkInfo)
target.get(
new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "MyInfo"));
assertThat(info).isNotNull();
assertThat(info.getValue("source_jars")).isInstanceOf(Depset.class);
}
@Test
public void nativeAndStarlarkJavaOutputsCanBeAddedToADepset() throws Exception {
scratch.file(
"foo/extension.bzl",
"def _impl(ctx):",
" f = ctx.actions.declare_file(ctx.label.name + '.jar')",
" ctx.actions.write(f, '')",
" return [JavaInfo(output_jar=f, compile_jar=None)]",
"",
"my_rule = rule(implementation = _impl)");
scratch.file(
"foo/BUILD",
//
"load(':extension.bzl', 'my_rule')",
"my_rule(name = 'my_starlark_rule')");
JavaOutput nativeOutput =
JavaOutput.builder().setClassJar(createArtifact("native.jar")).build();
StarlarkList<?> starlarkOutputs =
((StarlarkInfo)
getConfiguredTarget("//foo:my_starlark_rule").get(JavaInfo.PROVIDER.getKey()))
.getValue("java_outputs", StarlarkList.class);
Depset depset =
Depset.fromDirectAndTransitive(
Order.STABLE_ORDER,
/* direct= */ ImmutableList.builder().add(nativeOutput).addAll(starlarkOutputs).build(),
/* transitive= */ ImmutableList.of(),
/* strict= */ true);
assertThat(depset).isNotNull();
assertThat(depset.toList()).hasSize(2);
}
@Test
public void translateStarlarkJavaInfo_minimal() throws Exception {
ImmutableMap<String, Object> fields = getBuilderWithMandataryFields().buildOrThrow();
StarlarkInfo starlarkInfo = makeStruct(fields);
JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);
assertThat(javaInfo).isNotNull();
assertThat(javaInfo.getProvider(JavaCompilationArgsProvider.class)).isNotNull();
assertThat(javaInfo.getCompilationInfoProvider()).isNull();
assertThat(javaInfo.getJavaModuleFlagsInfo()).isEqualTo(JavaModuleFlagsProvider.EMPTY);
assertThat(javaInfo.getJavaPluginInfo()).isEqualTo(JavaPluginInfo.empty());
}
@Test
public void translateStarlarkJavaInfo_binariesDoNotContainCompilationArgs() throws Exception {
ImmutableMap<String, Object> fields =
getBuilderWithMandataryFields().put("_is_binary", true).buildOrThrow();
StarlarkInfo starlarkInfo = makeStruct(fields);
JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);
assertThat(javaInfo).isNotNull();
assertThat(javaInfo.getProvider(JavaCompilationArgsProvider.class)).isNull();
}
@Test
public void translateStarlarkJavaInfo_compilationInfo() throws Exception {
ImmutableMap<String, Object> fields =
getBuilderWithMandataryFields()
.put(
"compilation_info",
makeStruct(
ImmutableMap.of(
"javac_options", StarlarkList.immutableOf("opt1", "opt2"),
"boot_classpath", StarlarkList.immutableOf(createArtifact("cp.jar")))))
.buildOrThrow();
StarlarkInfo starlarkInfo = makeStruct(fields);
JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);
assertThat(javaInfo).isNotNull();
assertThat(javaInfo.getCompilationInfoProvider()).isNotNull();
assertThat(javaInfo.getCompilationInfoProvider().getJavacOpts())
.containsExactly("opt1", "opt2");
assertThat(javaInfo.getCompilationInfoProvider().getBootClasspathList()).hasSize(1);
assertThat(prettyArtifactNames(javaInfo.getCompilationInfoProvider().getBootClasspathList()))
.containsExactly("cp.jar");
}
@Test
public void translatedStarlarkCompilationInfoEqualsNativeInstance() throws Exception {
Artifact bootClasspathArtifact = createArtifact("boot.jar");
NestedSet<Artifact> compilationClasspath =
NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, createArtifact("compile.jar"));
NestedSet<Artifact> runtimeClasspath =
NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, createArtifact("runtime.jar"));
StarlarkInfo starlarkInfo =
makeStruct(
ImmutableMap.of(
"compilation_classpath", Depset.of(Artifact.class, compilationClasspath),
"runtime_classpath", Depset.of(Artifact.class, runtimeClasspath),
"javac_options", StarlarkList.immutableOf("opt1", "opt2"),
"boot_classpath", StarlarkList.immutableOf(bootClasspathArtifact)));
JavaCompilationInfoProvider nativeCompilationInfo =
new JavaCompilationInfoProvider.Builder()
.setCompilationClasspath(compilationClasspath)
.setRuntimeClasspath(runtimeClasspath)
.setJavacOpts(ImmutableList.of("opt1", "opt2"))
.setBootClasspath(
NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, bootClasspathArtifact))
.build();
JavaCompilationInfoProvider starlarkCompilationInfo =
JavaCompilationInfoProvider.fromStarlarkCompilationInfo(starlarkInfo);
assertThat(starlarkCompilationInfo).isNotNull();
assertThat(starlarkCompilationInfo).isEqualTo(nativeCompilationInfo);
}
@Test
public void translateStarlarkJavaInfo_moduleFlagsInfo() throws Exception {
ImmutableMap<String, Object> fields =
getBuilderWithMandataryFields()
.put(
"module_flags_info",
makeStruct(
ImmutableMap.of(
"add_exports", makeDepset(String.class, "export1", "export2"),
"add_opens", makeDepset(String.class, "open1", "open2"))))
.buildOrThrow();
StarlarkInfo starlarkInfo = makeStruct(fields);
JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);
assertThat(javaInfo).isNotNull();
assertThat(javaInfo.getJavaModuleFlagsInfo()).isNotNull();
assertThat(javaInfo.getJavaModuleFlagsInfo().getAddExports().toList())
.containsExactly("export1", "export2");
assertThat(javaInfo.getJavaModuleFlagsInfo().getAddOpens().toList())
.containsExactly("open1", "open2");
}
@Test
public void translateStarlarkJavaInfo_pluginInfo() throws Exception {
ImmutableMap<String, Object> fields =
getBuilderWithMandataryFields()
.put(
"plugins",
JavaPluginData.create(
NestedSetBuilder.create(Order.STABLE_ORDER, "c1", "c2", "c3"),
NestedSetBuilder.create(Order.STABLE_ORDER, createArtifact("f1")),
NestedSetBuilder.emptySet(Order.STABLE_ORDER)))
.buildKeepingLast();
StarlarkInfo starlarkInfo = makeStruct(fields);
JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);
assertThat(javaInfo).isNotNull();
assertThat(javaInfo.plugins()).isNotNull();
assertThat(javaInfo.plugins().processorClasses().toList()).containsExactly("c1", "c2", "c3");
assertThat(prettyArtifactNames(javaInfo.plugins().processorClasspath())).containsExactly("f1");
}
private static ImmutableMap.Builder<String, Object> getBuilderWithMandataryFields() {
Depset emptyDepset = Depset.of(Artifact.class, NestedSetBuilder.create(Order.STABLE_ORDER));
return ImmutableMap.<String, Object>builder()
.put("transitive_native_libraries", emptyDepset)
.put("compile_jars", emptyDepset)
.put("full_compile_jars", emptyDepset)
.put("transitive_compile_time_jars", emptyDepset)
.put("transitive_runtime_jars", emptyDepset)
.put("_transitive_full_compile_time_jars", emptyDepset)
.put("_compile_time_java_dependencies", emptyDepset)
.put("plugins", JavaPluginData.empty())
.put("api_generating_plugins", JavaPluginData.empty())
.put("java_outputs", StarlarkList.empty())
.put("transitive_source_jars", emptyDepset)
.put("source_jars", StarlarkList.empty())
.put("runtime_output_jars", StarlarkList.empty());
}
private Artifact createArtifact(String path) throws IOException {
Path execRoot = scratch.dir("/");
ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, RootType.Output, "fake-root");
return ActionsTestUtil.createArtifact(root, path);
}
private static <T> Depset makeDepset(Class<T> clazz, T... elems) {
return Depset.of(clazz, NestedSetBuilder.create(Order.STABLE_ORDER, elems));
}
private static StarlarkInfo makeStruct(Map<String, Object> struct) {
return StructProvider.STRUCT.create(struct, "");
}
private RuleBuilder ruleBuilder() {
return new RuleBuilder();
}
private class RuleBuilder {
private boolean useIJar = false;
private boolean stampJar;
private boolean neverLink = false;
private boolean sourceFiles = false;
@CanIgnoreReturnValue
private RuleBuilder withIJar() {
useIJar = true;
return this;
}
@CanIgnoreReturnValue
private RuleBuilder withStampJar() {
stampJar = true;
return this;
}
@CanIgnoreReturnValue
private RuleBuilder withNeverLink() {
neverLink = true;
return this;
}
@CanIgnoreReturnValue
private RuleBuilder withSourceFiles() {
sourceFiles = true;
return this;
}
private String[] newJavaInfo() {
assertThat(useIJar && stampJar).isFalse();
ImmutableList.Builder<String> lines = ImmutableList.builder();
lines.add(
"result = provider()",
"def _impl(ctx):",
" ctx.actions.write(ctx.outputs.output_jar, 'JavaInfo API Test', is_executable=False) ",
" dp = [dep[java_common.provider] for dep in ctx.attr.dep]",
" dp_runtime = [dep[java_common.provider] for dep in ctx.attr.dep_runtime]",
" dp_exports = [dep[java_common.provider] for dep in ctx.attr.dep_exports]",
" dp_exported_plugins = [dep[JavaPluginInfo] for dep in ctx.attr.dep_exported_plugins]",
" dp_libs = [dep[CcInfo] for dep in ctx.attr.cc_dep]");
if (useIJar) {
lines.add(
" compile_jar = java_common.run_ijar(",
" ctx.actions,",
" jar = ctx.outputs.output_jar,",
" java_toolchain = ctx.attr._toolchain[java_common.JavaToolchainInfo],",
" )");
} else if (stampJar) {
lines.add(
" compile_jar = java_common.stamp_jar(",
" ctx.actions,",
" jar = ctx.outputs.output_jar,",
" target_label = ctx.label,",
" java_toolchain = ctx.attr._toolchain[java_common.JavaToolchainInfo],",
" )");
} else {
lines.add(" compile_jar = ctx.outputs.output_jar");
}
if (sourceFiles) {
lines.add(
" source_jar = java_common.pack_sources(",
" ctx.actions,",
" output_source_jar = ",
" ctx.actions.declare_file(ctx.outputs.output_jar.basename[:-4] + '-src.jar'),",
" sources = ctx.files.sources,",
" source_jars = ctx.files.source_jars,",
" java_toolchain = ctx.attr._toolchain[java_common.JavaToolchainInfo],",
")");
} else {
lines.add(
" if ctx.files.source_jars:",
" source_jar = list(ctx.files.source_jars)[0]",
" else:",
" source_jar = None");
}
lines.add(
" javaInfo = JavaInfo(",
" output_jar = ctx.outputs.output_jar,",
" compile_jar = compile_jar,",
" source_jar = source_jar,",
neverLink ? " neverlink = True," : "",
" deps = dp,",
" runtime_deps = dp_runtime,",
" exports = dp_exports,",
" exported_plugins = dp_exported_plugins,",
" jdeps = ctx.file.jdeps,",
" compile_jdeps = ctx.file.compile_jdeps,",
" generated_class_jar = ctx.file.generated_class_jar,",
" generated_source_jar = ctx.file.generated_source_jar,",
" native_headers_jar = ctx.file.native_headers_jar,",
" manifest_proto = ctx.file.manifest_proto,",
" native_libraries = dp_libs,");
if (analysisMock.isThisBazel()) {
lines.add(
" add_exports = ctx.attr.add_exports,", //
" add_opens = ctx.attr.add_opens,");
}
lines.add(
" )", //
" return [result(property = javaInfo)]");
return lines.build().toArray(new String[] {});
}
private void build() throws Exception {
if (useIJar || stampJar || sourceFiles) {
JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
}
ImmutableList.Builder<String> lines = ImmutableList.builder();
lines.add(newJavaInfo());
lines.add(
"my_rule = rule(",
" implementation = _impl,",
" toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
" attrs = {",
" 'dep' : attr.label_list(),",
" 'cc_dep' : attr.label_list(),",
" 'dep_runtime' : attr.label_list(),",
" 'dep_exports' : attr.label_list(),",
" 'dep_exported_plugins' : attr.label_list(),",
" 'output_jar' : attr.output(mandatory=True),",
" 'source_jars' : attr.label_list(allow_files=['.jar']),",
" 'sources' : attr.label_list(allow_files=['.java']),",
" 'jdeps' : attr.label(allow_single_file=True),",
" 'compile_jdeps' : attr.label(allow_single_file=True),",
" 'generated_class_jar' : attr.label(allow_single_file=True),",
" 'generated_source_jar' : attr.label(allow_single_file=True),",
" 'native_headers_jar' : attr.label(allow_single_file=True),",
" 'manifest_proto' : attr.label(allow_single_file=True),",
" 'add_exports' : attr.string_list(),",
" 'add_opens' : attr.string_list(),",
useIJar || stampJar || sourceFiles
? " '_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),"
: "",
" }",
")");
scratch.file("foo/extension.bzl", lines.build().toArray(new String[] {}));
}
}
private JavaInfo fetchJavaInfo() throws Exception {
ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
StructImpl info =
(StructImpl)
myRuleTarget.get(
new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));
return JavaInfo.PROVIDER.wrap(info.getValue("property", Info.class));
}
}