aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar asteinb <asteinb@google.com>2018-05-22 12:44:51 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-05-22 12:46:38 -0700
commitf6a858c59dad03c0618fd95bfff82076bf4a41f8 (patch)
treea7ff8d4092a36005fe4ed47abcb5441e575334a6 /src/main/java/com/google
parentd92688eec14040d9a381291bbb881a4b26a4d55d (diff)
Move non-resource busybox actions to BusyBoxActionBuilder and AndroidDataContext
BusyBoxActionBuilder makes much cleaner action builders while making it harder to do Bad Things (like collapsing NestedSets in analysis, or adding an artifact to one of the command line and the inputs but not both). Remaining action builders will be moved in the next change. Add old manifest merger tool to AndroidDataContext. RELNOTES: none PiperOrigin-RevId: 197607155
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java122
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataContext.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidSemantics.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java29
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java100
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java135
12 files changed, 151 insertions, 321 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java
index 351f66ddf5..c413ec92bb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java
@@ -15,18 +15,7 @@ package com.google.devtools.build.lib.rules.android;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.CommandLine;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-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.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.util.OS;
-import java.util.ArrayList;
-import java.util.List;
/** Builder for creating aar generator action. */
public class AarGeneratorBuilder {
@@ -42,19 +31,6 @@ public class AarGeneratorBuilder {
private Artifact aarOut;
private boolean throwOnResourceConflict;
- private final RuleContext ruleContext;
- private final SpawnAction.Builder builder;
-
- /**
- * Creates an {@link AarGeneratorBuilder}.
- *
- * @param ruleContext The {@link RuleContext} that is used to register the {@link Action}.
- */
- public AarGeneratorBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- this.builder = new SpawnAction.Builder();
- }
-
public AarGeneratorBuilder withPrimaryResources(AndroidResources primaryResources) {
this.primaryResources = primaryResources;
return this;
@@ -95,84 +71,32 @@ public class AarGeneratorBuilder {
return this;
}
- public void build(ActionConstructionContext context) {
- List<Artifact> outs = new ArrayList<>();
- List<Artifact> ins = new ArrayList<>();
- List<String> args = new ArrayList<>();
-
- // Set the busybox tool
- args.add("--tool");
- args.add("GENERATE_AAR");
- // Deliminate between the tool and the tool arguments.
- args.add("--");
-
- args.add("--mainData");
-
- Iterables.addAll(ins, primaryResources.getResources());
- Iterables.addAll(ins, primaryAssets.getAssets());
- ins.add(manifest);
-
- // no R.txt, because it will be generated from this action.
- args.add(
- String.format(
- "%s:%s:%s",
- AndroidDataConverter.rootsToString(primaryResources.getResourceRoots()),
- AndroidDataConverter.rootsToString(primaryAssets.getAssetRoots()),
- manifest.getExecPathString()));
-
- if (manifest != null) {
- args.add("--manifest");
- args.add(manifest.getExecPathString());
- ins.add(manifest);
- }
-
- if (rTxt != null) {
- args.add("--rtxt");
- args.add(rTxt.getExecPathString());
- ins.add(rTxt);
- }
-
- if (classes != null) {
- args.add("--classes");
- args.add(classes.getExecPathString());
- ins.add(classes);
- }
+ public void build(AndroidDataContext dataContext) {
+ BusyBoxActionBuilder builder =
+ BusyBoxActionBuilder.create(dataContext, "GENERATE_AAR")
+ // no R.txt, because it will be generated from this action.
+ .addInput(
+ "--mainData",
+ String.format(
+ "%s:%s:%s",
+ AndroidDataConverter.rootsToString(primaryResources.getResourceRoots()),
+ AndroidDataConverter.rootsToString(primaryAssets.getAssetRoots()),
+ manifest.getExecPathString()),
+ Iterables.concat(
+ primaryResources.getResources(),
+ primaryAssets.getAssets(),
+ ImmutableList.of(manifest)))
+ .addInput("--manifest", manifest)
+ .maybeAddInput("--rtxt", rTxt)
+ .maybeAddInput("--classes", classes);
for (Artifact proguardSpec : proguardSpecs) {
- args.add("--proguardSpec");
- args.add(proguardSpec.getExecPathString());
- ins.add(proguardSpec);
- }
-
- args.add("--aarOutput");
- args.add(aarOut.getExecPathString());
- outs.add(aarOut);
-
- if (throwOnResourceConflict) {
- args.add("--throwOnResourceConflict");
+ builder.addInput("--proguardSpec", proguardSpec);
}
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- ruleContext.registerAction(
- this.builder
- .useDefaultShellEnvironment()
- .addInputs(ImmutableList.<Artifact>copyOf(ins))
- .addOutputs(ImmutableList.<Artifact>copyOf(outs))
- .addCommandLine(CommandLine.of(args), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Building AAR package for %s", ruleContext.getLabel())
- .setMnemonic("AARGenerator")
- .build(context));
+ builder
+ .addOutput("--aarOutput", aarOut)
+ .maybeAddFlag("--throwOnResourceConflict", throwOnResourceConflict)
+ .buildAndRegister("Building AAR package", "AARGenerator");
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index ffaeb6fc58..0bc24677dd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -207,6 +207,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
AndroidManifest.fromAttributes(ruleContext, dataContext, androidSemantics)
.mergeWithDeps(
dataContext,
+ androidSemantics,
resourceDeps,
ApplicationManifest.getManifestValues(ruleContext),
ApplicationManifest.useLegacyMerging(ruleContext));
@@ -246,7 +247,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
applicationManifest =
androidSemantics
.getManifestForRule(ruleContext)
- .mergeWith(ruleContext, dataContext, resourceDeps);
+ .mergeWith(ruleContext, dataContext, androidSemantics, resourceDeps);
Artifact featureOfArtifact =
ruleContext.attributes().isAttributeValueExplicitlySpecified("feature_of")
@@ -902,7 +903,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
}
return Optional.of(
- new ResourceShrinkerActionBuilder(dataContext.getRuleContext())
+ new ResourceShrinkerActionBuilder()
.setResourceApkOut(
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_SHRUNK_APK))
.setShrunkResourcesOut(
@@ -918,7 +919,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
.setTargetAaptVersion(aaptVersion)
.setResourceFilterFactory(resourceFilterFactory)
.setUncompressedExtensions(noCompressExtensions)
- .build());
+ .build(dataContext));
}
@Immutable
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataContext.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataContext.java
index e4a489eefd..e894fbc2c9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataContext.java
@@ -42,6 +42,7 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
"Wraps common tools and settings used for working with Android assets, resources, and"
+ " manifests")
public class AndroidDataContext {
+
private final RuleContext ruleContext;
private final Label label;
@@ -50,6 +51,10 @@ public class AndroidDataContext {
private final AndroidSdkProvider sdk;
public static AndroidDataContext forNative(RuleContext ruleContext) {
+ return makeContext(ruleContext);
+ }
+
+ public static AndroidDataContext makeContext(RuleContext ruleContext) {
return new AndroidDataContext(
ruleContext,
ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java
index 5e3a6da7bc..5258d27128 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java
@@ -131,7 +131,7 @@ public class AndroidLibraryAarInfo extends NativeInfo {
Artifact aarOut =
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_LIBRARY_AAR);
- new AarGeneratorBuilder(dataContext.getRuleContext())
+ new AarGeneratorBuilder()
.withPrimaryResources(primaryResources)
.withPrimaryAssets(primaryAssets)
.withManifest(manifest.getManifest())
@@ -140,7 +140,7 @@ public class AndroidLibraryAarInfo extends NativeInfo {
.setAAROut(aarOut)
.setProguardSpecs(localProguardSpecs)
.setThrowOnResourceConflict(dataContext.getAndroidConfig().throwOnResourceConflict())
- .build(dataContext.getActionConstructionContext());
+ .build(dataContext);
return Aar.create(aarOut, manifest.getManifest());
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
index 5d4e3ee9ec..e32d12c1b2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
@@ -97,6 +97,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
resourceApk =
buildResourceApk(
dataContext,
+ androidSemantics,
AndroidManifest.fromAttributes(ruleContext, dataContext),
AndroidResources.from(ruleContext, "resource_files"),
AndroidAssets.from(ruleContext),
@@ -420,11 +421,15 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
AndroidResources.validateRuleContext(ruleContext);
ApplicationManifest ruleManifest =
ApplicationManifest.renamedFromRule(ruleContext, dataContext);
- applicationManifest = ruleManifest.mergeWith(ruleContext, dataContext, resourceDependencies);
+ applicationManifest =
+ ruleManifest.mergeWith(
+ ruleContext, dataContext, createAndroidSemantics(), resourceDependencies);
} else {
// we don't have a manifest, merge like android_library with a stub manifest
ApplicationManifest dummyManifest = ApplicationManifest.generatedManifest(ruleContext);
- applicationManifest = dummyManifest.mergeWith(ruleContext, dataContext, resourceDependencies);
+ applicationManifest =
+ dummyManifest.mergeWith(
+ ruleContext, dataContext, createAndroidSemantics(), resourceDependencies);
}
return applicationManifest;
}
@@ -545,6 +550,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
static ResourceApk buildResourceApk(
AndroidDataContext dataContext,
+ AndroidSemantics androidSemantics,
AndroidManifest manifest,
AndroidResources resources,
AndroidAssets assets,
@@ -556,7 +562,11 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
StampedAndroidManifest stamped =
manifest.mergeWithDeps(
- dataContext, resourceDeps, manifestValues, /* useLegacyMerger = */ false);
+ dataContext,
+ androidSemantics,
+ resourceDeps,
+ manifestValues,
+ /* useLegacyMerger = */ false);
return ProcessedAndroidData.processLocalTestDataFrom(
dataContext,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java
index 16920df0b0..4db8e3d959 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java
@@ -168,9 +168,10 @@ public class AndroidManifest {
* <p>If no manifest values are specified, the manifest will remain unstamped.
*/
public StampedAndroidManifest stampWithManifestValues(
- RuleContext ruleContext, AndroidDataContext dataContext) {
+ RuleContext ruleContext, AndroidDataContext dataContext, AndroidSemantics androidSemantics) {
return mergeWithDeps(
dataContext,
+ androidSemantics,
ResourceDependencies.empty(),
ApplicationManifest.getManifestValues(ruleContext),
ApplicationManifest.useLegacyMerging(ruleContext));
@@ -186,12 +187,19 @@ public class AndroidManifest {
*/
public StampedAndroidManifest mergeWithDeps(
AndroidDataContext dataContext,
+ AndroidSemantics androidSemantics,
ResourceDependencies resourceDeps,
Map<String, String> manifestValues,
boolean useLegacyMerger) {
Artifact newManifest =
ApplicationManifest.maybeMergeWith(
- dataContext, manifest, resourceDeps, manifestValues, useLegacyMerger, pkg)
+ dataContext,
+ androidSemantics,
+ manifest,
+ resourceDeps,
+ manifestValues,
+ useLegacyMerger,
+ pkg)
.orElse(manifest);
return new StampedAndroidManifest(newManifest, pkg, exported);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java
index 567ef49401..be6c9baf15 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java
@@ -15,6 +15,8 @@ package com.google.devtools.build.lib.rules.android;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+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.SpawnAction;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
@@ -30,6 +32,22 @@ public final class AndroidManifestMergeHelper {
Iterable<Artifact> mergees,
Collection<String> excludePermissions,
Artifact mergedManifest) {
+ createMergeManifestAction(
+ ruleContext,
+ ruleContext.getPrerequisite("$android_manifest_merge_tool", Mode.HOST),
+ merger,
+ mergees,
+ excludePermissions,
+ mergedManifest);
+ }
+
+ public static void createMergeManifestAction(
+ ActionConstructionContext context,
+ TransitiveInfoCollection manifestMerger,
+ Artifact merger,
+ Iterable<Artifact> mergees,
+ Collection<String> excludePermissions,
+ Artifact mergedManifest) {
CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
commandLine.addPrefixedExecPath("--merger=", merger);
for (Artifact mergee : mergees) {
@@ -42,15 +60,15 @@ public final class AndroidManifestMergeHelper {
commandLine.addPrefixedExecPath("--output=", mergedManifest);
- ruleContext.registerAction(
+ context.registerAction(
new SpawnAction.Builder()
.addInput(merger)
.addInputs(mergees)
.addOutput(mergedManifest)
- .setExecutable(ruleContext.getPrerequisite("$android_manifest_merge_tool", Mode.HOST))
+ .setExecutable(manifestMerger)
.setProgressMessage("Merging Android Manifests")
.setMnemonic("AndroidManifestMerger")
.addCommandLine(commandLine.build())
- .build(ruleContext));
+ .build(context));
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSemantics.java
index a1b33d6601..3fee62ed6b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSemantics.java
@@ -18,12 +18,15 @@ 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.SpawnAction;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.java.JavaCompilationArtifacts;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.rules.java.JavaTargetAttributes;
import com.google.devtools.build.lib.rules.java.ProguardHelper.ProguardOutput;
+import java.util.Map;
+import java.util.Optional;
/**
* Pluggable semantics for Android rules.
@@ -49,6 +52,17 @@ public interface AndroidSemantics {
return ApplicationManifest.renameManifestIfNeeded(dataContext, rawManifest);
}
+ default Optional<Artifact> maybeDoLegacyManifestMerging(
+ Map<Artifact, Label> mergeeManifests,
+ AndroidDataContext dataContext,
+ Artifact primaryManifest) {
+ if (mergeeManifests.isEmpty()) {
+ return Optional.empty();
+ }
+
+ throw new UnsupportedOperationException();
+ }
+
/** Returns the name of the file in which the file names of native dependencies are listed. */
String getNativeDepsFileName();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
index c89d3c9a8e..38f70d4ce6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
@@ -853,6 +853,7 @@ public abstract class AndroidSkylarkData {
ResourceApk resourceApk =
AndroidLocalTestBase.buildResourceApk(
ctx,
+ getAndroidSemantics(),
rawManifest,
AndroidResources.from(errorReporter, getFileProviders(resources), "resource_files"),
AndroidAssets.from(
@@ -1157,6 +1158,7 @@ public abstract class AndroidSkylarkData {
StampedAndroidManifest stampedManifest =
rawManifest.mergeWithDeps(
ctx,
+ getAndroidSemantics(),
resourceDeps,
manifestValues,
ApplicationManifest.useLegacyMerging(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
index b7662c02e4..900f1056a9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
@@ -247,9 +247,13 @@ public final class ApplicationManifest {
}
public ApplicationManifest mergeWith(
- RuleContext ruleContext, AndroidDataContext dataContext, ResourceDependencies resourceDeps) {
+ RuleContext ruleContext,
+ AndroidDataContext dataContext,
+ AndroidSemantics androidSemantics,
+ ResourceDependencies resourceDeps) {
return maybeMergeWith(
dataContext,
+ androidSemantics,
manifest,
resourceDeps,
manifestValues,
@@ -261,6 +265,7 @@ public final class ApplicationManifest {
static Optional<Artifact> maybeMergeWith(
AndroidDataContext dataContext,
+ AndroidSemantics androidSemantics,
Artifact primaryManifest,
ResourceDependencies resourceDeps,
Map<String, String> manifestValues,
@@ -269,25 +274,15 @@ public final class ApplicationManifest {
Map<Artifact, Label> mergeeManifests = getMergeeManifests(resourceDeps.getResourceContainers());
if (useLegacyMerging) {
- if (!mergeeManifests.isEmpty()) {
-
- Artifact outputManifest =
- dataContext.getUniqueDirectoryArtifact("_merged", "AndroidManifest.xml");
- AndroidManifestMergeHelper.createMergeManifestAction(
- dataContext.getRuleContext(),
- primaryManifest,
- mergeeManifests.keySet(),
- ImmutableList.of("all"),
- outputManifest);
- return Optional.of(outputManifest);
- }
+ return androidSemantics.maybeDoLegacyManifestMerging(
+ mergeeManifests, dataContext, primaryManifest);
} else {
if (!mergeeManifests.isEmpty() || !manifestValues.isEmpty()) {
Artifact outputManifest =
dataContext.getUniqueDirectoryArtifact("_merged", "AndroidManifest.xml");
Artifact mergeLog =
dataContext.getUniqueDirectoryArtifact("_merged", "manifest_merger_log.txt");
- new ManifestMergerActionBuilder(dataContext.getRuleContext())
+ new ManifestMergerActionBuilder()
.setManifest(primaryManifest)
.setMergeeManifests(mergeeManifests)
.setLibrary(false)
@@ -295,7 +290,7 @@ public final class ApplicationManifest {
.setCustomPackage(customPackage)
.setManifestOutput(outputManifest)
.setLogOut(mergeLog)
- .build(dataContext.getActionConstructionContext());
+ .build(dataContext);
return Optional.of(outputManifest);
}
}
@@ -363,12 +358,12 @@ public final class ApplicationManifest {
}
Artifact outputManifest =
dataContext.getUniqueDirectoryArtifact("_renamed", "AndroidManifest.xml");
- new ManifestMergerActionBuilder(dataContext.getRuleContext())
+ new ManifestMergerActionBuilder()
.setManifest(manifest)
.setLibrary(true)
.setCustomPackage(customPackage)
.setManifestOutput(outputManifest)
- .build(dataContext.getActionConstructionContext());
+ .build(dataContext);
return Optional.of(outputManifest);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java
index 860b129487..29a92f1e42 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java
@@ -15,26 +15,14 @@ package com.google.devtools.build.lib.rules.android;
import com.google.common.base.Function;
import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-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.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.util.OS;
import java.util.Iterator;
import java.util.Map;
/** Builder for creating manifest merger actions. */
public class ManifestMergerActionBuilder {
- private final RuleContext ruleContext;
- private final SpawnAction.Builder spawnActionBuilder;
private Artifact manifest;
private Map<Artifact, Label> mergeeManifests;
@@ -44,11 +32,6 @@ public class ManifestMergerActionBuilder {
private Artifact manifestOutput;
private Artifact logOut;
- public ManifestMergerActionBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- this.spawnActionBuilder = new SpawnAction.Builder();
- }
-
public ManifestMergerActionBuilder setManifest(Artifact manifest) {
this.manifest = manifest;
return this;
@@ -84,75 +67,27 @@ public class ManifestMergerActionBuilder {
return this;
}
- public void build(ActionConstructionContext context) {
- NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
- ImmutableList.Builder<Artifact> outputs = ImmutableList.builder();
- CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
-
- // Set the busybox tool.
- builder.add("--tool").add("MERGE_MANIFEST").add("--");
-
- inputs.addAll(
- ruleContext
- .getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)
- .getRunfilesSupport()
- .getRunfilesArtifacts());
+ public void build(AndroidDataContext dataContext) {
+ BusyBoxActionBuilder builder =
+ BusyBoxActionBuilder.create(dataContext, "MERGE_MANIFEST")
+ .maybeAddInput("--manifest", manifest);
- if (manifest != null) {
- builder.addExecPath("--manifest", manifest);
- inputs.add(manifest);
- }
-
- if (mergeeManifests != null && !mergeeManifests.isEmpty()) {
- builder.add(
+ if (mergeeManifests != null) {
+ builder.maybeAddInput(
"--mergeeManifests",
mapToDictionaryString(
- mergeeManifests, Artifact::getExecPathString, /* valueConverter= */ null));
- inputs.addAll(mergeeManifests.keySet());
- }
-
- if (isLibrary) {
- builder.add("--mergeType").add("LIBRARY");
+ mergeeManifests, Artifact::getExecPathString, /* valueConverter = */ null),
+ mergeeManifests.keySet());
}
- if (manifestValues != null && !manifestValues.isEmpty()) {
- builder.add("--manifestValues", mapToDictionaryString(manifestValues));
- }
-
- if (customPackage != null && !customPackage.isEmpty()) {
- builder.add("--customPackage", customPackage);
- }
-
- builder.addExecPath("--manifestOutput", manifestOutput);
- outputs.add(manifestOutput);
-
- if (logOut != null) {
- builder.addExecPath("--log", logOut);
- outputs.add(logOut);
- }
-
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- ruleContext.registerAction(
- this.spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTransitiveInputs(inputs.build())
- .addOutputs(outputs.build())
- .addCommandLine(builder.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Merging manifest for %s", ruleContext.getLabel())
- .setMnemonic("ManifestMerger")
- .build(context));
+ builder
+ .maybeAddFlag("--mergeType", isLibrary)
+ .maybeAddFlag("LIBRARY", isLibrary)
+ .maybeAddFlag("--manifestValues", mapToDictionaryString(manifestValues))
+ .maybeAddFlag("--customPackage", customPackage)
+ .addOutput("--manifestOutput", manifestOutput)
+ .maybeAddOutput("--log", logOut)
+ .buildAndRegister("Merging manifest", "ManifestMerger");
}
private static final Function<String, String> ESCAPER =
@@ -166,6 +101,9 @@ public class ManifestMergerActionBuilder {
Map<K, V> map,
Function<? super K, String> keyConverter,
Function<? super V, String> valueConverter) {
+ if (map == null) {
+ return null;
+ }
if (keyConverter == null) {
keyConverter = Functions.toStringFunction();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java
index 4e6c395287..f5861a72c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java
@@ -17,17 +17,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.analysis.FilesToRunProvider;
-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.config.CompilationMode;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
-import com.google.devtools.build.lib.util.OS;
import java.util.Collections;
import java.util.List;
@@ -43,20 +33,8 @@ public class ResourceShrinkerActionBuilder {
private Artifact shrunkResourcesOut;
private Artifact logOut;
- private final RuleContext ruleContext;
- private final SpawnAction.Builder spawnActionBuilder;
- private final AndroidSdkProvider sdk;
-
private List<String> uncompressedExtensions = Collections.emptyList();
- private ResourceFilterFactory resourceFilterFactory;
-
- /** @param ruleContext The RuleContext of the owning rule. */
- public ResourceShrinkerActionBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- this.spawnActionBuilder = new SpawnAction.Builder();
- this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
- this.resourceFilterFactory = ResourceFilterFactory.empty();
- }
+ private ResourceFilterFactory resourceFilterFactory = ResourceFilterFactory.empty();
public ResourceShrinkerActionBuilder setUncompressedExtensions(
List<String> uncompressedExtensions) {
@@ -131,38 +109,7 @@ public class ResourceShrinkerActionBuilder {
return this;
}
- public Artifact build() {
- ImmutableList.Builder<Artifact> inputs = ImmutableList.builder();
- ImmutableList.Builder<Artifact> outputs = ImmutableList.builder();
-
- CustomCommandLine.Builder commandLine = new CustomCommandLine.Builder();
-
- // Set the busybox tool.
- FilesToRunProvider aapt;
-
- if (targetAaptVersion == AndroidAaptVersion.AAPT2) {
- aapt = sdk.getAapt2();
- commandLine.add("--tool").add("SHRINK_AAPT2").add("--");
- commandLine.addExecPath("--aapt2", aapt.getExecutable());
- } else {
- aapt = sdk.getAapt();
- commandLine.add("--tool").add("SHRINK").add("--");
- commandLine.addExecPath("--aapt", aapt.getExecutable());
- }
-
- commandLine.addExecPath("--androidJar", sdk.getAndroidJar());
- inputs.add(sdk.getAndroidJar());
-
- if (!uncompressedExtensions.isEmpty()) {
- commandLine.addAll(
- "--uncompressedExtensions", VectorArg.join(",").each(uncompressedExtensions));
- }
- if (ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT) {
- commandLine.add("--debug");
- }
- if (resourceFilterFactory.hasConfigurationFilters()) {
- commandLine.add("--resourceConfigs", resourceFilterFactory.getConfigurationFilterString());
- }
+ public Artifact build(AndroidDataContext dataContext) {
checkNotNull(resourceFilesZip);
checkNotNull(shrunkJar);
@@ -172,63 +119,31 @@ public class ResourceShrinkerActionBuilder {
checkNotNull(primaryResources.getManifest());
checkNotNull(resourceApkOut);
- commandLine.addExecPath("--resources", resourceFilesZip);
- inputs.add(resourceFilesZip);
-
- commandLine.addExecPath("--shrunkJar", shrunkJar);
- inputs.add(shrunkJar);
-
- commandLine.addExecPath("--proguardMapping", proguardMapping);
- inputs.add(proguardMapping);
-
- commandLine.addExecPath("--rTxt", primaryResources.getRTxt());
- inputs.add(primaryResources.getRTxt());
-
- commandLine.addExecPath("--primaryManifest", primaryResources.getManifest());
- inputs.add(primaryResources.getManifest());
-
- ImmutableList<Artifact> dependencyManifests = getManifests(dependencyResources);
- if (!dependencyManifests.isEmpty()) {
- commandLine.addExecPaths("--dependencyManifest", dependencyManifests);
- inputs.addAll(dependencyManifests);
+ BusyBoxActionBuilder builder;
+ if (targetAaptVersion == AndroidAaptVersion.AAPT2) {
+ builder = BusyBoxActionBuilder.create(dataContext, "SHRINK_AAPT2");
+ } else {
+ builder = BusyBoxActionBuilder.create(dataContext, "SHRINK");
}
- ImmutableList<String> resourcePackages =
- getResourcePackages(primaryResources, dependencyResources);
- commandLine.addAll("--resourcePackages", VectorArg.join(",").each(resourcePackages));
-
- commandLine.addExecPath("--shrunkResourceApk", resourceApkOut);
- outputs.add(resourceApkOut);
-
- commandLine.addExecPath("--shrunkResources", shrunkResourcesOut);
- outputs.add(shrunkResourcesOut);
-
- commandLine.addExecPath("--log", logOut);
- outputs.add(logOut);
-
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- ruleContext.registerAction(
- spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTool(aapt)
- .addInputs(inputs.build())
- .addOutputs(outputs.build())
- .addCommandLine(commandLine.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Shrinking resources for %s", ruleContext.getLabel())
- .setMnemonic("ResourceShrinker")
- .build(ruleContext));
+ builder
+ .addAapt(targetAaptVersion)
+ .addAndroidJar()
+ .maybeAddVectoredFlag("--uncompressedExtensions", uncompressedExtensions)
+ .maybeAddFlag("--debug", dataContext.useDebug())
+ .maybeAddFlag("--resourceConfigs", resourceFilterFactory.getConfigurationFilterString())
+ .addInput("--resources", resourceFilesZip)
+ .addInput("--shrunkJar", shrunkJar)
+ .addInput("--proguardMapping", proguardMapping)
+ .addInput("--rTxt", primaryResources.getRTxt())
+ .addInput("--primaryManifest", primaryResources.getManifest())
+ .maybeAddInput("--dependencyManifest", getManifests(dependencyResources))
+ .addVectoredFlag(
+ "--resourcePackages", getResourcePackages(primaryResources, dependencyResources))
+ .addOutput("--shrunkResourceApk", resourceApkOut)
+ .addOutput("--shrunkResources", shrunkResourcesOut)
+ .addOutput("--log", logOut)
+ .buildAndRegister("Shrinking resources", "ResourceShrinker");
return resourceApkOut;
}