Skip to content

Commit

Permalink
Extract Android sources logic to simplify plugin (#1484)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrodbx authored Jun 19, 2024
1 parent 9744a63 commit d679e7f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 53 deletions.
2 changes: 1 addition & 1 deletion paparazzi-gradle-plugin/api/paparazzi-gradle-plugin.api
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
public final class app/cash/paparazzi/gradle/PaparazziPlugin : org/gradle/api/Plugin {
public fun <init> ()V
public fun <init> (Lorg/gradle/api/provider/ProviderFactory;)V
public synthetic fun apply (Ljava/lang/Object;)V
public fun apply (Lorg/gradle/api/Project;)V
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<List<Directory>>? 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<List<Directory>>? 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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@
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
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
Expand All @@ -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<Project> {
public class PaparazziPlugin @Inject constructor(
private val providerFactory: ProviderFactory
) : Plugin<Project> {
override fun apply(project: Project) {
val supportedPlugins = listOf("com.android.application", "com.android.library", "com.android.dynamic-feature")
project.afterEvaluate {
Expand Down Expand Up @@ -114,33 +117,7 @@ public class PaparazziPlugin : Plugin<Project> {
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",
Expand All @@ -152,27 +129,17 @@ public class PaparazziPlugin : Plugin<Project> {
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<String>::plus)
}
sources.localAssetDirs.relativize(projectDirectory)
.zip(sources.moduleAssetDirs.relativize(projectDirectory), List<String>::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"))
}

Expand Down Expand Up @@ -222,16 +189,16 @@ public class PaparazziPlugin : Plugin<Project> {
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)
Expand Down Expand Up @@ -330,6 +297,10 @@ public class PaparazziPlugin : Plugin<Project> {
private fun BaseExtension.targetSdkVersion(): String =
defaultConfig.targetSdkVersion?.apiLevel?.toString()
?: DEFAULT_COMPILE_SDK_VERSION.toString()

private fun Provider<List<Directory>>?.relativize(directory: Directory): Provider<List<String>> =
this?.map { dirs -> dirs.map { directory.relativize(it.asFile) } }
?: providerFactory.provider { emptyList() }
}

private const val DEFAULT_COMPILE_SDK_VERSION = 34

0 comments on commit d679e7f

Please sign in to comment.