diff --git a/keeper-gradle-plugin/api/keeper-gradle-plugin.api b/keeper-gradle-plugin/api/keeper-gradle-plugin.api index ab076858..b2ed64f8 100644 --- a/keeper-gradle-plugin/api/keeper-gradle-plugin.api +++ b/keeper-gradle-plugin/api/keeper-gradle-plugin.api @@ -2,7 +2,6 @@ public abstract class com/slack/keeper/AndroidTestVariantClasspathJar : com/slac public fun ()V public final fun createJar ()V public final fun from ([Ljava/lang/Object;)V - public abstract fun getAndroidTestArtifactFiles ()Lorg/gradle/api/file/ConfigurableFileCollection; public abstract fun getAppJarsFile ()Lorg/gradle/api/file/RegularFileProperty; public abstract fun getArchiveFile ()Lorg/gradle/api/file/RegularFileProperty; public abstract fun getClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection; @@ -11,8 +10,10 @@ public abstract class com/slack/keeper/AndroidTestVariantClasspathJar : com/slac public abstract class com/slack/keeper/BaseKeeperJarTask : org/gradle/api/DefaultTask { public fun ()V protected final fun diagnostic (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Ljava/io/File; + public final fun getArtifactFiles ()Lorg/gradle/api/file/FileCollection; public abstract fun getDiagnosticsOutputDir ()Lorg/gradle/api/file/DirectoryProperty; public abstract fun getEmitDebugInfo ()Lorg/gradle/api/provider/Property; + public final fun setArtifacts (Lorg/gradle/api/artifacts/ArtifactCollection;)V } public abstract class com/slack/keeper/InferAndroidTestKeepRules : org/gradle/api/tasks/JavaExec { @@ -76,7 +77,6 @@ public abstract class com/slack/keeper/VariantClasspathJar : com/slack/keeper/Ba public final fun from ([Ljava/lang/Object;)V public abstract fun getAppJarsFile ()Lorg/gradle/api/file/RegularFileProperty; public abstract fun getArchiveFile ()Lorg/gradle/api/file/RegularFileProperty; - public abstract fun getArtifactFiles ()Lorg/gradle/api/file/ConfigurableFileCollection; public abstract fun getClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection; } diff --git a/keeper-gradle-plugin/src/main/java/com/slack/keeper/KeeperPlugin.kt b/keeper-gradle-plugin/src/main/java/com/slack/keeper/KeeperPlugin.kt index 49a8e758..fe0acca6 100644 --- a/keeper-gradle-plugin/src/main/java/com/slack/keeper/KeeperPlugin.kt +++ b/keeper-gradle-plugin/src/main/java/com/slack/keeper/KeeperPlugin.kt @@ -32,9 +32,9 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.UnknownTaskException +import org.gradle.api.artifacts.ArtifactCollection import org.gradle.api.artifacts.Configuration import org.gradle.api.file.Directory -import org.gradle.api.file.FileCollection import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer @@ -381,7 +381,7 @@ public class KeeperPlugin : Plugin { private fun Project.applyGeneratedRules( appVariant: String, prop: Provider, - testProguardFiles: FileCollection + testProguardFiles: ArtifactCollection ) { val targetName = interpolateR8TaskName(appVariant) @@ -391,7 +391,7 @@ public class KeeperPlugin : Plugin { logger.debug( "$TAG: Patching task '$name' with inferred androidTest proguard rules") configurationFiles.from(prop) - configurationFiles.from(testProguardFiles) + configurationFiles.from(testProguardFiles.artifactFiles) } } @@ -412,7 +412,7 @@ public class KeeperPlugin : Plugin { with(testVariant) { from(layout.dir(javaCompileProvider.map { it.destinationDir })) - androidTestArtifactFiles.from(runtimeConfiguration.classesJars()) + setArtifacts(runtimeConfiguration.classesJars()) tasks.providerWithNameOrNull( "compile${name.capitalize(Locale.US)}Kotlin") ?.let { kotlinCompileTask -> @@ -444,7 +444,7 @@ public class KeeperPlugin : Plugin { this.emitDebugInfo.set(emitDebugInfo) with(appVariant) { from(layout.dir(javaCompileProvider.map { it.destinationDir })) - artifactFiles.from(runtimeConfiguration.classesJars()) + setArtifacts(runtimeConfiguration.classesJars()) tasks.providerWithNameOrNull( "compile${name.capitalize(Locale.US)}Kotlin") @@ -463,16 +463,15 @@ public class KeeperPlugin : Plugin { } } -private fun Configuration.classesJars(): FileCollection { +private fun Configuration.classesJars(): ArtifactCollection { return artifactView(ArtifactType.CLASSES_JAR) - .filter { it.exists() && it.extension == "jar" } } -private fun Configuration.proguardFiles(): FileCollection { +private fun Configuration.proguardFiles(): ArtifactCollection { return artifactView(ArtifactType.FILTERED_PROGUARD_RULES) } -private fun Configuration.artifactView(artifactType: ArtifactType): FileCollection { +private fun Configuration.artifactView(artifactType: ArtifactType): ArtifactCollection { return incoming .artifactView { attributes { @@ -483,7 +482,6 @@ private fun Configuration.artifactView(artifactType: ArtifactType): FileCollecti } } .artifacts - .artifactFiles } private inline fun TaskContainer.providerWithNameOrNull( diff --git a/keeper-gradle-plugin/src/main/java/com/slack/keeper/VariantClasspathJar.kt b/keeper-gradle-plugin/src/main/java/com/slack/keeper/VariantClasspathJar.kt index 9335e786..8ea59f18 100644 --- a/keeper-gradle-plugin/src/main/java/com/slack/keeper/VariantClasspathJar.kt +++ b/keeper-gradle-plugin/src/main/java/com/slack/keeper/VariantClasspathJar.kt @@ -21,17 +21,21 @@ package com.slack.keeper import com.android.zipflinger.BytesSource import com.android.zipflinger.ZipArchive import org.gradle.api.DefaultTask +import org.gradle.api.artifacts.ArtifactCollection import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileCollection import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.PathSensitivity.NONE import org.gradle.api.tasks.TaskAction import org.gradle.jvm.tasks.Jar @@ -44,9 +48,29 @@ public abstract class BaseKeeperJarTask : DefaultTask() { @get:Input public abstract val emitDebugInfo: Property + private lateinit var artifacts: ArtifactCollection + @get:OutputDirectory public abstract val diagnosticsOutputDir: DirectoryProperty + /** + * This artifact collection is the result of resolving the compilation classpath. + */ + public fun setArtifacts(artifacts: ArtifactCollection) { + this.artifacts = artifacts + } + + /** + * This is the "official" input for wiring task dependencies correctly, but is otherwise + * unused. This needs to use [InputFiles] and [PathSensitivity.ABSOLUTE] because the path to the + * jars really does matter here. Using [Classpath] is an error, as it looks only at content and + * not name or path, and we really do need to know the actual path to the artifact, even if its + * contents haven't changed. + */ + @PathSensitive(PathSensitivity.ABSOLUTE) + @InputFiles + public fun getArtifactFiles(): FileCollection = artifacts.artifactFiles + protected fun diagnostic(fileName: String, body: () -> String): File? { return if (emitDebugInfo.get()) { diagnosticsOutputDir.get().file("${fileName}.txt").asFile.apply { @@ -69,9 +93,6 @@ public abstract class BaseKeeperJarTask : DefaultTask() { @CacheableTask public abstract class VariantClasspathJar : BaseKeeperJarTask() { - @get:Classpath - public abstract val artifactFiles: ConfigurableFileCollection - @get:OutputFile public abstract val archiveFile: RegularFileProperty @@ -92,7 +113,7 @@ public abstract class VariantClasspathJar : BaseKeeperJarTask() { val appClasses = mutableSetOf() ZipArchive(archiveFile.asFile.get().toPath()).use { archive -> // The runtime classpath (i.e. from dependencies) - artifactFiles + getArtifactFiles() .forEach { jar -> appJars.add(jar.canonicalPath) archive.extractClassesFrom(jar) { @@ -132,9 +153,6 @@ public abstract class AndroidTestVariantClasspathJar : BaseKeeperJarTask() { val LOG = AndroidTestVariantClasspathJar::class.simpleName!! } - @get:Classpath - public abstract val androidTestArtifactFiles: ConfigurableFileCollection - @get:PathSensitive(NONE) // Only care about the contents @get:InputFile public abstract val appJarsFile: RegularFileProperty @@ -155,7 +173,7 @@ public abstract class AndroidTestVariantClasspathJar : BaseKeeperJarTask() { logger.debug("$LOG: Diffing androidTest jars and app jars") val appJars = appJarsFile.get().asFile.useLines { it.toSet() } - val androidTestClasspath = androidTestArtifactFiles.files + val androidTestClasspath = getArtifactFiles() diagnostic("jars") { androidTestClasspath.sortedBy { it.canonicalPath } .joinToString("\n") {