Как определить пользовательскую задачу Gradle, которая пропускает зависимости, если выходной файл новее, чем входной файл - PullRequest
0 голосов
/ 02 июля 2018

У меня есть проект gradle со следующей структурой:

У меня есть последовательность задач (назовем их taskA, taskB, taskC), которые берут один входной файл (назовем его source.tar.gz) и генерируют выходной файл (назовем его dist.tar.gz). , Предположим, что taskA / taskB / taskC потребуется запустить процессы и т. Д.

У меня также есть задача (называемая taskZ), которая обеспечивает очистку после taskA, taskB, taskC. Предположим, он остановит процессы, запущенные первым набором задач.

У меня есть пользовательская задача make, которая зависит от сборки и ее завершения. Примерно так:

task make {
    dependsOn taskA, taskB, taskC
    finalizedBy taskZ
}

Наконец, встроенная задача gradle для сборки зависит от моей пользовательской задачи make.

Я хотел бы сообщить сотрудникам Gradle, что вход make - это файл 'source.tar.gz', а вывод - 'dist.tar.gz', поэтому make 'не нужно запускать, если' dist.tar.gz ' новее, чем source.tar.gz.

Я попытался объявить ввод и вывод «make» следующим образом:

task make {
    dependsOn taskA, taskB, taskC
   finalizedBy taskZ

   inputs.file("$projectDir/src/main/source.tar.gz")
   outputs.file("$buildDir/dist.tar.gz")
}

Но gradle все еще запускает весь процесс.

Можно ли как-нибудь сказать gradle пропустить задачу make и ее зависимости?

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Я решил свою проблему, следуя предложению @ lu.koerfer. Я задаю для задач taskA, taskB, taskC, make, taskZ одинаковые входы и выходы. Я также пометил taskB, taskC, taskZ, чтобы он выполнялся только в том случае, если задача A не была UP-TO-DATE.

При такой конфигурации задача A будет работать только в том случае, если gradle использует собственный механизм для выполнения задачи A, и только если задача A не помечена как UPD-DATE датой gradle, тогда остальные задачи будут выполняться.

task taskA {
    ...
}

task taskB {
    ...
    onlyIf { !taskA.state.upToDate }
}

task taskC {
    ...
    onlyIf { !taskA.state.upToDate }
}

task taskZ {
    ...
    onlyIf { !taskA.state.upToDate }
}

task make {
    dependsOn taskA, taskB, taskC
    finalizedBy taskZ
    ...
}

[taskA, taskB, taskC, taskZ, make].each { t ->
   t.inputs.file("$projectDir/src/main/source.tar.gz")
   t.outputs.file("$buildDir/dist.tar.gz")
}

Это работает как ожидалось. Иногда механизм Gradle до даты может не работать. Если вам нужно принудительно запустить все задачи, просто запустите:

./gradlew make --rerun-tasks
0 голосов
/ 02 июля 2018

Инкрементная сборка Gradle основана не только на временных метках (временные метки могут даже не учитываться в наши дни), поэтому это не поможет с тем, что ты пытаешься сделать. Кроме того, я уверен, что задачи A -> C всегда будут выполняться, даже если make настроен таким образом. make сначала должен убедиться, что его зависимости запущены или уже обновлены.

Учитывая это, я думаю, вам может понадобиться использовать специальную проверку меток времени в проверке onlyIf(). Что-то вроде:

make.onlyIf { inputFile.lastModified() > outputFile.lastModified() }

, где inputFile и outputFile - пути к соответствующим файлам (например, project.file()). Я не думаю, что это ужасно надежно, но этого может быть достаточно для вашего варианта использования.

В качестве альтернативы, создайте пользовательскую задачу, которая выполняет B и C вместе, если вы можете настроить такую ​​задачу с соответствующими определенными входами и выходами. Я думаю, что это лучшее решение на основе предоставленной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...