动态创建的Copy类型任务始终是UP-TO-DATE [英] Dynamically created task of type Copy is always UP-TO-DATE

查看:282
本文介绍了动态创建的Copy类型任务始终是UP-TO-DATE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我准备了一个非常简单的脚本,说明了我使用Gradle 1.7看到的问题(由于某些插件尚未支持新版本,因此需要坚持使用它)。



我试图动态创建每个对应于项目目录中的文件的任务。这工作正常,但我创建的任务从未被执行,只要我给他们分配类型'复制'。



这是我的问题 build。 gradle

  file('templates')。listFiles()。each {File f  - > ; 

//这行不起作用
任务myDist - $ {f.name}(type:Copy){

//下一行工作
//任务myDist - $ {f.name}{
doLast {
printlnMYDIST-+ f.name
}
}
}

任务distAll(dependsOn:tasks.matching {任务任务 - > task.name.startsWith(myDist)}){
printlnMYDISTALL
}

defaultTasks'distAll'

这样我的任务不会在执行时被执行我将调用默认任务简单地称为 gradle

  MYDISTALL 
:myDist-template1升级日期
:myDist-template2升级日期
:distAll升级日期

制造成功

如果我从我的动态任务中删除类型 Copy (取消上面的行注释) ,我的任务被执行:

  MYDISTALL 
:myDist-template1
MYDIST-template1
:myDist-template2
MYDIST-模板2
:distAll

建立成功



<您>需要在 build.gradle 所在的同一目录中创建一个文件夹名称 templates ,并将几个空文件放入那里为了运行测试)

根据调试输出:


跳过任务':myDist-template1',因为它没有源文件。



跳过任务':myDist-template2',因为它没有源文件。


那么如何指定源文件并使我的 Copy 任务执行?
我试过从('/ absolute / path / to / existing / file'){
到'myfolder'
}

到任务正文,我试过了分配任务的 inputs.source文件('/ my / existing / file')没有成功。
请问如何修改我的简单脚本,让我创建动态任务,并保留我的 Copy >动态任务?



谢谢!

编辑:
好​​的,这样任务被调用:

  file('templates')。listFiles()。each {File f  - > 
任务myDist - $ {f.name}(类型:复制){
从f
到'dist'
doLast {
printlnMYDIST- + f.name
}
}
}

但它看起来我必须总是从 / 中指定

解决方案

A 复制

code>任务只有在需要复制时才会执行。告诉它要拷贝什么是配置任务的一部分,因此需要在配置阶段中完成,而不是在执行阶段中完成。这些都是非常重要的概念,您可以在 Gradle用户指南或在 Gradle论坛上。



doFirst doLast 块会在执行过程中执行阶段,作为执行任务的一部分。两者都不能告诉任务要复制的内容: doFirst 在主任务操作(在本例中为复制)之前立即执行,但在跳过最新检查(基于任务的配置)。 doLast 会在主要任务操作后执行,因此显然太晚了。


I've prepared a very simple script, that illustrates the problem I see using Gradle 1.7 (need to stick with it because of some plugins not yet supporting newer versions).

I'm trying to dynamically create tasks each of which corresponds to a file in the project directory. This works fine, but the tasks I create never get executed as soon as I assign them type 'Copy'.

Here is my problem build.gradle:

file('templates').listFiles().each { File f ->

    // THIS LINE DOES NOT WORK
    task "myDist-${f.name}" (type: Copy) {

    // NEXT LINE WORKS
    //task "myDist-${f.name}" {
        doLast {
            println "MYDIST-" + f.name
        }
    }
}

task distAll(dependsOn: tasks.matching { Task task -> task.name.startsWith("myDist")}) {
    println "MYDISTALL"
}

defaultTasks 'distAll'

in this way my tasks do not get executed when I call default task calling simply gradle:

MYDISTALL
:myDist-template1 UP-TO-DATE
:myDist-template2 UP-TO-DATE
:distAll UP-TO-DATE

BUILD SUCCESSFUL

If I remove type Copy from my dynamic task (uncommenting the line above), my tasks get executed:

MYDISTALL
:myDist-template1
MYDIST-template1
:myDist-template2
MYDIST-template2
:distAll

BUILD SUCCESSFUL

(You'll need to create a folder name templates in the same directory where build.gradle is located and put couple of empty files into there in order to run the test)

According to the debug output:

Skipping task ':myDist-template1' as it has no source files.

Skipping task ':myDist-template2' as it has no source files.

So how can I specify source files and make my Copy tasks execute? I've tried adding

from( '/absolute/path/to/existing/file' ) {
    into 'myfolder'
}

to the task body, I've tried assigning task's inputs.source file('/my/existing/file') with no success. Could you please advise on how to modify my simple script leaving dynamic task creation and keeping my dynamic tasks of type Copy?

Thank you!

Edit: All right, this way the task gets called:

file('templates').listFiles().each { File f ->
    task "myDist-${f.name}" (type: Copy) {
        from f
        into 'dist'
        doLast {
            println "MYDIST-" + f.name
        }
    }
}

but it looks I must always specify from/into. It doesn't suffice to do that in the doLast{} body.

解决方案

A Copy task only gets executed if it has something to copy. Telling it what to copy is part of configuring the task, and therefore needs to be done in the configuration phase, rather than the execution phase. These are very important concepts to understand, and you can read up on them in the Gradle User Guide or on the Gradle Forums.

doFirst and doLast blocks get executed in the execution phase, as part of executing the task. Both are too late to tell the task what to copy: doFirst gets executed immediately before the main task action (which in this case is the copying), but (shortly) after the skipped and up-to-date checks (which are based on the task's configuration). doLast gets executed after the main task action, and is therefore clearly too late.

这篇关于动态创建的Copy类型任务始终是UP-TO-DATE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