Repository: runningcode/fladle
Pull request #98 (2020-04-27 08:35:20)

Use Lazy Property for debug apk and instrumentation apk.
This will allow computing the value lazily so that we aren't touching
the filesystem in the configuration phase of gradle.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2e4054..e290e46 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Changelog
 
+## 0.9.2
+* Breaking API change: debugApk and instrumentationApk now use Lazy Property API to avoid resolving at configuration time.
+
 ## 0.9.1
 * Bugfix: ability to set flank version. [PR](https://github.com/runningcode/fladle/pull/97)
 * Breaking API change: serviceAccountCredentials now uses [Lazy  Property API](https://docs.gradle.org/current/userguide/lazy_configuration.html#working_with_files_in_lazy_properties). See README for details on how to set it. [PR](https://github.com/runningcode/fladle/pull/97)
diff --git a/README.md b/README.md
index 7a623c8..a41c1ac 100644
--- a/README.md
+++ b/README.md
@@ -81,8 +81,8 @@ fladle {
     ]
     projectId("flank-gradle")
     flankVersion("8.1.0")
-    debugApk("$buildDir/outputs/apk/debug/sample-debug.apk")
-    instrumentationApk("$buildDir/outputs/apk/androidTest/debug/sample-debug-androidTest.apk")
+    debugApk = "$buildDir/outputs/apk/debug/sample-debug.apk"
+    instrumentationApk = "$buildDir/outputs/apk/androidTest/debug/sample-debug-androidTest.apk"
     additionalTestApks = ["$buildDir/outputs/apk/debug/sample-debug.apk": ["$buildDir/outputs/apk/androidTest/debug/sample2-debug-androidTest.apk"]]
     autoGoogleLogin = true
     testShards = 5
@@ -126,10 +126,10 @@ This is automatically discovered based on the service credential by default.
 `flankCoordinates = "com.github.flank:flank"` to specify custom flank coordinates.
 
 ### debugApk
-This is the path to the app's debug apk.
+This is the path to the app's debug apk. Supports wildcard characters. Example `build/outputs/apk/debug/*.apk`.
 
 ### instrumentationApk
-This is the path to the app's instrumentation apk.
+This is the path to the app's instrumentation apk. Supports wildcard characters. Example `build/outputs/apk/androidTest/debug/*.apk`.
 
 ### additionalTestApks
 Paths to additional test configurations.
diff --git a/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt
index 1048a07..9dc6ea7 100644
--- a/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradleExtension.kt
@@ -34,8 +34,11 @@ open class FlankGradleExtension(project: Project) : FladleConfig {
   // Variant to use for configuring output APK.
   var variant: String? = null
 
-  var debugApk: String? = null
-  var instrumentationApk: String? = null
+  /**
+   * debugApk and instrmentationApk are [Property<String>] and not [RegularFileProperty] because we support wildcard characters.
+   */
+  val debugApk: Property<String> = project.objects.property()
+  val instrumentationApk: Property<String> = project.objects.property()
 
   override var directoriesToPull: List<String> = emptyList()
 
diff --git a/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradlePlugin.kt b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradlePlugin.kt
index 76f99c4..587c2b5 100644
--- a/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradlePlugin.kt
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/FlankGradlePlugin.kt
@@ -43,7 +43,7 @@ class FlankGradlePlugin : Plugin<Project> {
 
       // Only use automatic apk path detection for 'com.android.application' projects.
       project.pluginManager.withPlugin("com.android.application") {
-        if (base.debugApk == null || base.instrumentationApk == null) {
+        if (!base.debugApk.isPresent || !base.instrumentationApk.isPresent) {
           findDebugAndInstrumentationApk(project, base)
         }
       }
@@ -103,8 +103,8 @@ class FlankGradlePlugin : Plugin<Project> {
     if (base.serviceAccountCredentials.isPresent) {
       check(project.file(base.serviceAccountCredentials.get()).exists()) { "serviceAccountCredential file doesn't exist ${base.serviceAccountCredentials.get()}" }
     }
-    checkNotNull(base.debugApk!!) { "debugApk file cannot be null ${base.debugApk}" }
-    checkNotNull(base.instrumentationApk!!) { "instrumentationApk file cannot be null ${base.instrumentationApk}" }
+    check(base.debugApk.isPresent) { "debugApk file must be specified ${base.debugApk.orNull}" }
+    check(base.instrumentationApk.isPresent) { "instrumentationApk file must be specified ${base.instrumentationApk.orNull}" }
     base.additionalTestApks.forEach {
       check(it.value.isNotEmpty()) { "must provide at least one instrumentation apk for ${it.key}" }
     }
@@ -130,8 +130,8 @@ class FlankGradlePlugin : Plugin<Project> {
             testVariant.outputs.all test@{
               project.log("Configuring fladle.debugApk from variant ${this@debug.name}")
               project.log("Configuring fladle.instrumentationApk from variant ${this@test.name}")
-              extension.debugApk = this@debug.outputFile.absolutePath
-              extension.instrumentationApk = this@test.outputFile.absolutePath
+              extension.debugApk.set(this@debug.outputFile.absolutePath)
+              extension.instrumentationApk.set(this@test.outputFile.absolutePath)
             }
           }
         }
diff --git a/buildSrc/src/main/java/com/osacky/flank/gradle/YamlWriter.kt b/buildSrc/src/main/java/com/osacky/flank/gradle/YamlWriter.kt
index fcf29ac..cdf4608 100644
--- a/buildSrc/src/main/java/com/osacky/flank/gradle/YamlWriter.kt
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/YamlWriter.kt
@@ -8,15 +8,15 @@ internal class YamlWriter {
     if (base.projectId == null) {
       check(base.serviceAccountCredentials.isPresent) { "ServiceAccountCredentials in fladle extension not set. https://github.com/runningcode/fladle#serviceaccountcredentials" }
     }
-    checkNotNull(base.debugApk) { "debugApk cannot be null" }
-    checkNotNull(base.instrumentationApk) { "instrumentationApk cannot be null" }
+    check(base.debugApk.isPresent) { "debugApk must be specified" }
+    check(base.instrumentationApk.isPresent) { "instrumentationApk must be specified" }
 
     val deviceString = createDeviceString(config.devices)
     val additionalProperties = writeAdditionalProperties(config)
     val flankProperties = writeFlankProperties(config)
     return """gcloud:
-      |  app: ${base.debugApk}
-      |  test: ${base.instrumentationApk}
+      |  app: ${base.debugApk.get()}
+      |  test: ${base.instrumentationApk.get()}
       |$deviceString
       |$additionalProperties
       |$flankProperties
diff --git a/sample/build.gradle b/sample/build.gradle
index 9ee200a..dcf6f47 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -58,7 +58,7 @@ dependencies {
         exclude group: 'com.android.support'
     }
     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
-    testImplementation 'junit:junit:4.12'
+    testImplementation 'junit:junit:4.13'
     androidTestImplementation 'androidx.test:runner:1.2.0'
     androidTestImplementation 'androidx.test:rules:1.2.0'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'


Test patch:
diff --git a/buildSrc/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt b/buildSrc/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt
index b83c26d..a94bdce 100644
--- a/buildSrc/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt
+++ b/buildSrc/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt
@@ -20,8 +20,8 @@ class MultipleConfigsTest {
       |
       |fladle {
       |  serviceAccountCredentials = layout.projectDirectory.file("flank-gradle-service.json")
-      |  debugApk("foo.apk")
-      |  instrumentationApk("instrument.apk")
+      |  debugApk = "foo.apk"
+      |  instrumentationApk = "instrument.apk"
       |
       |  testTargets = ['default']
       |  configs {
diff --git a/buildSrc/src/test/java/com/osacky/flank/gradle/YamlWriterTest.kt b/buildSrc/src/test/java/com/osacky/flank/gradle/YamlWriterTest.kt
index 83cc27b..689899b 100644
--- a/buildSrc/src/test/java/com/osacky/flank/gradle/YamlWriterTest.kt
+++ b/buildSrc/src/test/java/com/osacky/flank/gradle/YamlWriterTest.kt
@@ -136,8 +136,8 @@ class YamlWriterTest {
   fun verifyMissingServiceDoesntThrowErrorIfProjectIdSet() {
     val extension = FlankGradleExtension(project).apply {
       projectId = "set"
-      debugApk = "path"
-      instrumentationApk = "instrument"
+      debugApk.set("path")
+      instrumentationApk.set("instrument")
     }
     val yaml = yamlWriter.createConfigProps(extension, extension)
     assertEquals("gcloud:\n" +
@@ -168,7 +168,7 @@ class YamlWriterTest {
       yamlWriter.createConfigProps(extension, extension)
       fail()
     } catch (expected: IllegalStateException) {
-      assertEquals("debugApk cannot be null", expected.message)
+      assertEquals("debugApk must be specified", expected.message)
     }
   }
 
@@ -176,13 +176,13 @@ class YamlWriterTest {
   fun verifyInstrumentationApkThrowsError() {
     val extension = FlankGradleExtension(project).apply {
       serviceAccountCredentials.set(project.layout.projectDirectory.file("fake.json"))
-      debugApk = "path"
+      debugApk.set("path")
     }
     try {
       yamlWriter.createConfigProps(extension, extension)
       fail()
     } catch (expected: IllegalStateException) {
-      assertEquals("instrumentationApk cannot be null", expected.message)
+      assertEquals("instrumentationApk must be specified", expected.message)
     }
   }
 
@@ -563,8 +563,8 @@ class YamlWriterTest {
   @Test
   fun writeAdditionalTestApks() {
     val extension = FlankGradleExtension(project).apply {
-      debugApk = "../orange/build/output/app.apk"
-      instrumentationApk = "../orange/build/output/app-test.apk"
+      debugApk.set("../orange/build/output/app.apk")
+      instrumentationApk.set("../orange/build/output/app-test.apk")
       additionalTestApks = mapOf(
         "../orange/build/output/app.apk" to listOf("../orange/build/output/app-test2.apk"),
         "../bob/build/output/app.apk" to listOf("../bob/build/output/app-test.apk")
diff --git a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt
index d2eccf9..47d3bb8 100644
--- a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt
+++ b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt
@@ -130,7 +130,7 @@ class FlankGradlePluginIntegrationTest {
                 .withArguments("printYml")
                 .build()
         } catch (expected: UnexpectedBuildFailure) {
-            assertThat(expected).hasMessageThat().contains("debugApk cannot be null")
+            assertThat(expected).hasMessageThat().contains("debugApk must be specified")
         }
     }
 }