Update Android Starlark APIs.
- Clean up processLibraryData, unused by Starlark android_library.
- Split out the resource merge parts of mergeResources into its own method,
mergeRes, because the Starlark android_library requires direct access to the
ValidatedAndroidResources to pull the resources apk. This is to replicate
the behavior of the native legacy android provider (b/130978748).
- Add the ability to access the R.jar from the ValidatedAndroidData enabling
the deletion of the mergeResources API in a follow up release.
PiperOrigin-RevId: 244710315
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 83600b4..c44b68d 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
@@ -153,7 +153,7 @@
}
@Override
- public SkylarkDict<Provider, NativeInfo> mergeResources(
+ public ValidatedAndroidResources mergeRes(
AndroidDataContext ctx,
AndroidManifestInfo manifest,
SkylarkList<ConfiguredTarget> resources,
@@ -167,35 +167,43 @@
SkylarkErrorReporter.from(ctx.getActionConstructionContext(), location, env)) {
AndroidAaptVersion aaptVersion =
ctx.getSdk().getAapt2() != null ? AndroidAaptVersion.AAPT2 : AndroidAaptVersion.AAPT;
-
- ValidatedAndroidResources validated =
- AndroidResources.from(errorReporter, getFileProviders(resources), "resources")
- .process(
- ctx,
- manifest.asStampedManifest(),
- ResourceDependencies.fromProviders(deps, neverlink),
- DataBinding.contextFrom(
- enableDataBinding,
- ctx.getActionConstructionContext(),
- ctx.getAndroidConfig()),
- aaptVersion);
-
- JavaInfo javaInfo =
- getJavaInfoForRClassJar(validated.getClassJar(), validated.getJavaSourceJar());
-
- return SkylarkDict.of(
- /* env = */ null,
- AndroidResourcesInfo.PROVIDER,
- validated.toProvider(),
- JavaInfo.PROVIDER,
- javaInfo);
-
+ return AndroidResources.from(errorReporter, getFileProviders(resources), "resources")
+ .process(
+ ctx,
+ manifest.asStampedManifest(),
+ ResourceDependencies.fromProviders(deps, neverlink),
+ DataBinding.contextFrom(
+ enableDataBinding, ctx.getActionConstructionContext(), ctx.getAndroidConfig()),
+ aaptVersion);
} catch (RuleErrorException e) {
throw new EvalException(Location.BUILTIN, e);
}
}
@Override
+ public SkylarkDict<Provider, NativeInfo> mergeResources(
+ AndroidDataContext ctx,
+ AndroidManifestInfo manifest,
+ SkylarkList<ConfiguredTarget> resources,
+ SkylarkList<AndroidResourcesInfo> deps,
+ boolean neverlink,
+ boolean enableDataBinding,
+ Location location,
+ Environment env)
+ throws EvalException, InterruptedException {
+ ValidatedAndroidResources validated =
+ mergeRes(ctx, manifest, resources, deps, neverlink, enableDataBinding, location, env);
+ JavaInfo javaInfo =
+ getJavaInfoForRClassJar(validated.getClassJar(), validated.getJavaSourceJar());
+ return SkylarkDict.of(
+ /* env = */ null,
+ AndroidResourcesInfo.PROVIDER,
+ validated.toProvider(),
+ JavaInfo.PROVIDER,
+ javaInfo);
+ }
+
+ @Override
public AndroidLibraryAarInfo makeAar(
AndroidDataContext ctx,
AndroidResourcesInfo resourcesInfo,
@@ -263,100 +271,6 @@
}
@Override
- public SkylarkDict<Provider, NativeInfo> processLibraryData(
- AndroidDataContext ctx,
- Artifact libraryClassJar,
- Object manifest,
- Object resources,
- Object assets,
- Object assetsDir,
- Object exportsManifest,
- Object customPackage,
- boolean neverlink,
- boolean enableDataBinding,
- SkylarkList<Artifact> localProguardSpecs,
- SkylarkList<ConfiguredTarget> deps,
- Location location,
- Environment env)
- throws InterruptedException, EvalException {
-
- SkylarkList<AndroidResourcesInfo> resourceDeps =
- getProviders(deps, AndroidResourcesInfo.PROVIDER);
- SkylarkList<AndroidAssetsInfo> assetDeps = getProviders(deps, AndroidAssetsInfo.PROVIDER);
-
- ImmutableMap.Builder<Provider, NativeInfo> infoBuilder = ImmutableMap.builder();
-
- AndroidResourcesInfo resourcesInfo;
- AndroidAssetsInfo assetsInfo;
- if (isNone(manifest)
- && isNone(resources)
- && isNone(assets)
- && isNone(assetsDir)
- && isNone(exportsManifest)) {
-
- // If none of these parameters were specified, for backwards compatibility, do not trigger
- // data processing.
- resourcesInfo = resourcesFromDeps(ctx, resourceDeps, neverlink, customPackage, location, env);
- assetsInfo = assetsFromDeps(assetDeps, neverlink, env);
-
- infoBuilder.put(AndroidResourcesInfo.PROVIDER, resourcesInfo);
- } else {
-
- AndroidManifestInfo baseManifest =
- stampAndroidManifest(
- ctx,
- manifest,
- customPackage,
- fromNoneableOrDefault(exportsManifest, Boolean.class, false),
- location,
- env);
-
- SkylarkDict<Provider, NativeInfo> resourceOutput =
- mergeResources(
- ctx,
- baseManifest,
- listFromNoneableOrEmpty(resources, ConfiguredTarget.class),
- resourceDeps,
- neverlink,
- enableDataBinding,
- location,
- env);
-
- resourcesInfo = (AndroidResourcesInfo) resourceOutput.get(AndroidResourcesInfo.PROVIDER);
- assetsInfo = mergeAssets(ctx, assets, assetsDir, assetDeps, neverlink, location, env);
-
- infoBuilder.putAll(resourceOutput);
- }
-
- AndroidLibraryAarInfo aarInfo =
- makeAar(
- ctx,
- resourcesInfo,
- assetsInfo,
- libraryClassJar,
- localProguardSpecs,
- getProviders(deps, AndroidLibraryAarInfo.PROVIDER),
- neverlink);
-
- // Only expose the aar provider in non-neverlinked actions
- if (!neverlink) {
- infoBuilder.put(AndroidLibraryAarInfo.PROVIDER, aarInfo);
- }
-
- // Expose the updated manifest that was changed by resource processing
- // TODO(b/30817309): Use the base manifest once manifests are no longer changed in resource
- // processing
- AndroidManifestInfo manifestInfo = resourcesInfo.getManifest();
-
- return SkylarkDict.copyOf(
- /* env = */ null,
- infoBuilder
- .put(AndroidAssetsInfo.PROVIDER, assetsInfo)
- .put(AndroidManifestInfo.PROVIDER, manifestInfo)
- .build());
- }
-
- @Override
public SkylarkDict<Provider, NativeInfo> processAarImportData(
AndroidDataContext ctx,
SpecialArtifact resources,
@@ -806,14 +720,4 @@
.filter(Objects::nonNull)
.collect(ImmutableList.toImmutableList()));
}
-
- private static <T> SkylarkList<T> listFromNoneableOrEmpty(Object object, Class<T> clazz)
- throws EvalException {
- List<T> value = listFromNoneable(object, clazz);
- if (value == null) {
- return SkylarkList.createImmutable(ImmutableList.of());
- }
-
- return SkylarkList.createImmutable(value);
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
index def9acc..ca7faea 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
@@ -25,7 +25,7 @@
/** Wraps validated and packaged Android resource information */
public class ValidatedAndroidResources extends MergedAndroidResources
- implements ValidatedAndroidDataApi<Artifact> {
+ implements ValidatedAndroidDataApi<Artifact, AndroidResourcesInfo> {
private final Artifact rTxt;
private final Artifact sourceJar;
private final Artifact apk;
@@ -116,6 +116,7 @@
this.staticLibrary = staticLibrary;
}
+ @Override
public AndroidResourcesInfo toProvider() {
return getResourceDependencies().toInfo(this);
}
@@ -126,6 +127,11 @@
}
@Override
+ public Artifact getJavaClassJar() {
+ return super.getClassJar();
+ }
+
+ @Override
public Artifact getJavaSourceJar() {
return sourceJar;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/AndroidDataProcessingApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/AndroidDataProcessingApi.java
index 87cfbb8..78f6b52 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/AndroidDataProcessingApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/AndroidDataProcessingApi.java
@@ -26,6 +26,7 @@
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
/** Skylark-visible methods for working with Android data (manifests, resources, and assets). */
@SkylarkModule(
@@ -257,6 +258,84 @@
throws EvalException, InterruptedException;
@SkylarkCallable(
+ name = "merge_res",
+ parameters = {
+ @Param(
+ name = "ctx",
+ positional = true,
+ named = false,
+ type = AndroidDataContextApi.class,
+ doc = "The Android data context object for this target."),
+ @Param(
+ name = "manifest",
+ positional = true,
+ named = false,
+ type = AndroidManifestInfoApi.class,
+ doc =
+ "The provider of this target's manifest. This provider is produced by, "
+ + "for example, stamp_android_manifest."),
+ @Param(
+ name = "resources",
+ positional = false,
+ defaultValue = "[]",
+ type = SkylarkList.class,
+ generic1 = FileProviderApi.class,
+ named = true,
+ doc = "Providers of this target's resources."),
+ @Param(
+ name = "deps",
+ positional = false,
+ defaultValue = "[]",
+ type = SkylarkList.class,
+ generic1 = AndroidResourcesInfoApi.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."),
+ @Param(
+ name = "enable_data_binding",
+ positional = false,
+ defaultValue = "False",
+ type = Boolean.class,
+ named = true,
+ doc =
+ "Defaults to False. If True, processes data binding expressions in layout"
+ + " resources."),
+ },
+ useLocation = true,
+ useEnvironment = true,
+ doc =
+ "Merges this target's resources together with resources inherited from dependencies."
+ + " Returns a dict of provider type to actual info, with elements for"
+ + " AndroidResourcesInfoApi (various resource information) and JavaInfoApi (wrapping"
+ + " the R.class jar, for use in Java compilation). 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.",
+ documented = false,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ENABLE_ANDROID_MIGRATION_APIS)
+ ValidatedAndroidDataT mergeRes(
+ AndroidDataContextT ctx,
+ AndroidManifestInfoT manifest,
+ SkylarkList<TransitiveInfoCollectionT> resources,
+ SkylarkList<AndroidResourcesInfoT> deps,
+ boolean neverlink,
+ boolean enableDataBinding,
+ Location location,
+ Environment env)
+ throws EvalException, InterruptedException;
+
+ @SkylarkCallable(
name = "merge_resources",
parameters = {
@Param(
@@ -408,146 +487,6 @@
throws EvalException, InterruptedException;
@SkylarkCallable(
- name = "process_library_data",
- parameters = {
- @Param(
- name = "ctx",
- positional = true,
- named = false,
- type = AndroidDataContextApi.class,
- doc = "The Android data context object for this target."),
- @Param(
- name = "library_class_jar",
- positional = true,
- named = false,
- type = FileApi.class,
- doc = "The library class jar."),
- @Param(
- name = "manifest",
- positional = false,
- type = FileApi.class,
- defaultValue = "None",
- named = true,
- noneable = true,
- doc =
- "If passed, the manifest to use for this target. Otherwise, a dummy manifest will"
- + " be generated."),
- @Param(
- name = "resources",
- positional = false,
- defaultValue = "None",
- type = SkylarkList.class,
- generic1 = FileProviderApi.class,
- named = true,
- noneable = true,
- doc = "Providers of this target's resources."),
- @Param(
- name = "assets",
- positional = false,
- defaultValue = "None",
- type = SkylarkList.class,
- generic1 = TransitiveInfoCollectionApi.class,
- noneable = true,
- named = true,
- doc =
- "Targets containing raw assets for this target. If passed, 'assets_dir' must also"
- + " be passed."),
- @Param(
- name = "assets_dir",
- positional = false,
- defaultValue = "None",
- type = String.class,
- noneable = true,
- named = true,
- doc =
- "Directory the assets are contained in. Must be passed if and only if 'assets' is"
- + " passed. This path will be split off of the asset paths on the device."),
- @Param(
- name = "exports_manifest",
- positional = false,
- defaultValue = "None",
- type = Boolean.class,
- named = true,
- noneable = true,
- doc =
- "Defaults to False. If passed as True, this manifest will be exported to and"
- + " eventually merged into targets that depend on it. Otherwise, it won't be"
- + " inherited."),
- @Param(
- name = "custom_package",
- positional = false,
- defaultValue = "None",
- type = String.class,
- noneable = true,
- named = true,
- doc =
- "The Android application package to stamp the manifest with. If not provided, the"
- + " current Java package, derived from the location of this target's BUILD"
- + " file, will be used. For example, given a BUILD file in"
- + " 'java/com/foo/bar/BUILD', the package would be 'com.foo.bar'."),
- @Param(
- name = "neverlink",
- positional = false,
- defaultValue = "False",
- type = Boolean.class,
- named = true,
- doc =
- "Defaults to False. If passed as True, these resources and assets will not be"
- + " inherited by targets that depend on this one."),
- @Param(
- name = "enable_data_binding",
- positional = false,
- defaultValue = "False",
- type = Boolean.class,
- named = true,
- doc =
- "Defaults to False. If True, processes data binding expressions in layout"
- + " resources."),
- @Param(
- name = "local_proguard_specs",
- type = SkylarkList.class,
- generic1 = FileApi.class,
- defaultValue = "[]",
- positional = false,
- named = true,
- doc =
- "Files to be used as Proguard specification for this target, which will be"
- + " inherited in the top-level target."),
- @Param(
- name = "deps",
- positional = false,
- defaultValue = "[]",
- type = SkylarkList.class,
- generic1 = AndroidAssetsInfoApi.class,
- named = true,
- doc =
- "Dependency targets. Providers will be extracted from these dependencies for each"
- + " type of data."),
- },
- useLocation = true,
- useEnvironment = true,
- doc =
- "Performs full processing of data for android_library or similar rules. Returns a dict"
- + " from provider type to providers for the target.",
- documented = false)
- SkylarkDict<? extends ProviderApi, ? extends StructApi> processLibraryData(
- AndroidDataContextT cotx,
- FileT libraryClassJar,
- Object manifest,
- Object resources,
- Object assets,
- Object assetsDir,
- Object exportsManifest,
- Object customPackage,
- boolean neverlink,
- boolean enableDataBinding,
- SkylarkList<FileT> localProguardSpecs,
- SkylarkList<TransitiveInfoCollectionT> deps,
- Location location,
- Environment env)
- throws InterruptedException, EvalException;
-
- @SkylarkCallable(
name = "process_aar_import_data",
parameters = {
@Param(
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/ValidatedAndroidDataApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/ValidatedAndroidDataApi.java
index d3670ac..30fb3a6 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/ValidatedAndroidDataApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android/ValidatedAndroidDataApi.java
@@ -30,7 +30,21 @@
+ "Validated Android data which can be merged together with assets from dependencies.",
documented = false,
category = SkylarkModuleCategory.PROVIDER)
-public interface ValidatedAndroidDataApi<FileT extends FileApi> {
+public interface ValidatedAndroidDataApi<
+ FileT extends FileApi,
+ AndroidResourcesInfoT extends
+ AndroidResourcesInfoApi<
+ FileT,
+ ? extends ValidatedAndroidDataApi<FileT, AndroidResourcesInfoT>,
+ ? extends AndroidManifestInfoApi<FileT>>> {
+
+ @SkylarkCallable(
+ name = "to_provider",
+ structField = true,
+ doc = "",
+ documented = false,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ENABLE_ANDROID_MIGRATION_APIS)
+ AndroidResourcesInfoT toProvider();
@SkylarkCallable(
name = "r_txt",
@@ -41,6 +55,14 @@
FileT getRTxt();
@SkylarkCallable(
+ name = "java_class_jar",
+ structField = true,
+ doc = "",
+ documented = false,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ENABLE_ANDROID_MIGRATION_APIS)
+ FileT getJavaClassJar();
+
+ @SkylarkCallable(
name = "java_source_jar",
structField = true,
doc = "",
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/android/FakeAndroidResourcesInfo.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/android/FakeAndroidResourcesInfo.java
index 6275836..2cf90be 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/android/FakeAndroidResourcesInfo.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/android/FakeAndroidResourcesInfo.java
@@ -140,7 +140,13 @@
}
/** Fake implementation of {@link ValidatedAndroidDataApi}. */
- public static class FakeValidatedAndroidDataApi implements ValidatedAndroidDataApi<FileApi> {
+ public static class FakeValidatedAndroidDataApi
+ implements ValidatedAndroidDataApi<FileApi, FakeAndroidResourcesInfo> {
+
+ @Override
+ public FakeAndroidResourcesInfo toProvider() {
+ return null;
+ }
@Override
public FileApi getRTxt() {
@@ -148,6 +154,11 @@
}
@Override
+ public FileApi getJavaClassJar() {
+ return null;
+ }
+
+ @Override
public FileApi getJavaSourceJar() {
return null;
}