aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ZipFilterBuilder.java135
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java5
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/BUILD4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/BUILD.tools12
-rw-r--r--tools/android/BUILD.tools5
6 files changed, 166 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index d0bac081e9..0d9fbb7d50 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -948,6 +948,11 @@ public final class AndroidRuleClasses {
.undocumented("blocked by android_instrumentation_test")
.allowedRuleClasses("android_binary")
.allowedFileTypes(NO_FILE))
+ .add(
+ attr("$zip_filter", LABEL)
+ .cfg(HOST)
+ .exec()
+ .value(env.getToolsLabel("//tools/android:zip_filter")))
.advertiseSkylarkProvider(SkylarkProviderIdentifier.forKey(JavaInfo.PROVIDER.getKey()))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ZipFilterBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ZipFilterBuilder.java
new file mode 100644
index 0000000000..e3e83a3ffb
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ZipFilterBuilder.java
@@ -0,0 +1,135 @@
+// Copyright 2017 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.android;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
+
+/**
+ * Builder for creating a zip filter action.
+ */
+public class ZipFilterBuilder {
+ /**
+ * Type of compression to apply to output archive.
+ */
+ public enum Compression {
+ /** Output should be compressed. */
+ COMPRESSED,
+ /** Output should not be compressed. */
+ UNCOMPRESSED,
+ /** Compression should not change from input Zip. */
+ DONT_CHANGE;
+ }
+
+ private final RuleContext ruleContext;
+ private Artifact inputZip;
+ private Artifact outputZip;
+ private final ImmutableSet.Builder<Artifact> filterZipsBuilder;
+ private final ImmutableSet.Builder<String> filterFileTypesBuilder;
+ private final ImmutableSet.Builder<String> explicitFilterBuilder;
+ private Compression outputMode = Compression.DONT_CHANGE;
+
+ /** Creates a builder using the configuration of the rule as the action configuration. */
+ public ZipFilterBuilder(RuleContext ruleContext) {
+ this.ruleContext = ruleContext;
+ filterZipsBuilder = new ImmutableSet.Builder<>();
+ filterFileTypesBuilder = new ImmutableSet.Builder<>();
+ explicitFilterBuilder = new ImmutableSet.Builder<>();
+ }
+
+ /** Sets the Zip file to be filtered. */
+ public ZipFilterBuilder setInputZip(Artifact inputZip) {
+ this.inputZip = inputZip;
+ return this;
+ }
+
+ /** Sets the artifact to create with the action. */
+ public ZipFilterBuilder setOutputZip(Artifact outputZip) {
+ this.outputZip = outputZip;
+ return this;
+ }
+
+ /**
+ * Adds to the Zip files to use as filters. Contents in these files will be omitted from the
+ * output.
+ */
+ public ZipFilterBuilder addFilterZips(Iterable<Artifact> filterZips) {
+ this.filterZipsBuilder.addAll(filterZips);
+ return this;
+ }
+
+ /**
+ * Adds to the file types to use as filters. Only contents in the filter Zip files with these
+ * extensions will be filtered out.
+ */
+ public ZipFilterBuilder addFileTypeToFilter(String filterFileType) {
+ this.filterFileTypesBuilder.add(filterFileType);
+ return this;
+ }
+
+ /** Adds filterRegex to the set of filters to always check for and remove. */
+ public ZipFilterBuilder addExplicitFilter(String filterRegex) {
+ this.explicitFilterBuilder.add(filterRegex);
+ return this;
+ }
+
+ /** Builds the action as configured. */
+ public void build() {
+ ImmutableSet<Artifact> filterZips = filterZipsBuilder.build();
+ ImmutableSet<String> filterFileTypes = filterFileTypesBuilder.build();
+ ImmutableSet<String> explicitFilters = explicitFilterBuilder.build();
+
+ CustomCommandLine.Builder args = CustomCommandLine.builder();
+ args.addExecPath("--inputZip", inputZip);
+ args.addExecPath("--outputZip", outputZip);
+ if (!filterZips.isEmpty()) {
+ args.addExecPaths("--filterZips", VectorArg.join(",").each(filterZips));
+ }
+ if (!filterFileTypes.isEmpty()) {
+ args.addAll("--filterTypes", VectorArg.join(",").each(filterFileTypes));
+ }
+ if (!explicitFilters.isEmpty()) {
+ args.addAll("--explicitFilters", VectorArg.join(",").each(explicitFilters));
+ }
+ args.add("--outputMode");
+ switch (outputMode) {
+ case COMPRESSED:
+ args.add("FORCE_DEFLATE");
+ break;
+ case UNCOMPRESSED:
+ args.add("FORCE_STORED");
+ break;
+ case DONT_CHANGE:
+ default:
+ args.add("DONT_CARE");
+ break;
+ }
+
+ ruleContext.registerAction(
+ new SpawnAction.Builder()
+ .addInput(inputZip)
+ .addInputs(filterZips)
+ .addOutput(outputZip)
+ .setExecutable(ruleContext.getExecutablePrerequisite("$zip_filter", Mode.HOST))
+ .addCommandLine(args.build())
+ .setProgressMessage("Filtering Zip %s", inputZip.prettyPrint())
+ .setMnemonic("ZipFilter")
+ .build(ruleContext));
+ }
+}
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 423f20c290..626bbdcceb 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
@@ -238,6 +238,11 @@ public final class BazelAnalysisMock extends AnalysisMock {
.add("java_binary(name = 'IdlClass',")
.add(" runtime_deps = [ ':idlclass_import' ],")
.add(" main_class = 'com.google.devtools.build.android.idlclass.IdlClass')")
+ .add("java_binary(name = 'zip_filter',")
+ .add(" main_class = 'com.google.devtools.build.android.ZipFilterAction',")
+ .add(" runtime_deps = [ ':ZipFilterAction_import' ])")
+ .add("java_import(name = 'ZipFilterAction_import',")
+ .add(" jars = [ 'ZipFilterAction_deploy.jar' ])")
.add("sh_binary(name = 'aar_resources_extractor', srcs = ['empty.sh'])")
.add("sh_binary(name = 'aar_embedded_jars_extractor', srcs = ['empty.sh'])")
.add("java_import(name = 'idlclass_import',")
diff --git a/src/tools/android/java/com/google/devtools/build/android/BUILD b/src/tools/android/java/com/google/devtools/build/android/BUILD
index 6bf42f53e3..d563c772df 100644
--- a/src/tools/android/java/com/google/devtools/build/android/BUILD
+++ b/src/tools/android/java/com/google/devtools/build/android/BUILD
@@ -40,6 +40,10 @@ java_binary(
java_binary(
name = "ZipFilterAction",
+ # Memory consumption of SingleJar is about 250 bytes per entry in the output file. Unfortunately,
+ # the JVM tends to kill the process with an OOM long before we're at the limit. In the most
+ # recent example, 400 MB of memory was enough for about 500,000 entries.
+ jvm_flags = ["-Xmx1600m"],
main_class = "com.google.devtools.build.android.ZipFilterAction",
visibility = ["//visibility:private"],
runtime_deps = [":android_builder_lib"],
diff --git a/src/tools/android/java/com/google/devtools/build/android/BUILD.tools b/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
index f0f858b6db..26b66d2496 100644
--- a/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
+++ b/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
@@ -17,3 +17,15 @@ java_binary(
":all_android_tools",
],
)
+
+java_binary(
+ name = "ZipFilterAction",
+ # Memory consumption of SingleJar is about 250 bytes per entry in the output file. Unfortunately,
+ # the JVM tends to kill the process with an OOM long before we're at the limit. In the most
+ # recent example, 400 MB of memory was enough for about 500,000 entries.
+ jvm_flags = ["-Xmx1600m"],
+ main_class = "com.google.devtools.build.android.ZipFilterAction",
+ runtime_deps = [
+ ":all_android_tools"
+ ],
+)
diff --git a/tools/android/BUILD.tools b/tools/android/BUILD.tools
index 8459ff3d9b..6826d52235 100644
--- a/tools/android/BUILD.tools
+++ b/tools/android/BUILD.tools
@@ -50,6 +50,11 @@ alias(
actual = "//src/tools/android/java/com/google/devtools/build/android/desugar:Desugar",
)
+alias(
+ name = "zip_filter",
+ actual = "//src/tools/android/java/com/google/devtools/build/android:ZipFilterAction",
+)
+
# Bazel puts this on the bootclasspath of android_* targets to support Java 8
# if requested.
filegroup(