Skip to content

Commit

Permalink
Implement worker support for GenerateDataBindingBaseClasses
Browse files Browse the repository at this point in the history
  • Loading branch information
arunsampathkumar-grabtaxi committed Aug 8, 2022
1 parent fe7deab commit c0edd1c
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
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.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.BuildType;
Expand All @@ -37,6 +33,7 @@
import com.google.devtools.build.lib.rules.android.AndroidDataBindingProcessorBuilder;
import com.google.devtools.build.lib.rules.android.AndroidDataContext;
import com.google.devtools.build.lib.rules.android.AndroidResources;
import com.google.devtools.build.lib.rules.android.BusyBoxActionBuilder;
import com.google.devtools.build.lib.rules.java.JavaPluginInfo;
import com.google.devtools.build.lib.starlarkbuildapi.android.DataBindingV2ProviderApi;
import com.google.devtools.build.lib.starlarkbuildapi.android.DataBindingV2ProviderApi.LabelJavaPackagePair;
Expand Down Expand Up @@ -289,44 +286,31 @@ public ImmutableList<Artifact> getAnnotationSourceFiles(RuleContext ruleContext)
}

private ImmutableList<Artifact> createBaseClasses(RuleContext ruleContext) {

if (!AndroidResources.definesAndroidResources(ruleContext.attributes())) {
return ImmutableList.of(); // no resource, no base classes or class info
}

Artifact layoutInfo = getLayoutInfoFile();
Artifact classInfoFile = getClassInfoFile(ruleContext);
Artifact srcOutFile =
final Artifact layoutInfo = getLayoutInfoFile();
final Artifact classInfoFile = getClassInfoFile(ruleContext);
final Artifact srcOutFile =
DataBinding.getDataBindingArtifact(
ruleContext, "baseClassSrc.srcjar", /* isDirectory= */ false);

FilesToRunProvider exec =
ruleContext.getExecutablePrerequisite(DataBinding.DATABINDING_EXEC_PROCESSOR_ATTR);

CustomCommandLine.Builder commandLineBuilder =
CustomCommandLine.builder()
.add("GEN_BASE_CLASSES")
.addExecPath("-layoutInfoFiles", layoutInfo)
.add("-package", AndroidCommon.getJavaPackage(ruleContext))
.addExecPath("-classInfoOut", classInfoFile)
.addExecPath("-sourceOut", srcOutFile)
.add("-zipSourceOutput", "true")
.add("-useAndroidX", useAndroidX ? "true" : "false");

NestedSet<Artifact> dependencyClassInfo = getDirectClassInfo(ruleContext);
commandLineBuilder.addExecPaths(
VectorArg.addBefore("-dependencyClassInfoList").each(dependencyClassInfo));

ruleContext.registerAction(
new SpawnAction.Builder()
.setExecutable(exec)
.setMnemonic("GenerateDataBindingBaseClasses")
.addInput(layoutInfo)
.addTransitiveInputs(dependencyClassInfo)
.addOutput(classInfoFile)
.addOutput(srcOutFile)
.addCommandLine(commandLineBuilder.build())
.build(ruleContext));
final NestedSet<Artifact> dependencyClassInfo = getDirectClassInfo(ruleContext);

final BusyBoxActionBuilder builder =
BusyBoxActionBuilder.create(AndroidDataContext.forNative(ruleContext), "GEN_BASE_CLASSES")
.addInput("--layoutInfoFiles", layoutInfo)
.addFlag("--package", AndroidCommon.getJavaPackage(ruleContext))
.addOutput("--classInfoOut", classInfoFile)
.addOutput("--sourceOut", srcOutFile)
.addFlag("--useDataBindingAndroidX", useAndroidX ? "true" : "false");

dependencyClassInfo
.toList()
.forEach(classInfo -> builder.addInput("--dependencyClassInfoList", classInfo));

builder.buildAndRegister(
"Generating databinding base classes", "GenerateDataBindingBaseClasses");

return ImmutableList.of(srcOutFile);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package com.google.devtools.build.android;

import android.databinding.AndroidDataBinding;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions;
import com.google.devtools.build.android.Converters.PathConverter;
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.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

public class GenerateDatabindingBaseClassesAction {

public static final class Options extends OptionsBase {
@Option(
name = "layoutInfoFiles",
defaultValue = "null",
converter = PathConverter.class,
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "Path to layout-info.zip file produced by databinding processor")
public Path layoutInfoFile;

@Option(
name = "package",
defaultValue = "null",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "Package name of the android target")
public String packageName;

@Option(
name = "classInfoOut",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
defaultValue = "null",
converter = PathConverter.class,
category = "output",
help = "Path to write classInfo.zip file")
public Path classInfoOut;

@Option(
name = "sourceOut",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
defaultValue = "null",
converter = PathConverter.class,
category = "output",
help = "Path to write databinding base classes to be used in Java compilation")
public Path sourceOut;

@Option(
name = "dependencyClassInfoList",
defaultValue = "null",
converter = PathConverter.class,
allowMultiple = true,
category = "input",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "List of dependency class info zip files")
public List<Path> dependencyClassInfoList;
}

static final Logger logger =
Logger.getLogger(GenerateDatabindingBaseClassesAction.class.getName());

public static void main(String[] args) throws Exception {
final OptionsParser optionsParser =
OptionsParser.builder()
.allowResidue(true)
.optionsClasses(
Options.class, AaptConfigOptions.class, ResourceProcessorCommonOptions.class)
.argsPreProcessor(new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()))
.build();
optionsParser.parseAndExitUponError(args);
final Options options = optionsParser.getOptions(Options.class);
final AaptConfigOptions aaptConfigOptions = optionsParser.getOptions(AaptConfigOptions.class);

if (options.layoutInfoFile == null) {
throw new IllegalArgumentException("--layoutInfoFiles is required");
}

if (options.packageName == null) {
throw new IllegalArgumentException("--packageName is required");
}

if (options.classInfoOut == null) {
throw new IllegalArgumentException("--classInfoOut is required");
}

if (options.sourceOut == null) {
throw new IllegalArgumentException("--sourceOut is required");
}

final List<Path> dependencyClassInfoList =
options.dependencyClassInfoList == null
? Collections.emptyList()
: options.dependencyClassInfoList;

final ImmutableList.Builder<String> dbArgsBuilder =
ImmutableList.<String>builder()
.add("GEN_BASE_CLASSES")
.add("-layoutInfoFiles")
.add(options.layoutInfoFile.toString())
.add("-package", options.packageName)
.add("-classInfoOut")
.add(options.classInfoOut.toString())
.add("-sourceOut")
.add(options.sourceOut.toString())
.add("-zipSourceOutput")
.add("true")
.add("-useAndroidX")
.add(Boolean.toString(aaptConfigOptions.useDataBindingAndroidX));

dependencyClassInfoList.forEach(
classInfo -> dbArgsBuilder.add("-dependencyClassInfoList").add(classInfo.toString()));

try {
AndroidDataBinding.main(
Streams.mapWithIndex(
dbArgsBuilder.build().stream(), (arg, index) -> index == 0 ? arg : arg + " ")
.toArray(String[]::new));
} catch (Exception e) {
logger.log(java.util.logging.Level.SEVERE, "Unexpected", e);
throw e;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ void call(String[] args) throws Exception {
void call(String[] args) throws Exception {
AndroidDataBindingProcessingAction.main(args);
}
},
GEN_BASE_CLASSES {
@Override
void call(String[] args) throws Exception {
GenerateDatabindingBaseClassesAction.main(args);
}
};

abstract void call(String[] args) throws Exception;
Expand Down

0 comments on commit c0edd1c

Please sign in to comment.