Strange copy task behavior


(Damon Kohler) #1

I would expect both of these task definitions to behave in the same way:

task a(type: Copy) {
   from configurations.compile.copy().setTransitive(false)
   into "${projectDir}/libs"
}
  task b << {
   copy {
      from configurations.compile.copy().setTransitive(false)
      into "${projectDir}/libs"
   }
}

However, only task b works. In task a, it seems that configurations.compile.copy() is empty.

As an aside, I’m having difficulty figuring out how to look up documentation for the copy syntax used in task b. However, I found the DSL guide for Copy easily enough.

$ gradle --version
  ------------------------------------------------------------
Gradle 1.0-milestone-8a
------------------------------------------------------------
  Gradle build time: Monday, February 20, 2012 4:00:18 PM UTC
Groovy: 1.8.4
Ant: Apache Ant(TM) version 1.8.2 compiled on December 20 2010
Ivy: 2.2.0
JVM: 1.6.0_20 (Sun Microsystems Inc. 19.0-b09)
OS: Linux 2.6.32-37-generic amd64

(Peter Niederwieser) #2

The syntax for the ‘copy’ method is exactly the same as that for the ‘Copy’ task. Your declarations aren’t the same, however. In the first case, the copy operation gets configured at configuration time, whereas in the second case, it gets configured at execution time. According to your description, it seems like the compile dependencies haven’t been configured when task ‘a’ gets evaluated. One way to solve this problem is to defer the evaluation of ‘from’ by way of a closure:

from { configurations.compile.copy().setTransitive(false) }

Another difference is that the first task will only run if necessary, whereas the second task will always run because its inputs and outputs haven’t been declared. Unless you have a concrete reason not to, you should always prefer the ‘Copy’ task over the ‘copy’ method.


(Sergei Kobiakov) #3

Hm, I got the same problem and not fully understood. Here even more easy example:

task deploy(type: Copy) << {
 from <any folder>
 into <any other folder>
                 }
task deploy(type: Copy) {
 from <any folder>
 into <any other folder>
                 }

In the first case the task simly not works, and if there is anywhere specified why? Or any ideas?


(Peter Niederwieser) #4

‘<<’ is a shortcut for ‘doLast {}’ and is the wrong way to configure a task. It means that the task will only get configured in the execution phase, after it has run. You can read up on task actions in the Gradle User Guide.


(Sergei Kobiakov) #5

Thanks, I am still slightly confused with understanding: tasks of which types it is possible to use during execution phase with << shortcut and for which, like task type: “Copy”, it is the wrong way to configure a task


(Peter Niederwieser) #6

Tasks should always be configured in the configuration phase (except for some edge cases). ‘<<’ adds a task action, which tells the task what to do when it executes. By giving a task an explicit type, you also give it a task action (because each task type defines an action). You can learn more about these concepts in the Gradle User Guide.


(Sergei Kobiakov) #7

Thanks, once more, now, it seems a little bit more clear