我正在创建一个 Gradle 任务,我想在其中下载并引用 jar 文件以查找 Maven 存储库中存在的工件。 具体来说,我计划通过 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
文件将检索项目(如有必要(,并提供文件位置作为脚本的参数:
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
的调用返回对项目的 jar 文件的java.io.File
引用。 此 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"
}