Skip to content

Using the output of a Gradle task to set the value of a property on FlankGradleExtension #239

Description

@jschear

I'm trying to set the value of the testTargets property using the ouput of a task. It looks like the testTargets property is getting resolved at configuration time, leading to a java.io.FileNotFoundException (it tries to read a file that would be generated by the task).

Is this a bug, or something that isn't generally supported?

Context

One feature we’ve implemented in our current non-fladle flank setup is a “stability gate” for new and changed tests — we use git diff to generate a list of test classes that have been modified or added in a pull request, and then dynamically generate a flank yml config that runs those tests a large number of times to check if any flakiness was introduced.

I’m trying to implement this functionality when using fladle. My first thought was to wrap the git invocation in a gradle task, and wire up an output property from the task to the testTargets property in the fladle extension:

// In app/build.gradle.kts

open class GetChangedTestTargets : DefaultTask() {
  @OutputFile
  val outputFile: RegularFileProperty = project.objects.fileProperty()

  @TaskAction
  fun action() {
    // TODO(fladle): execute a git diff between the current branch and master to calculate which test targets should run.
    outputFile.asFile.get().writeText(
      """
      class foo.bar.SomeTestClass1
      class foo.bar.SomeTestClass2
      """.trimIndent()
    )
  }
}

val stabilityGateTestTargets by tasks.registering(GetChangedTestTargets::class) {
  // This task should never be considered up to date because it depends on state outside of the build: it invokes git.
  outputs.upToDateWhen { false }
  outputFile.set(layout.buildDirectory.file("stabilityGateTestTargets.txt"))
}

fladle {
  configs {
    // ...
    create("stabilityGateTests") {
      // ...
      testTargets.set(stabilityGateTestTargets.map { it.outputFile.get().asFile.readLines() })
    }
  }
}

… but unfortunately it appears that the testTargets is getting resolved at configuration time, because I get:

A problem occurred configuring project ':app'.
> java.io.FileNotFoundException: /Users/jschear/dev/myproject/app/build/stabilityGateTestTargets.txt (No such file or directory)

Looking at the stacktrace, it looks like the validateOptionsUsed function is the culprit.

Caused by: org.gradle.api.UncheckedIOException: java.io.FileNotFoundException: /Users/jschear/dev/myproject/app/build/stabilityGateTestTargets.txt (No such file or directory)
        at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:61)
        at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:41)
        at org.gradle.api.internal.provider.AbstractProperty.calculatePresence(AbstractProperty.java:63)
        at org.gradle.api.internal.provider.AbstractMinimalProvider.isPresent(AbstractMinimalProvider.java:74)
        at com.osacky.flank.gradle.FladleConfig$DefaultImpls.getPresentProperties(FladleConfig.kt:462)
        at com.osacky.flank.gradle.FladleConfigImpl.getPresentProperties(FladleConfigImpl.kt:9)
        at com.osacky.flank.gradle.validation.ValidateOptionsKt.validateOptionsUsed(ValidateOptions.kt:8)
        at com.osacky.flank.gradle.FladlePluginDelegate.createTasksForConfig(FladlePluginDelegate.kt:72)
        at com.osacky.flank.gradle.FladlePluginDelegate.access$createTasksForConfig(FladlePluginDelegate.kt:15)
        at com.osacky.flank.gradle.FladlePluginDelegate$configureTasks$1.execute(FladlePluginDelegate.kt:64)
        at com.osacky.flank.gradle.FladlePluginDelegate$configureTasks$1.execute(FladlePluginDelegate.kt:15)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions