blob: 7fc3258a5a2ec657d651b6061ff985158a44fb30 [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.lib.rules.android;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.vfs.PathFragment;
/** Builder for creating databinding processing action. */
public class AndroidDataBindingProcessorBuilder {
/**
* Creates and registers an action to strip databinding from layout xml and generate the layout
* info file.
*
* @param dataContext The android data context.
* @param androidResources The resources to process.
* @param appId The app id (the app's java package).
* @param dataBindingLayoutInfoOut The output layout info file to write.
* @param useDataBindingAndroidX Whether generated files should use AndroidX dependencies.
* @return The new AndroidResources that has been processed by databinding.
*/
public static AndroidResources create(
AndroidDataContext dataContext,
AndroidResources androidResources,
String appId,
Artifact dataBindingLayoutInfoOut,
boolean useDataBindingAndroidX) {
ImmutableList.Builder<Artifact> databindingProcessedResourcesBuilder = ImmutableList.builder();
for (Artifact resource : androidResources.getResources()) {
// Create resources that will be processed by databinding under paths that look like:
//
// <bazel-pkg>/databinding-processed-resources/<rule-name>/<bazal-pkg>/<resource-dir>
Artifact databindingProcessedResource =
dataContext.getUniqueDirectoryArtifact(
"databinding-processed-resources", resource.getExecPath());
databindingProcessedResourcesBuilder.add(databindingProcessedResource);
}
ImmutableList<Artifact> databindingProcessedResources =
databindingProcessedResourcesBuilder.build();
BusyBoxActionBuilder builder = BusyBoxActionBuilder.create(dataContext, "PROCESS_DATABINDING");
// Create output resource roots that correspond to the paths of the resources created above:
//
// <bazel-pkg>/databinding-processed-resources/<rule-name>/<resource-root>
ArtifactRoot binOrGenfiles = dataContext.getBinOrGenfilesDirectory();
PathFragment uniqueDir =
dataContext.getUniqueDirectory(PathFragment.create("databinding-processed-resources"));
PathFragment outputResourceRoot = binOrGenfiles.getExecPath().getRelative(uniqueDir);
// AndroidDataBindingProcessingAction will append each value of --resource_root to its
// corresponding --output_resource_directory, so the only part that needs to be constructed here
// is:
//
// <bazel-pkg>/databinding-processed-resources/<rule-name>
builder.addFlag("--output_resource_directory", outputResourceRoot.toString());
ImmutableList.Builder<PathFragment> outputResourceRootsBuilder = ImmutableList.builder();
for (PathFragment resourceRoot : androidResources.getResourceRoots()) {
builder.addFlag("--resource_root", resourceRoot.toString());
outputResourceRootsBuilder.add(outputResourceRoot.getRelative(resourceRoot));
}
// Even though the databinding processor really only cares about layout files, we send
// all the resources so that the new resource root that is created for databinding processing
// can be used for later processing (e.g. aapt). It would be nice to send only the layout
// files, but then we'd have to mix roots and rely on sandboxing to "hide" the
// old unprocessed files, which might not work if, for example, the actions run locally.
builder.addInputs(androidResources.getResources());
builder.addOutputs(databindingProcessedResources);
builder.addOutput("--dataBindingInfoOut", dataBindingLayoutInfoOut);
builder.addFlag("--appId", appId);
builder.maybeAddFlag("--useDataBindingAndroidX", useDataBindingAndroidX);
builder.buildAndRegister("Processing data binding", "ProcessDatabinding");
return new AndroidResources(databindingProcessedResources, outputResourceRootsBuilder.build());
}
}