blob: 0368dbf6f996a6d6a9aacb0fc25c4c7c483abd28 [file] [log] [blame]
// 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;
}
/** Modes of performing content hash checking during zip filtering. */
public enum CheckHashMismatchMode {
NONE,
WARN,
ERROR;
}
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;
private CheckHashMismatchMode checkHashMismatch = CheckHashMismatchMode.WARN;
/** 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;
}
/** Enable checking of hash mismatches for files with the same name. */
public ZipFilterBuilder setCheckHashMismatchMode(CheckHashMismatchMode mode) {
this.checkHashMismatch = mode;
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));
}
switch (checkHashMismatch) {
case WARN:
args.add("--checkHashMismatch").add("WARN");
break;
case ERROR:
args.add("--checkHashMismatch").add("ERROR");
break;
case NONE:
args.add("--checkHashMismatch").add("IGNORE");
break;
}
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));
}
}