Artifact builtBy task is not called when resolving a configuration

Given the following, I expected the task buildIt to run as a result of running the useIt task, since the useIt task causes the myConfig configuration to be resolved. Am I doing something wrong or otherwise not understanding something?

Thanks, Chris

allprojects {
    configurations {
        myConfig
    }
}
project( ':subproject' ) {
    ext.theFile = file( 'some.file' )
    task buildIt << {
        println 'building'
        theFile.withWriter { it.println 'test' }
    }
    artifacts {
        myConfig file: theFile, builtBy: buildIt
    }
}
dependencies {
    myConfig project( path: ':subproject', configuration: 'myConfig' )
}
task useIt << {
    configurations.myConfig.each {
        println it
    }
}

$ ./gradlew useIt
:useIt
/home/cdore/sandbox/gradle-configurationartifacts-test/subproject/some.file
BUILD SUCCESSFUL

I think you need to add

evaluationDependsOn ":subproject" 

Thanks for the suggestion Lance.

I gave it a test and unfortunately it didn’t help.

useIt doesn’t have a dependency on configurations.myConfig, so Gradle can’t infer the dependency on buildIt

Try:

task useIt {
    dependsOn configurations.myConfig
    doLast {
        configurations.myConfig.each {
            println it
        }
    }
}

Thank you Sterling, that was the missing piece to the puzzle.

I was not aware that configurations could be used as task dependencies. Also, clearly my thinking that the configuration resolution would somehow trigger the task to execute was incorrect. Which make sense if you consider the fact that a configuration could be resolved at configuration time.

Thanks again,
Chris

Yep, a task can depend on many things. The important one here is the Buildable type. A Configuration is buildable.

1 Like

I was not aware that configurations could be used as task dependencies

That’s news to me too

@sterling, would it be a safe “rule” to say that any task that uses a resolved configuration during its task action, should also declare a dependency on that configuration?

We haven’t been doing that in the past. I think we’ve just been getting away with it because all of the dependencies have been from maven repositories where simply triggering the resolution does the trick.

Yes, I think that’s safer.

Better yet the Configuration should be declared as an input so that it affects incremental builds.

@mark_vieira, to clarify, are you suggesting that the configuration should be declared as an input instead of a task dependency or in addition to. I think you mean in addition to.

What would be the proper way to declare a configuration as an input without triggering a resolve at config time? I ask because I’ve experimented with this in past and ended up with bad results. I was probably doing something wrong.

Adding it as an input will additionally add it as an inferred dependency. You don’t need to explicitly do both.

Doing something like inputs.files configurations.foo shouldn’t trigger resolution until execution time.

Thanks for the info guys. Seems like some basic/core things I’ve missed along the years and I can already tell this is going to help out.

Regarding the inferred dependency from task inputs, is that documented somewhere?

Just now taking a look, I suppose we don’t. We casually mention “task dependency interference” in example 15.14 in the user guide. We should add a section about this.

Yes, that does seem like an important concept that is well buried. Chapter 14 is where I would naturally go looking for this type of information. I suggest a good place to document it might be in or around section 14.9 and possibly referenced in section 14.4.