4

我正在创建一个 Gradle 任务,我想在其中下载并引用 Maven 存储库中存在的工件的 jar 文件。具体来说,我计划通过 Gradle exec任务调用外部脚本,使用该 jar 的位置作为脚本的参数。使用 exec 任务很简单;我想弄清楚的是如何在文件系统上获取工件的 jar 文件的位置。

作为一个简单而具体的示例,假设我的 Gradle 项目目录中有以下文件:

构建.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 的文件路径,并在必要时从远程存储库下载它?例如,如果它不在我的本地工件缓存中,或者它是更新的快照版本,则应该下载它。

4

2 回答 2

7

假设我们想要的 jar 文件是guava-26.0-jre.jar. 以下build.gradle文件将检索工件(如有必要)并将文件位置作为参数提供给脚本:

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块中的任务临时目录,而不是直接引用文件的路径。这是为了在加载脚本时不需要解析工件。否则,即使在执行不相关的任务(包括诸如和之类的基本任务)时,也需要解析(并且可能下载)工件,如果无法解析工件,则会导致构建失败。cleantasks

StandardCopyOption.REPLACE_EXISTING选项用于覆盖以前构建中的任何以前的 jar 文件。

于 2018-08-10T22:22:48.733 回答
4

以下带有复制任务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"
}
于 2020-05-02T08:16:07.643 回答