【问题标题】:Gradle 1.8 erroneously reports a task is UP-TO-DATEGradle 1.8 错误地报告任务是最新的
【发布时间】:2014-02-05 08:32:54
【问题描述】:

这是一个非常常见的场景,当一个项目需要两种类型的 3rd 方 JavaScript 依赖项时。出于开发目的,使用非缩小版本的 JavaScript 文件,而部署场景通常只包括缩小版本 (*.min.js)。 让我们假设所有依赖项的两个(缩小和非缩小)版本都在“repo”文件夹中。此外,'main' 文件有 2 个版本,一个使用缩小的 deps 'main.min.js',而 'main.js' 使用非缩小的。让我们假设两个“主”文件都可以通过某种方式从声明所有依赖项的“deps.json”生成。文件结构如下:

public/
    lib/
repo/
        angular/
            ...
        angular-resource/
            ...
        angular-route/
            ...
build.gradle
deps.json
main.js
main.min.js

public文件夹是所有输出文件应该出现的地方,所以我写了对应的build.gradle文件:

task createMain {
    inputs.file 'deps.json'
    // TODO: read deps.json and create  main.min.js and './main.js
    outputs.file 'main.min.js'
    outputs.file 'main.js'
}

task copyMain(type: Copy, dependsOn: createMain) {
    from('.') {
        include 'main.js'
    }
    into('public')
}

task copyMainForDeploy(type: Copy, dependsOn: createMain) {
    from('.') {
        include 'main.min.js'
    }
    rename('main.min.js','main.js')
    into('public')
}

task installJSDeps(type: Copy, dependsOn: copyMain){
    from('repo')
    into('public/lib')
    outputs.dir 'public/lib'
    inputs.file 'deps.json'
}

task installJSDepsForDeploy(type: Copy, dependsOn: copyMainForDeploy){
    from('repo'){
        include '**/*.min.js'
    }
    into('public/lib')
    outputs.dir 'public/lib'
    inputs.file 'deps.json'


    doFirst {
        //clean up any existing files before copying new ones
        FileTree tree = fileTree (dir: "public/lib");  
        delete(tree)
    }
}

我希望实现的是:如果我调用installJSDepsForDeploy,则只有缩小的文件出现在public/lib 中,如果我调用installJSDeps,所有文件都出现在public/lib 中(除了main 文件被复制/重命名)。 会发生以下情况:

$ gradle installJSDepsForDeploy
:createMain UP-TO-DATE
:copyMainForDeploy
:installJSDepsForDeploy

BUILD SUCCESSFUL

Total time: 3.698 secs

$ gradle installJSDeps
:createMain UP-TO-DATE
:copyMain
:installJSDeps

BUILD SUCCESSFUL

Total time: 2.484 secs

$ gradle installJSDepsForDeploy
:createMain UP-TO-DATE
:copyMainForDeploy
:installJSDepsForDeploy UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.41 secs

第二次报告:installJSDepsForDeploy UP-TO-DATE,这是不希望的,据我了解,不正确。

我错过了什么吗? 提前致谢, 腰带

编辑:

考虑到下面的 cmets,更多正确的 build.gradle 文件将是:

task createMain {
    inputs.file 'deps.json'
    // ASSUME: read deps.json and create  main.min.js and './main.js
    outputs.file 'main.min.js'
    outputs.file 'main.js'
}

task copyMain(type: Copy, dependsOn: createMain) {
    from('.') {
        include 'main.js'
    }
    into('public')
}

task copyMainForDeploy(type: Copy, dependsOn: createMain) {
    from('.') {
        include 'main.min.js'
    }
    rename('main.min.js','main.js')
    into('public')
}

task fetchJSDeps {
    // ASSUME: reads `deps.json` and fetches
    // all the deps into `repo` folder
    outputs.dir 'repo'
    inputs.file 'deps.json'        
}

task installJSDeps(type: Copy, dependsOn: ['copyMain','fetchJSDeps']){
    from('repo')
    into('public/lib')
    outputs.dir 'public/lib'
    inputs.file 'deps.json'
}

task installJSDepsForDeploy(type: Copy, dependsOn: ['copyMainForDeploy','fetchJSDeps']){
    from('repo'){
        include '**/*.min.js'
    }
    into('public/lib')
    outputs.dir 'public/lib'
    inputs.file 'deps.json'


    doFirst {
        //clean up any existing files before copying new ones
        FileTree tree = fileTree (dir: "public/lib");  
        delete(tree)
    }
}

