diff options
author | asteinb <asteinb@google.com> | 2018-05-03 10:43:47 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-05-03 10:45:39 -0700 |
commit | 4a2845c3051915ed5aa1cb3a977f987a1a3b95ed (patch) | |
tree | b9b40627e581db8c61edf08dbc397172f9a233c5 /src/main/java/com/google | |
parent | 3851667a8454d891eb031c00fe6d07244b6e606d (diff) |
Expose intial parts of resource merging to Skylark
RELNOTES: none
PiperOrigin-RevId: 195274968
Diffstat (limited to 'src/main/java/com/google')
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( |