Copy task not working

I am trying to copy the scripts from Project directory to deploy directory which is not working.

task copyScriptsToBuild(type: Copy) {
doLast{
from “$rootDir/AppScripts”
into “$buildDir/output/bin”
}
}

When i run the gradle copyScriptsToBuild task its not copying the files to destination directory.

But when i try the below with out doLast action it is working fine.

task copyScriptsToBuild(type: Copy) {
from “$rootDir/AppScripts”
into “$buildDir/output/bin”
}

can someone help me to understand when we should use doFirst/doLast actions in the task!

doFirst and doLast allow you to perform custom actions before and after the task itself is executed.

The timeline is something like:

  • Your build.gradle is executed and the task copyScriptsToBuild is created/registered.
    If the task is created the code inside the { and } is executed.
    If it is only registered this step delayed.
  • Gradle calculates which tasks should be executed and executes the code inside the { and } for tasks which have only been registered, and are now created. (Note that Gradle can skip this part for tasks which are not needed.)
  • Then tasks are started. (if possible in parallel but usually tasks depend on each other):
    1. call doFirst of the task
    2. perform the task action
    3. call doLast of the task

As the copy-task (step 2) is executed before doLast (step 3) your first code sample would configure the task after it had already completed.
It might be possible to configure the task in doFirst but in any case you should not configure your task during the execution step.

You second code sample is the correct way. You are configuring the Copy task during the configuration phase.

An example where I use the doFirst function: the swagger codegen task creates code, but doesn’t empty the target directory. I now delete all files in the target directory in the doFirst function.

You could also output debug statements in doFirst and doLast

Disclaimer: this is my understanding. I hope it’s correct. Please correct any mistakes

Additional edit:
from "$rootDir/AppScripts" and into "$buildDir/output/bin" do not perform any actions.
Those code lines only configure the Copy task!

1 Like

Hi Christian, Thank you for your response.

As you asked for it. :slight_smile:

Note that Gradle can skip this part for tasks which are not needed.

If the task would have been registered, that would be correct.
In the shown example though eager API is used that does not leverage task configuration avoidance.
So in the shown case the configuration code is always executed.

  1. call doFirst of the task
  2. perform the task action
  3. call doLast of the task

plural for the 1 and 3, you can register multiple doFirst and doLast actions

As the copy-task (step 2) is executed before doLast (step 3) your first code sample would configure the task after it had already completed.
It might be possible to configure the task in doFirst

I don’t think it is possible in doFirst because before doFirst is executed the inputs and outputs are checked and Gradle will see that there are no inputs and don’t even start to execute the task.

but in any case you should not configure your task during the execution step.

very true and important especially for upcoming configuration cache.
But also for up-to-date checking (and caching for cacheable tasks).

1 Like