Spawn new Gradle instance from within a task

Is it possible to spawn a new instance of the current Gradle (wrapper) instance from within a task, aside from shelling out to ./gradlew? I’d like to execute a particular task repeatedly with different parameters, which isn’t something that fits into Gradle’s task graph model.

Namely, I’d like to implement a test matrix where the check task is executed with different dependency version combinations:

./gradlew check -PdepA=1 -PdepB=1
./gradlew check -PdepA=2 -PdepB=1
./gradlew check -PdepA=1 -PdepB=2
./gradlew check -PdepA=2 -PdepB=2

I can make it work by execing the wrapper script with the appropriate arguments (*), but I was wondering if there might be a better (more efficient, more portable) way.

(*) Including --console=plain, because the parent and child progress bars interfere with each other and there doesn’t seem to be a way to only disable the progress bar. Also including --no-daemon, because stopped daemons can’t seem to be reused by the child processes.

There is a GradleBuild task and there is the Tooling API GradleConnector that you could use like

GradleConnector
    .newConnector()
    .forProjectDirectory(layout.projectDirectory.asFile)
    .connect()
    .use { projectConnection ->
        val buildLauncher = projectConnection
            .newBuild()
            .forTasks("check")
            .setStandardInput(System.`in`)
            .setStandardOutput(System.out)
            .setStandardError(System.err)
            ...
            .run()
    }

But actually both ways sound smelly.
But hard to suggest an alternative from the given information.

Thanks for your pointers! I’ll look into them next week.

What kind of information would you need?

Probably your whole build. :smiley:
For example if those properties are just forwarded to the test task and consumed in the test code or only influence the test task configuration, you could just declare multiple test tasks that are configured accordingly, then you can also test all cases with one Gradle run.
Or you could use some means to test the cases from the test code within one test task.
Or if you those properties change some dependency versions, you could have multiple configurations for each version combination and then derive individual test tasks from those, …

Thank you! I was able to make it work with individual GradleBuild tasks and an entry point task that depends on those. Here are the changes if anyone’s curious. Please don’t judge :wink:

The only non-obvious obstacle was that I had to set a different buildName for each task; otherwise Gradle would complain “Included build /path/to/project has build path :project which is the same as included build /path/to/project”.