Execute download task before model is configured


I’m trying to configure a native library (google-test), for which the sources are downloaded during the build. The problem is that if the source files are not present at the time the model is configured, nothing will be built when executing the corresponding task, even if the source files are present at that time. I basically need to run a task before the model is configured, or I need to force the model to reconfigure after a certain task is executed. Otherwise I have to run the task always twice. Is this possible?

plugins {
  id "cpp"
  id "google-test"
  id "de.undercouch.download" version "1.2"
model {
  components {
    gtest(NativeLibrarySpec) {
      sources.cpp(CppSourceSet) {
        source.srcDir "${buildDir}/downloads/gtest"
        source.include 'src/gtest-all.cc'
        exportedHeaders.srcDir "${buildDir}/downloads/gtest"
        exportedHeaders.srcDir "${buildDir}/downloads/gtest/include"
  tasks {
    linkGtestSharedLibrary.dependsOn unzipGoogleTest
    createGtestStaticLibrary.dependsOn unzipGoogleTest

import de.undercouch.gradle.tasks.download.Download
task downloadGoogleTest(type: Download) {
  version = '1.7.0'
  src "https://googletest.googlecode.com/files/gtest-${version}.zip"
  dest new File(buildDir, "downloads/gtest-${version}.zip")
  outputs.file dest

task unzipGoogleTest(dependsOn: downloadGoogleTest) {
  def dest = new File(buildDir, 'downloads/gtest')
  inputs.file downloadGoogleTest.dest
  outputs.dir dest
  doLast {
    copy {
      from zipTree(downloadGoogleTest.dest)
      into "${buildDir}/downloads"
    new File(downloadGoogleTest.dest.path[0..-5]).renameTo(dest)

The rule based model configuration is built thanks to Rules, and the notion of subjects and inputs.
The model guarantees that all inputs of a given rule are properly configured before the rule is executed.
What you need is to create a @Model Rule to create your gtest(NativeLibrarySpec) element, using as inputs the downloadGoogleTest task results.

Something ‘like’

void gtest(NativeLibrarySpec spec, 'downloadGoogleTest results') {}

Maybe someone could confirm or elaborate on this.
I’m not sure that this could be done at the time being. How can we use a task output as rule input ?

Just inline configuration in your build script to do this, outside of a task. Currently we evaluate the build script before any of the component rules.

That actually answers my question, but I was hoping for something like what François mentioned . Your approach is very imperative and would require me to implement the UP-TO-DATE logic by myself. That’s pretty simple in my case (checking if a directory exists), but not very pretty.
Something like what François mentioned is not possible yet?

Technically yes, but it wouldn’t solve the incremental problem because we would still treat the result as configuration (which we don’t yet cache), and therefore you wouldn’t get the benefits of UP-TO-DATE checking. Either way, if you want to cache an expensive result which in turn an input to more configuration you’ll have to implement that yourself.