blob: b2b470b53a5f2452e935adbd416659638be5e937 [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.android;
import com.android.builder.core.VariantType;
import com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions;
import com.google.devtools.build.android.Converters.PathConverter;
import com.google.devtools.build.android.Converters.VariantTypeConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Action that processes resources for Databinding v2.
*/
public class AndroidDataBindingProcessingAction {
/** Flag specifications for this action. */
public static final class Options extends OptionsBase {
@Option(
name = "resource_root",
defaultValue = "null",
converter = PathConverter.class,
allowMultiple = true,
category = "input",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "Input resource root. A corresponding output resource root must be passed to "
+ "--output_resource_root. Multiple roots will be paired in the order they're passed.")
public List<Path> resourceRoots;
@Option(
name = "output_resource_root",
defaultValue = "null",
converter = PathConverter.class,
allowMultiple = true,
category = "input",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "The output resource root. A corresponding input resource root must be passed to "
+ "--resource_root. Multiple roots will be paired in the order they're passed.")
public List<Path> outputResourceRoots;
@Option(
name = "packageType",
defaultValue = "DEFAULT",
converter = VariantTypeConverter.class,
category = "config",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help =
"Variant configuration type for packaging the resources."
+ " Acceptable values DEFAULT, LIBRARY, ANDROID_TEST, UNIT_TEST")
public VariantType packageType;
@Option(
name = "dataBindingInfoOut",
defaultValue = "null",
converter = PathConverter.class,
category = "output",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "Path to where data binding's layout info output should be written.")
public Path dataBindingInfoOut;
@Option(
name = "appId",
defaultValue = "null",
category = "config",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "The java package for the app.")
public String appId;
}
public static void main(String[] args) throws IOException {
OptionsParser optionsParser =
OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class);
optionsParser.enableParamsFileSupport(
new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()));
optionsParser.parseAndExitUponError(args);
Options options = optionsParser.getOptions(Options.class);
if (options.dataBindingInfoOut == null) {
throw new IllegalArgumentException("--dataBindingInfoOut is required");
}
if (options.appId == null) {
throw new IllegalArgumentException("--appId is required");
}
List<Path> resourceRoots = options.resourceRoots == null
? Collections.emptyList()
: options.resourceRoots;
List<Path> outputResourceRoots = options.outputResourceRoots == null
? Collections.emptyList()
: options.outputResourceRoots;
if (resourceRoots.size() != outputResourceRoots.size()) {
throw new IllegalArgumentException("--resource_root and --output_resource_root must be "
+ "specified the same number of times");
}
try (ScopedTemporaryDirectory dataBindingInfoOutDir =
new ScopedTemporaryDirectory("android_data_binding_layout_info_tmp")) {
// 1. Process databinding resources for each source root.
for (int i = 0; i < resourceRoots.size(); i++) {
Path resourceRoot = resourceRoots.get(i);
Path outputResourceRoot = outputResourceRoots.get(i);
AndroidResourceProcessor.processDataBindings(
outputResourceRoot,
resourceRoot,
dataBindingInfoOutDir.getPath(),
options.appId,
/* shouldZipDataBindingInfo= */ false);
}
// 2. Zip all the layout info files into one zip file.
try (ZipOutputStream layoutInfoZip =
new ZipOutputStream(Files.newOutputStream(options.dataBindingInfoOut));
Stream<Path> layoutInfos = Files.list(dataBindingInfoOutDir.getPath())) {
for (Path layoutInfo : (Iterable<Path>) layoutInfos::iterator) {
ZipEntry zipEntry = new ZipEntry(layoutInfo.getFileName().toString());
layoutInfoZip.putNextEntry(zipEntry);
Files.copy(layoutInfo, layoutInfoZip);
layoutInfoZip.closeEntry();
}
}
}
}
}