Repository: runningcode/fladle (kotlin)

Issue:
Make Fladle compatible with the Configuration Cache
https://docs.gradle.org/release-nightly/userguide/configuration_cache.html

Pull request:
Fixes #143

Patch:
diff --git a/buildSrc/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt b/buildSrc/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt
index bb2a3744..8fd3091d 100644
--- a/buildSrc/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt
@@ -5,7 +5,6 @@ import com.android.builder.model.TestOptions
 import org.gradle.api.GradleException
 import org.gradle.api.Project
 import org.gradle.api.artifacts.Configuration
-import org.gradle.api.tasks.JavaExec
 import org.gradle.api.tasks.TaskContainer
 import org.gradle.kotlin.dsl.create
 import org.gradle.util.GradleVersion
@@ -68,22 +67,17 @@ class FladlePluginDelegate {
 
     val writeConfigProps = register("writeConfigProps$name", YamlConfigWriterTask::class.java, config, base)
 
-    register("flankDoctor$name", JavaExec::class.java) {
+    register("flankDoctor$name", FlankJavaExec::class.java) {
       description = "Finds problems with the current configuration."
-      group = TASK_GROUP
-      workingDir(project.layout.fladleDir)
       classpath = project.fladleConfig
-      main = "ftl.Main"
       args = listOf("firebase", "test", "android", "doctor")
       dependsOn(writeConfigProps)
     }
 
-    val execFlank = register("execFlank$name", JavaExec::class.java) {
+    val execFlank = register("execFlank$name", FlankExecutionTask::class.java, config)
+    execFlank.configure {
       description = "Runs instrumentation tests using flank on firebase test lab."
-      group = TASK_GROUP
-      workingDir(project.layout.fladleDir)
       classpath = project.fladleConfig
-      main = "ftl.Main"
       args = if (project.hasProperty("dumpShards")) {
         listOf("firebase", "test", "android", "run", "--dump-shards")
       } else {
@@ -92,10 +86,7 @@ class FladlePluginDelegate {
       if (config.serviceAccountCredentials.isPresent) {
         environment(mapOf("GOOGLE_APPLICATION_CREDENTIALS" to config.serviceAccountCredentials.get()))
       }
-      dependsOn(named("writeConfigProps$name"))
-      doFirst {
-        checkFilesExist(base, project)
-      }
+      dependsOn(writeConfigProps)
     }
 
     register("runFlank$name", RunFlankTask::class.java).configure {
@@ -103,12 +94,6 @@ class FladlePluginDelegate {
     }
   }
 
-  private fun checkFilesExist(base: FlankGradleExtension, project: Project) {
-    if (base.serviceAccountCredentials.isPresent) {
-      check(project.file(base.serviceAccountCredentials.get()).exists()) { "serviceAccountCredential file doesn't exist ${base.serviceAccountCredentials.get()}" }
-    }
-  }
-
   private fun automaticallyConfigureTestOrchestrator(project: Project, extension: FlankGradleExtension, androidExtension: AppExtension) {
     project.afterEvaluate {
       val useOrchestrator = androidExtension.testOptions.executionEnum == TestOptions.Execution.ANDROIDX_TEST_ORCHESTRATOR || androidExtension.testOptions.executionEnum == TestOptions.Execution.ANDROID_TEST_ORCHESTRATOR
diff --git a/buildSrc/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt
new file mode 100644
index 00000000..21dcb5ff
--- /dev/null
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt
@@ -0,0 +1,19 @@
+package com.osacky.flank.gradle
+
+import org.gradle.api.file.ProjectLayout
+import javax.inject.Inject
+
+open class FlankExecutionTask @Inject constructor(projectLayout: ProjectLayout, private val config: FladleConfig) : FlankJavaExec(projectLayout) {
+
+  init {
+    doFirst {
+      checkFilesExist(config)
+    }
+  }
+
+  private fun checkFilesExist(base: FladleConfig) {
+    if (base.serviceAccountCredentials.isPresent) {
+      check(base.serviceAccountCredentials.get().asFile.exists()) { "serviceAccountCredential file doesn't exist ${base.serviceAccountCredentials.get()}" }
+    }
+  }
+}
diff --git a/buildSrc/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt
new file mode 100644
index 00000000..8da37a39
--- /dev/null
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt
@@ -0,0 +1,13 @@
+package com.osacky.flank.gradle
+
+import org.gradle.api.file.ProjectLayout
+import org.gradle.api.tasks.JavaExec
+import javax.inject.Inject
+
+open class FlankJavaExec @Inject constructor(projectLayout: ProjectLayout) : JavaExec() {
+  init {
+    group = TASK_GROUP
+    main = "ftl.Main"
+    workingDir(projectLayout.fladleDir)
+  }
+}


Test patch:
diff --git a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt
index 13f664a4..1f5a775a 100644
--- a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt
+++ b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt
@@ -1,9 +1,7 @@
 package com.osacky.flank.gradle.integration
 
 import com.google.common.truth.Truth.assertThat
-import org.gradle.testkit.runner.BuildResult
 import org.gradle.testkit.runner.GradleRunner
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.TemporaryFolder
@@ -25,11 +23,11 @@ class ConfigurationCacheTest {
              |  id "com.osacky.fladle"
              |}""".trimMargin()
     )
-    val result = runConfigCachingBuild("help")
+    val result = configCachingRunner("help").build()
 
     assertThat(result.output).contains("SUCCESS")
 
-    val secondResult = runConfigCachingBuild("help")
+    val secondResult = configCachingRunner("help").build()
 
     assertThat(secondResult.output).contains("Reusing configuration cache.")
   }
@@ -48,23 +46,26 @@ class ConfigurationCacheTest {
            |}
            |""".trimMargin()
     )
-    val result = runConfigCachingBuild("writeConfigProps")
+    val result = configCachingRunner("writeConfigProps").build()
 
     assertThat(result.output).contains("SUCCESS")
 
-    val secondResult = runConfigCachingBuild("writeConfigProps")
+    val secondResult = configCachingRunner("writeConfigProps").build()
 
     assertThat(secondResult.output).contains("Reusing configuration cache.")
   }
 
   @Test
-  @Ignore
-  fun runFlank() {
+  fun flankDoctor() {
     writeBuildGradle(
       """|plugins {
            |  id "com.osacky.fladle"
            |}
            |
+           |repositories {
+           |  mavenCentral()
+           |}
+           |
            |fladle {
            |  serviceAccountCredentials = project.layout.projectDirectory.file("flank-gradle-service-account.json")
            |  debugApk = "debug.apk"
@@ -72,21 +73,50 @@ class ConfigurationCacheTest {
            |}
            |""".trimMargin()
     )
-    val result = runConfigCachingBuild("runFlank")
+    val result = configCachingRunner("flankDoctor").build()
 
     assertThat(result.output).contains("SUCCESS")
 
-    val secondResult = runConfigCachingBuild("runFlank")
+    val secondResult = configCachingRunner("flankDoctor").build()
+
+    assertThat(secondResult.output).contains("Reusing configuration cache.")
+  }
+
+  @Test
+  fun runFlank() {
+    writeBuildGradle(
+      """|plugins {
+           |  id "com.osacky.fladle"
+           |}
+           |
+           |repositories {
+           |  mavenCentral()
+           |}
+           |
+           |fladle {
+           |  serviceAccountCredentials = project.layout.projectDirectory.file("flank-gradle-service-account.json")
+           |  debugApk = "debug.apk"
+           |  instrumentationApk = "test.apk"
+           |}
+           |""".trimMargin()
+    )
+    testProjectRoot.newFile("flank-gradle-service-account.json").writeText("foo")
+    val result = configCachingRunner("runFlank").buildAndFail()
+
+    assertThat(result.output).contains("Error: Failed to read service account credential.")
+    assertThat(result.output).contains("Configuration cache entry stored.")
+
+    val secondResult = configCachingRunner("runFlank").buildAndFail()
 
+    assertThat(secondResult.output).contains("Error: Failed to read service account credential.")
     assertThat(secondResult.output).contains("Reusing configuration cache.")
   }
 
-  private fun runConfigCachingBuild(arg: String): BuildResult {
+  private fun configCachingRunner(arg: String): GradleRunner {
     return GradleRunner.create()
       .withProjectDir(testProjectRoot.root)
       .withPluginClasspath()
       .forwardOutput()
       .withArguments(arg, "--configuration-cache")
-      .build()
   }
 }
diff --git a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt
index 892a11a2..3b547166 100644
--- a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt
+++ b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt
@@ -16,7 +16,7 @@ class FulladlePluginIntegrationTest {
   }
 
   @Test
-  fun fladleSmokeTest() {
+  fun fulladleSmokeTest() {
     writeBuildGradle(
       """plugins {
              |  id "com.osacky.fulladle"