对应的输出还是:

$ gradle installJSDepsForDeploy
:createMain UP-TO-DATE
:copyMainForDeploy
:fetchJSDeps UP-TO-DATE
:installJSDepsForDeploy

BUILD SUCCESSFUL

Total time: 2.769 secs

$ gradle installJSDeps
:createMain UP-TO-DATE
:copyMain
:fetchJSDeps UP-TO-DATE
:installJSDeps

BUILD SUCCESSFUL

Total time: 2.519 secs

$ gradle installJSDepsForDeploy
:createMain UP-TO-DATE
:copyMainForDeploy
:fetchJSDeps UP-TO-DATE
:installJSDepsForDeploy UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.376 secs

更新:

我尝试了很多不同的设置,但在我看来 Gradle 不支持此类任务。本质上,我想要taskA 复制自:

/repo/**/*.js
/repo/**/*min.js
/repo/**/*min.js.map
/repo/**/*.css
/repo/**/*.md

到:

/public/lib/**/*min.js
/public/lib/**/*min.js.map

我想要taskB 复制自:

/repo/**/*.js
/repo/**/*min.js
/repo/**/*min.js.map
/repo/**/*css
/repo/**/*.md

到:

/public/lib/**/*.js
/public/lib/**/*.css
/public/lib/**/*.md

任务相互依赖,这实际上是这里的重点。此外,我希望 TaskA NOT 复制 TaskB 正在复制的文件。两个任务都需要确保完成后另一个任务正在复制的文件不存在

基本上,在运行gradle taskA 之后,public/lib 应该包含

/public/lib/**/*min.js
/public/lib/**/*min.js.map

不是

/public/lib/**/*.js
/public/lib/**/*.css
/public/lib/**/*.md

运行 `gradle taskB' 后,结果应该是相反的。 在 Gradle 中可以做到这一点吗?

提前致谢, 腰带

【问题讨论】:

    标签: javascript gradle


    【解决方案1】:

    查看代码,我不清楚您要在这里做什么。一个最小的例子会有所帮助。

    一些一般性提示(由于太长,我无法对此发表评论):

    • createMain 什么都不做,这意味着 copyMain 任务将没有任何要复制的内容(除非您现在手动放置 main.jsmain.min.js 文件)。
    • copyMaincopyMainForDeploy 在同一个地方创建同一个文件,这意味着它们会不断覆盖彼此的输出,从而使另一个任务过时。
    • 任务依赖没有意义,因为(比如说)installJSDeps 不消耗copyMain 产生的任何东西(即两个任务之间没有语义依赖)。
    • 我不明白为什么deps.json 会成为Copy 任务的输入。此外,诸如Copy 之类的任务类型会根据它们的配置方式(例如frominto)自动声明它们的输入和输出,这意味着它们不必在构建脚本中声明。
    • 应该使用from 'foo' 而不是from('.') { include 'foo' }
    • 与其在复制前删除目标目录的内容,不如使用Sync 任务(其配置方式与Copy 完全相同)。

    【讨论】:

    • 感谢您的回答。 createMain 对本演示没有任何作用,让我们假设它按照评论中所说的那样做:创建 2 个 main.js 文件,它们已经存在。你是对的:两个任务在同一个地方创建同一个文件。但确切地说:installJSDepsinstallJSDepsForDeploy 创建更多 个文件,两者生成的文件都是*.min.js。此外,我同意你的观点:我希望他们会让彼此过时,这是故意的,但这正是不会发生的,这就是问题所在。跨度>
    • installJSDepsinstallJSDepsForDeploy 不要让彼此过时;事实上,前者将使后者最新。也许您正在寻找的是将文件与Sync 任务同步,而不是使用Copy 任务复制它们。这将删除目标目录中未复制的所有文件。
    • 我不知道Copy 任务会自动声明inputsoutputs,坦率地说,我没有注意到阅读任务文档(可能错过了它)。还有很多其他任务可以做同样的事情吗? (快速谷歌搜索没有多大帮助)。 Sync 任务听起来像我需要的,会试一试。
    • 了解可用任务类型的最佳位置是Gradle Build Language Reference
    猜你喜欢
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 2015-04-03
    • 1970-01-01
    相关资源
    最近更新 更多