Behavior when depending on assemble life-cycle task

I’m puzzled by the behavior of the assemble life-cycle task.
Below a minimal example.

Root build.gradle file is:

plugins {
    id 'base'
}

task task1 {
    doLast {
        println 'Task #1'
    }
}

task task2 {
    dependsOn assemble
    doLast {
        println 'Task #2'
    }
}

assemble.dependsOn(task1)

Sub-project a/build.gradle file is:

plugins {
    id 'base'
}

task task3 {
    doLast {
        println 'Task #3'
    }
}

assemble.dependsOn(task3)

settings.gradle file is:

include 'a'

Executing assemble task:

> gradle assemble

> Task :task1
Task #1

> Task :a:task3
Task #3

Executing task2 gives:

> gradle task2   

> Task :task1
Task #1

> Task :task2
Task #2

Why is task3 executed when executing assemble task directly but not when executing task2? I was assuming that assemble is special in the sense that it depends on all sub-projects assemble tasks but it does not seem to hold when a task depends on assemble. I must be doing something wrong but I can’t figure out what…

There is no dependency relationship between the :assemble and :a:assemble tasks. They are independent tasks. Running gradle assemble is not the same as running gradle :assemble.

When you run gradle assemble, you are asking Gradle to run the assemble task in every project in the build, not just the root project :assemble task. The :a:assemble task is running because you’re asking for it to run, not because of a task dependency.

More Info:
https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_executing_tasks