gradle - 如何在 Gradle 中下载和引用单个工件?

标签 gradle dependency-management dependency-resolution

我正在创建一个 Gradle 任务,我想在其中下载并引用 Maven 存储库中存在的工件的 jar 文件。具体来说,我打算通过 Gradle exec 调用外部脚本使用该 jar 的位置作为脚本参数的任务。使用 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"

如何获取工件 jar 的文件路径,并在必要时从远程存储库下载它?例如,如果它不在我的本地工件缓存中,或者它是更新的快照版本,则应该下载它。

最佳答案

假设我们想要的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()
}
这将创建一个自定义 configuration命名为“myArtifact”,仅依赖于 guava-26.0-jre .通过将其标记为 transitive: false任何工件的依赖项都不会包含在配置中,如果它们尚不存在于本地工件缓存中,也不会下载它们。
调用 configurations.myArtifact.singleFile返回 java.io.File对工件的 jar 文件的引用。此 getSingleFile()方法还确保集合中只有一个文件,抛出 IllegalStateException如果有零个或多个。如果将来配置被错误地错误配置为具有多个工件(例如,如果有人从我们的脚本中删除了“传递”选项),这可以防止引用错误的工件。
toAbsolutePath()方法确保脚本的路径是绝对的,因此不需要相对于任何特定目录进行解析。
请注意,这是将工件复制到 the task's temporary directorydoFirst块,而不是直接引用文件的路径。这是为了在加载脚本时不需要解析工件。否则,即使在执行不相关的任务时也需要解析(并可能下载)工件——包括诸如 clean 之类的基本任务。和 tasks — 如果无法解决工件,则会导致构建失败。
StandardCopyOption.REPLACE_EXISTING 选项用于覆盖先前构建中的任何先前 jar 文件。

关于gradle - 如何在 Gradle 中下载和引用单个工件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51794696/

相关文章:

multithreading - 如何指定SBT在任何命令期间使用的线程数?

android - 错误 : Could not Resolve Package Name in Flutter

java - 如何避免 Gradle 的 osgi 插件为私有(private)包生成 export-pacakge 条目,为嵌入式依赖项生​​成 import-package 条目

android - 将项目从 Android Studio 版本 2 转换为 3- 配置问题

php - 需要其他依赖项应该使用的 Composer 的 fork

android - 无法解析 : support-compat ONLY FOR :27. 1.1

android - 使用 apache commons ftp 的 gradle 错误 "ZipException: duplicate entry: org/apache/ftpserver/ftplet/Authentication.class"

javascript - 如何解决内置 AngularJS 应用程序的依赖问题?

java - 如何为移至库的类工厂反转依赖关系