Создание задачи копирования после сборки с помощью Gradle

Я борюсь с жизненным циклом сборки Gradle; особенно с разделением между фазами configuration и execution. Я прочитал несколько разделов в руководстве по Gradle и видел несколько идей в Интернете, но не нашел решения следующей проблемы:

Я хочу запустить определенную задачу для создания артефакта в конце моей сборки java-library-distribution, который представляет собой сглаженную версию jar-файлов конфигурации runtime. То есть я хочу создавать артефакт только тогда, когда запускаю конкретную задачу по созданию артефакта.

Я создал следующую задачу:

task packageSamplerTask(type: Tar, dependsOn: distTar) {
    description "Packages the build jars including dependencies as a flattened tar file. Artifact: ${distsDir}/${archivesBaseName}-${version}.tar"
    from tarTree("${distsDir}/${archivesBaseName}-${version}.tar").files
    classifier = 'dist'
    into "${distsDir}/${archivesBaseName}-dist-${version}.tar"
}

Хотя эта задача действительно создает требуемый артефакт, задача выполняется во время фазы configuration gradle. Такое поведение имеет следующие последствия:

  • Независимо от того, какую задачу я запускаю из командной строки, эта packageSamplerTask задача запускается всегда, часто без необходимости; и
  • Если я clean проект, то при следующем запуске сборка завершится ошибкой, потому что $distsDir не существует на этапе configuration (очевидно).

Похоже, что если я расширяю задачу Copy таким образом, я всегда буду получать такое преждевременное поведение.

Есть ли способ использовать объявления << closure/doLast, чтобы получить то, что я хочу? Или есть что-то еще, что я упускаю/должен делать?

Обновить

После дальнейшей работы я уточнил свои требования и решил свой вопрос следующим образом (в частности):

"Я хочу упаковать свой код и зависимости моего кода в виде плоского архива jar-файлов, который можно развернуть как подключаемый модуль jMeter. Затем пакет можно установить, распаковав в каталог jMeter lib/ext как есть. Таким образом, пакет , не должны включать JAR-файлы jMeter (и их зависимости), которые используются для сборки и тестирования"

Поскольку Gradle не поддерживает подобное Maven управление зависимостями provided, я создал новую конфигурацию для своего пакета, исключающую JAR-файлы jMeter.

configurations {
    jmpackage {
        extendsFrom runtime
        exclude group: 'org.apache.jmeter', name: 'ApacheJMeter_core', version: '2.11'
        exclude group: 'org.apache.jmeter', name: 'ApacheJMeter_java', version: '2.11'
    }
}

А затем создал следующую задачу (используя рекомендацию по закрытию от Питера Нидервизера):

task packageSamplerTask(type: Tar, dependsOn: assemble) {
    from { libsDir }
    from { configurations.jmpackage.getAsFileTree() }
    classifier = 'dist'
}

Похоже, это решение работает и позволяет мне использовать только плагин Gradle java.


person s5b    schedule 10.08.2014    source источник
comment
Откуда distsDir?   -  person Opal    schedule 10.08.2014
comment
@Opal Спасибо за интерес. Переменная distsDir задается как часть подключаемого модуля Java. Вы найдете упоминание об этом в документации Gradle здесь.   -  person s5b    schedule 11.08.2014


Ответы (2)


Объявление задачи в порядке, но выравнивание тоже нужно отложить:

...
from { tarTree("${distsDir}/${archivesBaseName}-${version}.tar").files }

Кроме того, на файл Tar следует ссылаться более абстрактно. Например:

from { tarTree(distTar.archivePath).files }  
person Peter Niederwieser    schedule 10.08.2014

Сначала ваша задача не выполняется на этапе configuration phase, но, как и КАЖДАЯ задача, она настраивается на этом этапе. И ваше закрытие — это просто конфигурация вашей задачи (закрытие конфигурации, а не закрытие действия). Вот почему ваш код «выполняется» на этапе настройки».

Если вы хотите, чтобы ваш код выполнялся в execution phase, вы должны написать его в doLastclosure или doFirst. Но в вашем случае лучше держать его в закрытии конфигурации, потому что вы настраиваете свою задачу.

Чтобы ваша сборка не завершилась ошибкой из-за отсутствия папки, вы можете создать ее с помощью distsDir.mkdirs().

person The End    schedule 11.08.2014
comment
Спасибо за ваш ответ. Извините, я не ясно выразился в своем вопросе. Задача используется для переупаковки runtime артефактов из сборки, включая мой собственный код. Простое создание distsDir может предотвратить сбой задачи, но задача по-прежнему будет выполняться каждый раз при вызове любой цели задачи. Я хочу вызывать эту задачу только тогда, когда я ее запрашиваю, или как зависимость от какой-либо другой задачи, которую я запрашиваю. В зависимости от размера артефакта сборки эта задача может оказывать заметное влияние на прошедшее время сборки, когда эта задача запускается каждый раз. - person s5b; 12.08.2014