动态创建的Copy类型任务始终是UP-TO-DATE

时间:2013-11-27 17:30:59

标签: gradle build.gradle

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

我试图动态创建任务,每个任务对应于项目目录中的文件。这样可以正常工作,但是我创建的任务一旦分配出来就永远不会被执行'复制'。

以下是我的问题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'

这样,当我调用默认任务调用gradle时,我的任务就不会被执行:

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

BUILD SUCCESSFUL

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

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

BUILD SUCCESSFUL

(您需要在templates所在的同一目录中创建文件夹名build.gradle,并将几个空文件放入其中以便运行测试)

根据调试输出:

  

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

     

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

那么如何指定源文件并执行我的Copy任务? 我尝试过添加

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

到任务组,我尝试分配任务inputs.source file('/my/existing/file')但没有成功。 你能否告诉我如何修改我的简单脚本,让动态任务创建并保持Copy类型的动态任务?

谢谢!

编辑: 好的,这样就可以调用任务:

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

但看起来我必须始终指定from / into。在doLast {}体内做到这一点还不够。

4 个答案:

答案 0 :(得分:12)

Copy任务只有在需要复制的情况下才会执行。告诉它要复制什么是配置任务的一部分,因此需要在配置阶段而不是执行阶段中完成。这些是非常重要的概念,您可以在Gradle User GuideGradle Forums上阅读这些概念。

作为执行任务的一部分,

doFirstdoLast块在执行阶段执行。两者都来不及告诉任务要复制什么:doFirst在主任务操作之前立即执行(在这种情况下是复制),但是(很快)在skipped和{{1之后)执行检查(基于任务的配置)。 up-to-date在主要任务操作后执行,因此显然为时已晚。

答案 1 :(得分:2)

我认为以下Gradle User Guide quote最能回答我的问题:

  

其次,当一个任务被用作复制源时(即作为from()的一个参数),copy()方法不能遵守任务依赖性,因为它是一个方法而不是一个任务。因此,如果您使用copy()方法作为任务操作的一部分,则必须显式声明所有输入和输出以获得正确的行为。

答案 2 :(得分:2)

阅读了“最新”复制任务的大部分答案,看来缺少的部分是“包含”关键字:

task copy3rdPartyLibs(type: Copy) {
    from 'src/main/jni/libs/'
    into 'src/main/libs/armeabi/'
    include '**/*.so'
}

答案 3 :(得分:0)

frominto作为doLast部分的一部分不起作用。工作任务定义的一个示例是:

task copyMyFile(type: Copy) {

    def dockerFile = 'src/main/docker/Dockerfile'
    def copyTo = 'build/docker'

    from dockerFile
    into copyTo

    doLast {
        println "Copied Docker file [$dockerFile] to [$copyTo]"
    }
}

不是我期待的行为。 使用gradle 3.2.1