diff options
Diffstat (limited to 'src/test')
5 files changed, 235 insertions, 16 deletions
diff --git a/src/test/java/com/google/devtools/build/android/ideinfo/BUILD b/src/test/java/com/google/devtools/build/android/ideinfo/BUILD index 9de5aa76d4..0f5fe191b1 100644 --- a/src/test/java/com/google/devtools/build/android/ideinfo/BUILD +++ b/src/test/java/com/google/devtools/build/android/ideinfo/BUILD @@ -5,6 +5,22 @@ filegroup( ) java_test( + name = "JarFilterTest", + size = "small", + srcs = ["JarFilterTest.java"], + deps = [ + "//src/main/java/com/google/devtools/common/options", + "//src/main/protobuf:package_manifest_java_proto", + "//src/tools/android/java/com/google/devtools/build/android/ideinfo:jar_filter_lib", + "//third_party:guava", + "//third_party:jsr305", + "//third_party:junit4", + "//third_party:truth", + "//third_party/protobuf", + ], +) + +java_test( name = "PackageParserTest", size = "small", srcs = ["PackageParserTest.java"], diff --git a/src/test/java/com/google/devtools/build/android/ideinfo/JarFilterTest.java b/src/test/java/com/google/devtools/build/android/ideinfo/JarFilterTest.java new file mode 100644 index 0000000000..eedfb9f9e3 --- /dev/null +++ b/src/test/java/com/google/devtools/build/android/ideinfo/JarFilterTest.java @@ -0,0 +1,94 @@ +// Copyright 2015 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.android.ideinfo; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass.ArtifactLocation; +import com.google.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass.JavaSourcePackage; +import com.google.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass.PackageManifest; +import java.nio.file.Paths; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit tests for {@link JarFilter} + */ +@RunWith(JUnit4.class) +public class JarFilterTest { + + @Test + public void testParseCommandLineArguments() throws Exception { + String[] args = new String[]{ + "--jars", + "/tmp/1.jar:/tmp/2.jar", + "--output", + "/tmp/out.jar", + "--manifest", + "/tmp/manifest.file", + }; + JarFilter.JarFilterOptions options = JarFilter.parseArgs(args); + assertThat(options.jars).containsExactly( + Paths.get("/tmp/1.jar"), + Paths.get("/tmp/2.jar") + ); + assertThat(options.output.toString()).isEqualTo(Paths.get("/tmp/out.jar").toString()); + assertThat(options.manifest.toString()).isEqualTo(Paths.get("/tmp/manifest.file").toString()); + } + + @Test + public void testFilterMethod() throws Exception { + List<String> prefixes = ImmutableList.of( + "com/google/foo/Foo", + "com/google/bar/Bar", + "com/google/baz/Baz" + ); + assertThat(JarFilter.shouldKeep(prefixes, "com/google/foo/Foo.class")).isTrue(); + assertThat(JarFilter.shouldKeep(prefixes, "com/google/foo/Foo$Inner.class")).isTrue(); + assertThat(JarFilter.shouldKeep(prefixes, "com/google/bar/Bar.class")).isTrue(); + assertThat(JarFilter.shouldKeep(prefixes, "com/google/foo/Foo/NotFoo.class")).isFalse(); + assertThat(JarFilter.shouldKeep(prefixes, "wrong/com/google/foo/Foo.class")).isFalse(); + } + + @Test + public void testManifestParser() throws Exception { + PackageManifest packageManifest = PackageManifest.newBuilder() + .addSources(JavaSourcePackage.newBuilder() + .setArtifactLocation(ArtifactLocation.newBuilder() + .setIsSource(true) + .setRelativePath("com/google/foo/Foo.java")) + .setPackageString("com.google.foo")) + .addSources(JavaSourcePackage.newBuilder() + .setArtifactLocation(ArtifactLocation.newBuilder() + .setIsSource(true) + .setRelativePath("com/google/bar/Bar.java")) + .setPackageString("com.google.bar")) + .addSources(JavaSourcePackage.newBuilder() + .setArtifactLocation(ArtifactLocation.newBuilder() + .setIsSource(true) + .setRelativePath("some/path/Test.java")) + .setPackageString("com.google.test")) + .build(); + assertThat(JarFilter.parsePackageManifest(packageManifest)).containsExactly( + "com/google/foo/Foo", + "com/google/bar/Bar", + "com/google/test/Test" + ); + } +} + diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java index 5b47d44f86..0a7452d7b0 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java @@ -183,6 +183,11 @@ public final class BazelAnalysisMock extends AnalysisMock { .add("sh_binary(name = 'strip_resources', srcs = ['empty.sh'])") .add("sh_binary(name = 'build_incremental_dexmanifest', srcs = ['empty.sh'])") .add("sh_binary(name = 'incremental_install', srcs = ['empty.sh'])") + .add("java_binary(name = 'JarFilter',") + .add(" runtime_deps = [ ':JarFilter_import'],") + .add(" main_class = 'com.google.devtools.build.android.ideinfo.JarFilter')") + .add("java_import(name = 'JarFilter_import',") + .add(" jars = [ 'jar_filter_deploy.jar' ])") .add("java_binary(name = 'PackageParser',") .add(" runtime_deps = [ ':PackageParser_import'],") .add(" main_class = 'com.google.devtools.build.android.ideinfo.PackageParser')") diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java index d06352e17b..0a375a2666 100644 --- a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java +++ b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java @@ -118,6 +118,59 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase } @Test + public void testFilteredGenJarNotCreatedForSourceOnlyRule() throws Exception { + scratch.file( + "com/google/example/BUILD", + "java_library(", + " name = 'simple',", + " srcs = ['Test.java']", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + assertThat(ruleIdeInfo.getJavaRuleIdeInfo().hasFilteredGenJar()).isFalse(); + } + + @Test + public void testFilteredGenJarNotCreatedForOnlyGenRule() throws Exception { + scratch.file( + "com/google/example/BUILD", + "genrule(", + " name = 'gen_sources',", + " outs = ['Gen.java'],", + " cmd = '',", + ")", + "java_library(", + " name = 'simple',", + " srcs = [':gen_sources']", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + assertThat(ruleIdeInfo.getJavaRuleIdeInfo().hasFilteredGenJar()).isFalse(); + } + + @Test + public void testFilteredGenJarIsCreatedForMixedGenAndSourcesRule() throws Exception { + scratch.file( + "com/google/example/BUILD", + "genrule(", + " name = 'gen_sources',", + " outs = ['Gen.java'],", + " cmd = '',", + ")", + "java_library(", + " name = 'simple',", + " srcs = [':gen_sources', 'Test.java']", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + assertThat(ruleIdeInfo.getJavaRuleIdeInfo().getFilteredGenJar().getJar().getRelativePath()) + .isEqualTo("com/google/example/simple-filtered-gen.jar"); + } + + @Test public void testJavaLibraryWithDependencies() throws Exception { scratch.file( "com/google/example/BUILD", diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl b/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl index 1ef6df9e7f..79d1ae7601 100644 --- a/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl +++ b/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl @@ -270,6 +270,7 @@ def build_java_rule_ide_info(target, ctx): if not hasattr(target, "java") or ctx.rule.kind == "proto_library": return (None, set(), set()) + ide_info_files = set() sources = sources_from_rule(ctx) jars = [library_artifact(output) for output in target.java.outputs.jars] @@ -287,8 +288,37 @@ def build_java_rule_ide_info(target, ctx): jdeps = artifact_location(target.java.outputs.jdeps) - package_manifest = build_java_package_manifest(target, ctx) - ide_info_files = set([package_manifest]) if package_manifest else set() + java_sources, gen_java_sources = java_sources_for_package_manifest(ctx) + + package_manifest = None + if java_sources: + package_manifest = build_java_package_manifest(ctx, target, java_sources, ".manifest") + ide_info_files = ide_info_files | set([package_manifest]) + + filtered_gen_jar = None + if java_sources and gen_java_sources: + gen_package_manifest = build_java_package_manifest( + ctx, + target, + gen_java_sources, + "-filtered-gen.manifest" + ) + jar_artifacts = [] + for jar in target.java.outputs.jars: + if jar.ijar: + jar_artifacts.append(jar.ijar) + elif jar.class_jar: + jar_artifacts.append(jar.class_jar) + filtered_gen_jar_artifact = build_filtered_gen_jar( + ctx, + target, + jar_artifacts, + gen_package_manifest + ) + ide_resolve_files = ide_resolve_files | set([filtered_gen_jar_artifact]) + filtered_gen_jar = struct( + jar=artifact_location(filtered_gen_jar_artifact), + ) java_rule_ide_info = struct_omit_none( sources = sources, @@ -296,23 +326,20 @@ def build_java_rule_ide_info(target, ctx): jdeps = jdeps, generated_jars = gen_jars, package_manifest = artifact_location(package_manifest), + filtered_gen_jar = filtered_gen_jar, ) return (java_rule_ide_info, ide_info_files, ide_resolve_files) -def build_java_package_manifest(target, ctx): - """Builds a java package manifest and returns the output file.""" - source_files = java_sources_for_package_manifest(ctx) - if not source_files: - return None - - output = ctx.new_file(target.label.name + ".manifest") +def build_java_package_manifest(ctx, target, source_files, suffix): + """Builds the java package manifest for the given source files.""" + output = ctx.new_file(target.label.name + suffix) args = [] args += ["--output_manifest", output.path] args += ["--sources"] - args += [":".join([f.root.path + "," + f.path for f in source_files])] + args += [":".join([f.root.path + "," + f.short_path for f in source_files])] argfile = ctx.new_file(ctx.configuration.bin_dir, - target.label.name + ".manifest.params") + target.label.name + suffix + ".params") ctx.file_action(output=argfile, content="\n".join(args)) ctx.action( @@ -325,15 +352,34 @@ def build_java_package_manifest(target, ctx): ) return output +def build_filtered_gen_jar(ctx, target, jars, manifest): + """Filters the passed jar to contain only classes from the given manifest.""" + output = ctx.new_file(target.label.name + "-filtered-gen.jar") + args = [] + args += ["--jars"] + args += [":".join([jar.path for jar in jars])] + args += ["--manifest", manifest.path] + args += ["--output", output.path] + ctx.action( + inputs = jars + [manifest], + outputs = [output], + executable = ctx.executable._jar_filter, + arguments = args, + mnemonic = "JarFilter", + progress_message = "Filtering generated code for " + str(target.label), + ) + return output + def java_sources_for_package_manifest(ctx): """Get the list of non-generated java sources to go in the package manifest.""" if hasattr(ctx.rule.attr, "srcs"): - return [f - for src in ctx.rule.attr.srcs - for f in src.files - if f.is_source and f.basename.endswith(".java")] - return [] + srcs = ctx.rule.attr.srcs + all_java_sources = [f for src in srcs for f in src.files if f.basename.endswith(".java")] + java_sources = [f for f in all_java_sources if f.is_source] + gen_java_sources = [f for f in all_java_sources if not f.is_source] + return java_sources, gen_java_sources + return [], [] def build_android_rule_ide_info(target, ctx, legacy_resource_label): """Build AndroidRuleIdeInfo. @@ -520,6 +566,11 @@ def _aspect_def(impl): cfg = HOST_CFG, executable = True, allow_files = True), + "_jar_filter": attr.label( + default = tool_label("//tools/android:JarFilter"), + cfg = HOST_CFG, + executable = True, + allow_files = True), }, attr_aspects = ALL_DEPS.label + ALL_DEPS.label_list + [LEGACY_RESOURCE_ATTR], fragments = ["cpp"], |