Gradle 1.8 ошибочно сообщает, что задание обновлено

Это довольно распространенный сценарий, когда для проекта требуются две разновидности JavaScript-зависимостей сторонних производителей. Для целей разработки используются неминифицированные версии файлов JavaScript, в то время как сценарий развертывания обычно включает только минимизированные версии (*.min.js). Давайте предположим, что обе версии (минимизированные и не минимизированные) находятся в папке 'repo'. Кроме того, есть 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 сообщается, что нежелательно и, насколько я понимаю, неверно.

Я что-то пропустил? Заранее спасибо, Саш

РЕДАКТИРОВАТЬ:

Принимая во внимание комментарии ниже, более правильно 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 НЕ копировать файлы, которые 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?

Заранее спасибо, Саш

1 ответ

Глядя на код, мне не ясно, что вы пытаетесь сделать здесь. Минимальный пример поможет.

Некоторые общие подсказки (я не мог сделать это комментарием, потому что это слишком долго):

  • createMain ничего не делает, что означает, что copyMain задач не будет ничего копировать (если вы не поставите вручную main.js а также main.min.js файлы на месте пока).
  • copyMain а также copyMainForDeploy создайте один и тот же файл в том же месте, что означает, что они будут перезаписывать выходные данные друг друга, что делает другую задачу устаревшей.
  • Зависимости задачи не имеют смысла, потому что (скажем) installJSDeps не потребляет ничего, что copyMain производит (то есть нет никакой семантической зависимости между двумя задачами).
  • Я не понимаю почему deps.json будет вклад в Copy задачи. Кроме того, типы задач, такие как Copy автоматически объявлять свои входы и выходы в зависимости от того, как они настроены (например, from а также into), что означает, что они не должны быть объявлены в скрипте сборки.
  • Вместо from('.') { include 'foo' }, from 'foo' должен быть использован.
  • Вместо удаления содержимого целевого каталога перед копированием, Sync задача должна быть использована (которая настраивается точно так же, как Copy).
Другие вопросы по тегам