From d679e7fc1849cb9ecf4f8e52e2fcc94653a847aa Mon Sep 17 00:00:00 2001 From: John Rodriguez Date: Wed, 19 Jun 2024 06:56:23 +0200 Subject: [PATCH] Extract Android sources logic to simplify plugin (#1484) --- .../api/paparazzi-gradle-plugin.api | 2 +- .../paparazzi/gradle/AndroidVariantSources.kt | 56 ++++++++++++++ .../cash/paparazzi/gradle/PaparazziPlugin.kt | 75 ++++++------------- 3 files changed, 80 insertions(+), 53 deletions(-) create mode 100644 paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/AndroidVariantSources.kt diff --git a/paparazzi-gradle-plugin/api/paparazzi-gradle-plugin.api b/paparazzi-gradle-plugin/api/paparazzi-gradle-plugin.api index 852c797552..7596e218ac 100644 --- a/paparazzi-gradle-plugin/api/paparazzi-gradle-plugin.api +++ b/paparazzi-gradle-plugin/api/paparazzi-gradle-plugin.api @@ -1,5 +1,5 @@ public final class app/cash/paparazzi/gradle/PaparazziPlugin : org/gradle/api/Plugin { - public fun ()V + public fun (Lorg/gradle/api/provider/ProviderFactory;)V public synthetic fun apply (Ljava/lang/Object;)V public fun apply (Lorg/gradle/api/Project;)V } diff --git a/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/AndroidVariantSources.kt b/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/AndroidVariantSources.kt new file mode 100644 index 0000000000..7d2d162af6 --- /dev/null +++ b/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/AndroidVariantSources.kt @@ -0,0 +1,56 @@ +package app.cash.paparazzi.gradle + +import app.cash.paparazzi.gradle.utils.artifactsFor +import com.android.build.api.variant.Variant +import com.android.build.gradle.internal.publishing.AndroidArtifacts +import org.gradle.api.artifacts.component.ProjectComponentIdentifier +import org.gradle.api.file.Directory +import org.gradle.api.file.FileCollection +import org.gradle.api.provider.Provider + +/** + * All the relevant sources for a given Android variant. + */ +internal class AndroidVariantSources( + private val variant: Variant +) { + val localResourceDirs: Provider>? by lazy { + variant.sources.res?.all?.map { layers -> layers.flatten() }?.map { it.asReversed() } + } + + // https://android.googlesource.com/platform/tools/base/+/96015063acd3455a76cdf1cc71b23b0828c0907f/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/MergeResources.kt#875 + val moduleResourceDirs: FileCollection by lazy { + variant.runtimeConfiguration + .artifactsFor(AndroidArtifacts.ArtifactType.ANDROID_RES.type) { it is ProjectComponentIdentifier } + .artifactFiles + } + + val aarExplodedDirs: FileCollection by lazy { + variant.runtimeConfiguration + .artifactsFor(AndroidArtifacts.ArtifactType.ANDROID_RES.type) { it !is ProjectComponentIdentifier } + .artifactFiles + } + + val localAssetDirs: Provider>? by lazy { + variant.sources.assets?.all?.map { layers -> layers.flatten() }?.map { it.asReversed() } + } + + // https://android.googlesource.com/platform/tools/base/+/96015063acd3455a76cdf1cc71b23b0828c0907f/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/MergeResources.kt#875 + val moduleAssetDirs: FileCollection by lazy { + variant.runtimeConfiguration + .artifactsFor(AndroidArtifacts.ArtifactType.ASSETS.type) { it is ProjectComponentIdentifier } + .artifactFiles + } + + val aarAssetDirs: FileCollection by lazy { + variant.runtimeConfiguration + .artifactsFor(AndroidArtifacts.ArtifactType.ASSETS.type) { it !is ProjectComponentIdentifier } + .artifactFiles + } + + val packageAwareArtifactFiles: FileCollection by lazy { + variant.runtimeConfiguration + .artifactsFor(AndroidArtifacts.ArtifactType.SYMBOL_LIST_WITH_PACKAGE_NAME.type) + .artifactFiles + } +} diff --git a/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt b/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt index 98fb0a57ae..dda553efa2 100644 --- a/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt +++ b/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt @@ -16,7 +16,6 @@ package app.cash.paparazzi.gradle import app.cash.paparazzi.gradle.utils.artifactViewFor -import app.cash.paparazzi.gradle.utils.artifactsFor import app.cash.paparazzi.gradle.utils.relativize import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension @@ -24,16 +23,17 @@ import com.android.build.api.variant.DynamicFeatureAndroidComponentsExtension import com.android.build.api.variant.HasUnitTest import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.gradle.BaseExtension -import com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.type.ArtifactTypeDefinition import org.gradle.api.artifacts.type.ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE +import org.gradle.api.file.Directory import org.gradle.api.file.FileCollection import org.gradle.api.internal.artifacts.transform.UnzipTransform import org.gradle.api.logging.LogLevel.LIFECYCLE +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory import org.gradle.api.reporting.ReportingExtension import org.gradle.api.tasks.Delete import org.gradle.api.tasks.PathSensitivity @@ -44,9 +44,12 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin.VERIFICATION_GROUP import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget import java.util.Locale +import javax.inject.Inject @Suppress("unused") -public class PaparazziPlugin : Plugin { +public class PaparazziPlugin @Inject constructor( + private val providerFactory: ProviderFactory +) : Plugin { override fun apply(project: Project) { val supportedPlugins = listOf("com.android.application", "com.android.library", "com.android.dynamic-feature") project.afterEvaluate { @@ -114,33 +117,7 @@ public class PaparazziPlugin : Plugin { val gradleUserHomeDir = project.gradle.gradleUserHomeDir val reportOutputDir = project.extensions.getByType(ReportingExtension::class.java).baseDirectory.dir("paparazzi/${variant.name}") - val localResourceDirs = variant.sources.res?.all ?: project.provider { emptyList() } - - // https://android.googlesource.com/platform/tools/base/+/96015063acd3455a76cdf1cc71b23b0828c0907f/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/MergeResources.kt#875 - - val moduleResourceDirs = variant.runtimeConfiguration - .artifactsFor(ArtifactType.ANDROID_RES.type) { it is ProjectComponentIdentifier } - .artifactFiles - - val aarExplodedDirs = variant.runtimeConfiguration - .artifactsFor(ArtifactType.ANDROID_RES.type) { it !is ProjectComponentIdentifier } - .artifactFiles - - val localAssetDirs = variant.sources.assets?.all ?: project.provider { emptyList() } - - // https://android.googlesource.com/platform/tools/base/+/96015063acd3455a76cdf1cc71b23b0828c0907f/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/MergeResources.kt#875 - - val moduleAssetDirs = variant.runtimeConfiguration - .artifactsFor(ArtifactType.ASSETS.type) { it is ProjectComponentIdentifier } - .artifactFiles - - val aarAssetDirs = variant.runtimeConfiguration - .artifactsFor(ArtifactType.ASSETS.type) { it !is ProjectComponentIdentifier } - .artifactFiles - - val packageAwareArtifactFiles = variant.runtimeConfiguration - .artifactsFor(ArtifactType.SYMBOL_LIST_WITH_PACKAGE_NAME.type) - .artifactFiles + val sources = AndroidVariantSources(variant) val writeResourcesTask = project.tasks.register( "preparePaparazzi${variantSlug}Resources", @@ -152,27 +129,17 @@ public class PaparazziPlugin : Plugin { val gradleHomeDir = projectDirectory.dir(project.gradle.gradleUserHomeDir.path) task.packageName.set(android.packageName()) - task.artifactFiles.from(packageAwareArtifactFiles) + task.artifactFiles.from(sources.packageAwareArtifactFiles) task.nonTransitiveRClassEnabled.set(nonTransitiveRClassEnabled) task.targetSdkVersion.set(android.targetSdkVersion()) - - val localResourcePaths = localResourceDirs - .map { layers -> layers.flatten() } - .map { dirs -> dirs.map { projectDirectory.relativize(it.asFile) }.asReversed() } - - task.projectResourceDirs.set(localResourcePaths) - task.moduleResourceDirs.set(moduleResourceDirs.relativize(projectDirectory)) - task.aarExplodedDirs.set(aarExplodedDirs.relativize(gradleHomeDir)) + task.projectResourceDirs.set(sources.localResourceDirs.relativize(projectDirectory)) + task.moduleResourceDirs.set(sources.moduleResourceDirs.relativize(projectDirectory)) + task.aarExplodedDirs.set(sources.aarExplodedDirs.relativize(gradleHomeDir)) task.projectAssetDirs.set( - run { - val localAssetPaths = localAssetDirs - .map { layers -> layers.flatten() } - .map { dirs -> dirs.map { projectDirectory.relativize(it.asFile) }.asReversed() } - val moduleAssetPaths = moduleAssetDirs.relativize(projectDirectory) - localAssetPaths.zip(moduleAssetPaths, List::plus) - } + sources.localAssetDirs.relativize(projectDirectory) + .zip(sources.moduleAssetDirs.relativize(projectDirectory), List::plus) ) - task.aarAssetDirs.set(aarAssetDirs.relativize(gradleHomeDir)) + task.aarAssetDirs.set(sources.aarAssetDirs.relativize(gradleHomeDir)) task.paparazziResources.set(buildDirectory.file("intermediates/paparazzi/${variant.name}/resources.json")) } @@ -222,16 +189,16 @@ public class PaparazziPlugin : Plugin { test.inputs.property("paparazzi.test.record", isRecordRun) test.inputs.property("paparazzi.test.verify", isVerifyRun) - test.inputs.files(localResourceDirs) + test.inputs.files(sources.localResourceDirs) .withPropertyName("paparazzi.localResourceDirs") .withPathSensitivity(PathSensitivity.RELATIVE) - test.inputs.files(moduleResourceDirs) + test.inputs.files(sources.moduleResourceDirs) .withPropertyName("paparazzi.moduleResourceDirs") .withPathSensitivity(PathSensitivity.RELATIVE) - test.inputs.files(localAssetDirs) + test.inputs.files(sources.localAssetDirs) .withPropertyName("paparazzi.localAssetDirs") .withPathSensitivity(PathSensitivity.RELATIVE) - test.inputs.files(moduleAssetDirs) + test.inputs.files(sources.moduleAssetDirs) .withPropertyName("paparazzi.moduleAssetDirs") .withPathSensitivity(PathSensitivity.RELATIVE) test.inputs.files(layoutlibNativeRuntimeFileCollection) @@ -330,6 +297,10 @@ public class PaparazziPlugin : Plugin { private fun BaseExtension.targetSdkVersion(): String = defaultConfig.targetSdkVersion?.apiLevel?.toString() ?: DEFAULT_COMPILE_SDK_VERSION.toString() + + private fun Provider>?.relativize(directory: Directory): Provider> = + this?.map { dirs -> dirs.map { directory.relativize(it.asFile) } } + ?: providerFactory.provider { emptyList() } } private const val DEFAULT_COMPILE_SDK_VERSION = 34