Как я могу загрузить и сослаться на один артефакт в Gradle?

Я создаю задачу Gradle, в которой я хочу загрузить и сослаться на файл jar для артефакта, который существует в репозитории Maven. В частности, я планирую вызвать внешний скрипт через задачу Gradle exec, используя местоположение этого фляги в качестве аргумента скрипта. Использовать задачу exec просто; я пытаюсь выяснить, как определить местоположение файла jar артефакта в файловой системе.

В качестве простого, но конкретного примера, предположим, что у меня есть следующие файлы в каталоге проекта Gradle:

build.gradle:

task myScript(type: Exec) {
    executable './my_script.sh'
    args jarFilePath // How do I get this value?
}

my_script.sh:

#!/usr/bin/env bash
echo "Jar file location: $1"

Как я могу получить путь к файлу к банке артефакта, при необходимости загрузив его из удаленного хранилища? Например, его следует загрузить, если его нет в моем локальном кэше артефактов, или это обновленная версия снимка.

1 ответ

Решение

Давайте предположим, что файл JAR, который мы хотим, guava-26.0-jre.jar, Следующие build.gradle file извлечет артефакт (при необходимости) и предоставит местоположение файла в качестве аргумента сценария:

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption

repositories {
    mavenCentral()
}

configurations {
    myArtifact
}

dependencies {
    myArtifact group: 'com.google.guava', name: 'guava', version: '26.0-jre', transitive: false
}

task myScript(type: Exec) {
    Path artifactPath = temporaryDir.toPath().resolve('guava.jar').toAbsolutePath()

    doFirst {
        Files.copy(configurations.myArtifact.singleFile.toPath(), artifactPath, StandardCopyOption.REPLACE_EXISTING)
    }

    executable './my_script.sh'
    args artifactPath.toString()
}

Это создает пользовательскую конфигурацию с именем "myArtifact" с единственной зависимостью от guava-26.0-jre, Помечая это как transitive: false ни одна из зависимостей артефакта не будет включена в конфигурацию и не будет загружена, если они еще не существуют в локальном кэше артефакта.

Призыв к configurations.myArtifact.singleFile возвращает java.io.File ссылка на файл jar артефакта. Этот метод getSingleFile() также гарантирует, что в коллекции находится ровно один файл, IllegalStateException если есть ноль или более одного. Это защищает нас от ссылки на неправильный артефакт, если в будущем конфигурация будет неправильно настроена на наличие нескольких артефактов (например, если кто-то удалит параметр "переходный процесс").

Метод toAbsolutePath() гарантирует, что путь к сценарию является абсолютным, и, следовательно, не требует разрешения относительно какого-либо конкретного каталога.

Обратите внимание, что это копирование артефакта во временный каталог задачи в блоке doFirst, а не прямая ссылка на путь файла. Это связано с тем, что артефакт не нужно разрешать при загрузке скрипта. В противном случае, артефакт должен быть разрешен (и, возможно, загружен) даже при выполнении несвязанных задач, включая такие основные задачи, как clean а также tasks - вызвать сбой сборки, если артефакт не может быть разрешен.

StandardCopyOption.REPLACE_EXISTING опция используется для перезаписи любого предыдущего файла jar из предыдущих сборок.

Следующий фрагмент с копией задачи copyDependencies работает как для одной, так и для нескольких зависимостей. Вы можете определить любые другие задачи (например, типа Exec), которые зависят от этой задачи.

configurations {
    web {
        transitive = false
    }
}

dependencies {
    web "com.foo:foo-messaging:$version:@war",
            "com.foo:foo-ng:$version:@war"
}

task copyDependencies(type: Copy) {
    from configurations.web
    into "$buildDir/web"
}
Другие вопросы по тегам