aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/android/ZipFilterBuilder.java
blob: 0368dbf6f996a6d6a9aacb0fc25c4c7c483abd28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// 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));
  }
}