aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestInfo.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java75
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java35
6 files changed, 118 insertions, 21 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestInfo.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestInfo.java
index 1e44f46ab4..bdd182d9c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestInfo.java
@@ -98,4 +98,8 @@ public class AndroidManifestInfo extends NativeInfo {
public boolean exportsManifest() {
return exportsManifest;
}
+
+ public StampedAndroidManifest asStampedManifest() {
+ return new StampedAndroidManifest(manifest, pkg, exportsManifest);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java
index e48bf0d9ff..d548ddbcdf 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java
@@ -131,10 +131,18 @@ public class AndroidResources {
return empty();
}
- ImmutableList<Artifact> resources =
- getResources(ruleContext.getPrerequisites(resourcesAttr, Mode.TARGET, FileProvider.class));
+ return from(
+ ruleContext,
+ ruleContext.getPrerequisites(resourcesAttr, Mode.TARGET, FileProvider.class),
+ resourcesAttr);
+ }
- return forResources(ruleContext, resources, resourcesAttr);
+ static AndroidResources from(
+ RuleErrorConsumer errorConsumer,
+ Iterable<FileProvider> resourcesTargets,
+ String resourcesAttr)
+ throws RuleErrorException {
+ return forResources(errorConsumer, getResources(resourcesTargets), resourcesAttr);
}
/** Returns an {@link AndroidResources} for a list of resource artifacts. */
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 b4e3508489..66b0602774 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
@@ -13,8 +13,10 @@
// 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.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
@@ -26,6 +28,7 @@ import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nullable;
/** Skylark-visible methods for working with Android data (manifests, resources, and assets). */
@@ -177,6 +180,78 @@ public class AndroidSkylarkData {
}
}
+ /**
+ * Skylark API for merging android_library resources
+ *
+ * <p>TODO(b/79159379): Stop passing SkylarkRuleContext here
+ *
+ * @param ctx the SkylarkRuleContext. We will soon change to using an ActionConstructionContext
+ * instead. See b/79159379
+ */
+ @SkylarkCallable(
+ name = "merge_resources",
+ mandatoryPositionals = 2, // context, manifest
+ parameters = {
+ @Param(
+ name = "resources",
+ positional = false,
+ defaultValue = "[]",
+ type = SkylarkList.class,
+ generic1 = FileProvider.class,
+ named = true,
+ doc = "Providers of this target's resources"),
+ @Param(
+ name = "deps",
+ positional = false,
+ defaultValue = "[]",
+ type = SkylarkList.class,
+ generic1 = AndroidResourcesInfo.class,
+ named = true,
+ doc =
+ "Targets containing raw resources from dependencies. These resources will be merged"
+ + " together with each other and this target's resources."),
+ @Param(
+ name = "neverlink",
+ positional = false,
+ defaultValue = "False",
+ type = Boolean.class,
+ named = true,
+ doc =
+ "Defaults to False. If passed as True, these resources will not be inherited by"
+ + " targets that depend on this one."),
+ },
+ doc =
+ "Merges this target's resources together with resources inherited from dependencies. The"
+ + " passed manifest provider is used to get Android package information and to"
+ + " validate that all resources it refers to are available. Note that this method"
+ + " might do additional processing to this manifest, so in the future, you may want"
+ + " to use the manifest contained in this method's output instead of this one.")
+ public AndroidResourcesInfo mergeResources(
+ SkylarkRuleContext ctx,
+ AndroidManifestInfo manifest,
+ SkylarkList<ConfiguredTarget> resources,
+ SkylarkList<AndroidResourcesInfo> deps,
+ boolean neverlink)
+ throws EvalException, InterruptedException {
+
+ ImmutableList<FileProvider> fileProviders =
+ resources
+ .stream()
+ .map(target -> target.getProvider(FileProvider.class))
+ .filter(Objects::nonNull)
+ .collect(ImmutableList.toImmutableList());
+
+ try {
+ return AndroidResources.from(ctx.getRuleContext(), fileProviders, "resources")
+ .parse(ctx.getRuleContext(), manifest.asStampedManifest())
+ .merge(ctx.getRuleContext(), ResourceDependencies.fromProviders(deps, neverlink))
+ .validate(ctx.getRuleContext())
+ .toProvider();
+ } catch (RuleErrorException e) {
+ throw new EvalException(Location.BUILTIN, e);
+ }
+ }
+
/** Checks if a "Noneable" object passed by Skylark is "None", which Java should treat as null. */
private static boolean isNone(Object object) {
return object == Runtime.NONE;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java
index 07c274ac81..70ed4dfb9b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java
@@ -38,7 +38,7 @@ public class MergedAndroidResources extends ParsedAndroidResources {
private final ProcessedAndroidManifest manifest;
public static MergedAndroidResources mergeFrom(
- RuleContext ruleContext, ParsedAndroidResources parsed, boolean neverlink)
+ RuleContext ruleContext, ParsedAndroidResources parsed, ResourceDependencies resourceDeps)
throws InterruptedException, RuleErrorException {
AndroidConfiguration androidConfiguration = AndroidCommon.getAndroidConfig(ruleContext);
@@ -54,7 +54,7 @@ public class MergedAndroidResources extends ParsedAndroidResources {
AndroidResourceMergingActionBuilder builder =
new AndroidResourceMergingActionBuilder(ruleContext)
.setJavaPackage(parsed.getJavaPackage())
- .withDependencies(ResourceDependencies.fromRuleDeps(ruleContext, neverlink))
+ .withDependencies(resourceDeps)
.setThrowOnResourceConflict(androidConfiguration.throwOnResourceConflict())
.setUseCompiledMerge(useCompiledMerge);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
index 44b08e07ae..eddaa71b25 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
@@ -125,7 +125,12 @@ public class ParsedAndroidResources extends AndroidResources
/** Merges this target's resources with resources from dependencies. */
public MergedAndroidResources merge(RuleContext ruleContext, boolean neverlink)
throws InterruptedException, RuleErrorException {
- return MergedAndroidResources.mergeFrom(ruleContext, this, neverlink);
+ return merge(ruleContext, ResourceDependencies.fromRuleDeps(ruleContext, neverlink));
+ }
+
+ MergedAndroidResources merge(RuleContext ruleContext, ResourceDependencies resourceDeps)
+ throws InterruptedException, RuleErrorException {
+ return MergedAndroidResources.mergeFrom(ruleContext, this, resourceDeps);
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java
index 43b8ba0345..45f559eb85 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java
@@ -90,10 +90,17 @@ public final class ResourceDependencies {
private final boolean neverlink;
public static ResourceDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) {
+ return fromProviders(
+ AndroidCommon.getTransitivePrerequisites(
+ ruleContext, Mode.TARGET, AndroidResourcesInfo.PROVIDER),
+ neverlink);
+ }
+
+ public static ResourceDependencies fromProviders(
+ Iterable<AndroidResourcesInfo> providers, boolean neverlink) {
NestedSetBuilder<ValidatedAndroidData> transitiveDependencies =
NestedSetBuilder.naiveLinkOrder();
- NestedSetBuilder<ValidatedAndroidData> directDependencies =
- NestedSetBuilder.naiveLinkOrder();
+ NestedSetBuilder<ValidatedAndroidData> directDependencies = NestedSetBuilder.naiveLinkOrder();
NestedSetBuilder<Artifact> transitiveResources = NestedSetBuilder.naiveLinkOrder();
NestedSetBuilder<Artifact> transitiveAssets = NestedSetBuilder.naiveLinkOrder();
NestedSetBuilder<Artifact> transitiveManifests = NestedSetBuilder.naiveLinkOrder();
@@ -103,19 +110,17 @@ public final class ResourceDependencies {
NestedSetBuilder<Artifact> transitiveStaticLib = NestedSetBuilder.naiveLinkOrder();
NestedSetBuilder<Artifact> transitiveRTxt = NestedSetBuilder.naiveLinkOrder();
- for (AndroidResourcesInfo resources :
- AndroidCommon.getTransitivePrerequisites(
- ruleContext, Mode.TARGET, AndroidResourcesInfo.PROVIDER)) {
- transitiveDependencies.addTransitive(resources.getTransitiveAndroidResources());
- directDependencies.addTransitive(resources.getDirectAndroidResources());
- transitiveResources.addTransitive(resources.getTransitiveResources());
- transitiveAssets.addTransitive(resources.getTransitiveAssets());
- transitiveManifests.addTransitive(resources.getTransitiveManifests());
- transitiveAapt2RTxt.addTransitive(resources.getTransitiveAapt2RTxt());
- transitiveSymbolsBin.addTransitive(resources.getTransitiveSymbolsBin());
- transitiveCompiledSymbols.addTransitive(resources.getTransitiveCompiledSymbols());
- transitiveStaticLib.addTransitive(resources.getTransitiveStaticLib());
- transitiveRTxt.addTransitive(resources.getTransitiveRTxt());
+ for (AndroidResourcesInfo resources : providers) {
+ transitiveDependencies.addTransitive(resources.getTransitiveAndroidResources());
+ directDependencies.addTransitive(resources.getDirectAndroidResources());
+ transitiveResources.addTransitive(resources.getTransitiveResources());
+ transitiveAssets.addTransitive(resources.getTransitiveAssets());
+ transitiveManifests.addTransitive(resources.getTransitiveManifests());
+ transitiveAapt2RTxt.addTransitive(resources.getTransitiveAapt2RTxt());
+ transitiveSymbolsBin.addTransitive(resources.getTransitiveSymbolsBin());
+ transitiveCompiledSymbols.addTransitive(resources.getTransitiveCompiledSymbols());
+ transitiveStaticLib.addTransitive(resources.getTransitiveStaticLib());
+ transitiveRTxt.addTransitive(resources.getTransitiveRTxt());
}
return new ResourceDependencies(