OnlyIf affect only task but not tasks that depends on

I have next custom task in Gradle 2.10:

task startDockerCompose(type: ExecWait, dependsOn: ':buildImage') {
}

startDockerCompose.onlyIf {project.hasProperty('env') && project.getProperty('env') == 'local'}

If I run

/gradlew :acceptance-test:startDockerCompose then the output is:

:processResources UP-TO-DATE
:classes UP-TO-DATE
:createBuildInfoFile
:war
:assemble
:buildImage
:acceptance-test:startDockerCompose SKIPPED

But this is not correct because startDockerCompose is skipped and its dependencies should be as well.

This is the expected behavior.

If running the other tasks doesn’t make sense in your case, then all of them should have the onlyIf condition attached to them.

Well it is a bit strange see this, if I do:

startDockerCompose.onlyIf {project.hasProperty('env') && project.getProperty('env') == 'dev'}
rootProject.buildImage.onlyIf {project.hasProperty('env') && project.getProperty('env') == 'dev'}

startDockerCompose.dependsOn rootProject.buildImage
test.dependsOn startDockerCompose

Then it is true the buildImage task is not executed, but yes all the tasks that depends on buildImage:

:processResources UP-TO-DATE
:classes UP-TO-DATE
:createBuildInfoFile
:war
:assemble
:buildImage SKIPPED
:acceptance-test:startDockerCompose SKIPPED

You will agree with me that it is not practical at all having to know the whole hierarchy.

The onlyIf expression can read things that change as the build executes,
for instance

´´´onlyIf { otherTask.didWork}´´´

So we cannot do any up-front analysis who really needs to run.

What problem is this causing for you?

What I want to do is that in case that the user add the project property dev (which means the build is being executed in dev machine), I want to create the war (assemble) build the docker image (buildImage) and then call the docker-compose file passing the docker image that has been created and finally execute the tests. So doing ./gradlew -Penv=dev :acceptance-test:test makes all these steps automatically.

But if I am not in dev (means in Jenkins), when I run :acceptance-test:test I don’t want to start docker-compose and so on since the application is already deployed in PRE. But then when I execute the :acceptance-test:test task it is true that does not start the docker-compose, but it creates the war again, which is totally useless since this stage has been already executed in the past and now I don’t want to do the war again.

In that case the question becomes: Why does the test task depend on dockerCompose if you don’t want it? You could set up the dependency conditionally:

if (project.env == 'local') {
 test.dependsOn(startDockerCompose)
}

So true :S The forrest didn’t let me see the tree :slight_smile: Thank you so much

1 Like