Repository: runningcode/fladle (kotlin)

Issue:
`./gradlew flankAuth` throws `TaskExecutionException`
I just setup a project with Fladle and using the User Authentication approach to grant my local machine access to Firebase Test Lab. However, when I tried to run `./gradlew flankAuth`, it keeps throwing `TaskExecutionException`. The workaround I found is to run `./gradlew runFlank` first, then the `flankAuth` will work. Please find the Stacktrace below.

```
* What went wrong:
Execution failed for task ‘:{project}:flankAuth'.
> A problem occurred starting process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin/java''

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ‘:{project}:flankAuth'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:207)
        at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:205)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:186)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:114)
        at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
        at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:356)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)
Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin/java''
        at org.gradle.process.internal.DefaultExecHandle.execExceptionFor(DefaultExecHandle.java:241)
        at org.gradle.process.internal.DefaultExecHandle.setEndStateInfo(DefaultExecHandle.java:218)
        at org.gradle.process.internal.DefaultExecHandle.failed(DefaultExecHandle.java:372)
        at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:87)
        at org.gradle.internal.operations.CurrentBuildOperationPreservingRunnable.run(CurrentBuildOperationPreservingRunnable.java:42)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)
Caused by: net.rubygrapefruit.platform.NativeException: Could not start '/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin/java'
        at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:27)
        at net.rubygrapefruit.platform.internal.WrapperProcessLauncher.start(WrapperProcessLauncher.java:36)
        at org.gradle.process.internal.ExecHandleRunner.startProcess(ExecHandleRunner.java:98)
        at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:71)
        ... 7 more
Caused by: java.io.IOException: Cannot run program "/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin/java" (in directory "/Users/{user}/Android/{project}/build/fladle"): error=2, No such file or directory
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
        at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)
        ... 10 more

```

Pull request:
Flank expects the output directory to already exists.

Fixes #195

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 8ed2089e..b6e51cfc 100644
--- a/buildSrc/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt
+++ b/buildSrc/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt
@@ -21,6 +21,9 @@ class FladlePluginDelegate {
     val extension = target.extensions.create<FlankGradleExtension>("fladle", target.objects)
 
     target.tasks.register("flankAuth", FlankJavaExec::class.java) {
+      doFirst {
+        target.layout.fladleDir.get().asFile.mkdirs()
+      }
       classpath = project.fladleConfig
       args = listOf("auth", "login")
     }
diff --git a/docs/changelog.md b/docs/changelog.md
index a060ea0c..d095638c 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,6 +1,9 @@
 # Changelog
 
 ## Unreleased
+
+## 0.13.1
+* Fix flankAuth task throwing exception. [Fixes #195](https://github.com/runningcode/fladle/issues/195)
 * Add support for newly added flank options [PR#186](https://github.com/runningcode/fladle/pull/186) Thanks [pawelpasterz](https://github.com/pawelpasterz): 
     * `default-test-time`
     * `default-class-test-time`


Test patch:
diff --git a/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankAuthTestTask.kt b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankAuthTestTask.kt
new file mode 100644
index 00000000..45c5f434
--- /dev/null
+++ b/buildSrc/src/test/java/com/osacky/flank/gradle/integration/FlankAuthTestTask.kt
@@ -0,0 +1,34 @@
+package com.osacky.flank.gradle.integration
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+
+class FlankAuthTestTask {
+  @get:Rule
+  var testProjectRoot = TemporaryFolder()
+
+  @Test
+  fun testFlankAuth() {
+    // We set a task timeout because running flankAuth opens a link in the web browser.
+    // We want the task to fail from the timeout and not any other reason like a missing folder.
+    testProjectRoot.writeBuildDotGradle(
+      """plugins {
+         |  id "com.osacky.fladle"
+         |}
+         |repositories {
+         |  mavenCentral()
+         |}
+         |
+         |tasks.named("flankAuth").configure {
+         |  timeout.set(Duration.ofSeconds(5))
+         |}
+         |""".trimMargin()
+    )
+
+    val result = testProjectRoot.gradleRunner().withArguments("flankAuth").buildAndFail()
+
+    assertThat(result.output).contains("Visit the following URL in your browser:")
+  }
+}