gpt4 book ai didi

gradle - Gradle CopySpec.eachFile 中 FileCopyDetails 的评估

转载 作者:行者123 更新时间:2023-12-03 02:55:05 26 4
gpt4 key购买 nike

我正在尝试做一件看似相当简单的事情:使用 Gradle Copy 任务或方法显示我正在复制的文件的目标路径
为此,我使用了 CopySpec.eachFile 方法,在该方法中我使用了 FileCopyDetails 来访问目标路径,正如我认为在 Gradle javadoc 中解释的那样。

这是一个使用Copy 任务的示例(与Copy 方法的行为相同):

task copyTaskUsingEachFile(type: Copy) {

from("$projectDir/resources/file-with-tokens.txt")
into('generated/subfolder')

filter(ReplaceTokens, tokens: [sampleProp: 'Hello sample property!'])
eachFile { println """ ---- content of FileCopyDetails object used in eachFile :
object toString = $it
name = $it.name
path = $it.path
relativePath = $it.relativePath
sourceName = $it.sourceName
sourcePath = $it.sourcePath
"""
}
}

问题是:eachFile 中使用的基础FileCopyDetails 对象的每个属性都评估为相同的值:

:copyTaskUsingEachFile
---- content of FileCopyDetails object used in eachFile :
object toString = file 'C:\<some path>\resources\file-with-tokens.txt'
name = file-with-tokens.txt
path = file-with-tokens.txt
relativePath = file-with-tokens.txt
sourceName = file-with-tokens.txt
sourcePath = file-with-tokens.txt

我希望 Gradle 显示:

sourceName = resources/file-with-tokens.txt
path = generated/subfolder/file-with-tokens.txt

仔细阅读 FileCopyDetails 文档后:

Provides details about a file or directory about to be copied, and allows some aspects of the destination file to be modified

我开始认为,在 eachFile 中打印此对象时,“最终”目标路径尚未设置。

我尝试使用 child CopySpec,使用 from (...) {...} 语法,猜测它可能会影响评估时间:

task copyTaskUsingEachFileAndChildCopySpec(type: Copy) {

into 'generated'

from("$projectDir/resources/file-with-tokens.txt") {
into('subfolder')
}

filter(ReplaceTokens, tokens: [sampleProp: 'Hello sample property!'])
eachFile { println """ ---- content of FileCopyDetails object used in eachFile :
object toString = $it
name = $it.name
path = $it.path
relativePath = $it.relativePath
sourceName = $it.sourceName
sourcePath = $it.sourcePath
"""
}

}

这次我得到以下结果:

:copyTaskUsingEachFileAndChildCopySpec
---- content of FileCopyDetails object used in eachFile :
object toString = file 'C:\<some path>\resources\file-with-tokens.txt'
name = file-with-tokens.txt
path = subfolder/file-with-tokens.txt
relativePath = subfolder/file-with-tokens.txt
sourceName = file-with-tokens.txt
sourcePath = file-with-tokens.txt

因此,所有目标路径都显示有它们的子 CopySpec 值,而不是从父 CopySpec 继承的部分(在当前情况下为 generated)。

所以我有两个问题:

  • 有人知道如何/何时在 CopySpec.eachFile 中解析 FileCopyDetails 吗?
  • 有人知道如何显示由 Copy 任务(或方法)复制的文件的完整目标路径吗?

任何帮助或部分解释将不胜感激。


更新

使用 Vampire answer ,我知道在 CopySpec.eachFile 中成功打印了我复制的文件的完整目标路径。为此,我使用了 Copy.destinationDir 字段。

task copyMultipleFilesDisplayTargetFolder(type: Copy) {

printTask 'copyMultipleFilesDisplayTargetFolder'

into 'generated'
filter(ReplaceTokens, tokens: [sampleProp: 'Hello sample property!'])

/* Here, we print the complete destination path of the copied files, BUT,
I don't know how to print their complete SOURCE path.
*/
eachFile {
println "file $it.name copied to $destinationDir/$it.path"
println ''
}

from("$projectDir/resources/file-with-tokens.txt") {
into('subfolder')
}
from("$projectDir/resources2/file-with-tokens-2.txt") {
into('subfolder2')
}
from("$projectDir/resources3/file-with-tokens-3.txt") {
into('subfolder3')
}
}

给出:

 ------------ TASK ------------ copyMultipleFilesDisplayTargetFolder

:copyMultipleFilesDisplayTargetFolder
file file-with-tokens.txt copied to C:\<some path>\generated/subfolder/file-with-tokens.txt

file file-with-tokens-2.txt copied to C:\<some path>\generated/subfolder2/file-with-tokens-2.txt

file file-with-tokens-3.txt copied to C:\<some path>\generated/subfolder3/file-with-tokens-3.txt

现在唯一缺少的是能够以简单的方式打印复制文件的完整源路径
“简单方法” 我的意思是,例如,在单个 eachFile 中,所有子 CopySpec 都将继承(如上)。

目前,我可以使用 Copy.source 字段和 FileCollection.getAsPath 方法来显示它,但是要集成到 eachFile 中并不容易。


更新 2

Vampire 又说对了,你可以使用 FileCopyDetails.getFile() 来访问代表源的 File 对象,它允许你显示 完整的源码路径:

task copyMultipleFilesDisplayTargetFolder(type: Copy) {

printTask 'copyMultipleFilesDisplayTargetFolder'

into 'generated'
//filter(ReplaceTokens, tokens: [sampleProp: 'Hello sample property!'])

eachFile {
println "file $it.name copied to $destinationDir/$it.path"

/* !!!! BEWARE !!!!
You can't use the below FileCopyDetails.getFile() when also using a filter operation.
Check https://discuss.gradle.org/t/combining-eachfile-filter-results-in-failure/14801/2
*/
println "Initial source path: ${it.getFile().getCanonicalPath()}"

println ''
}

from("$projectDir/resources/file-with-tokens.txt") {
into('subfolder')
}
from("$projectDir/resources2/file-with-tokens-2.txt") {
into('subfolder2')
}
from("$projectDir/resources3/file-with-tokens-3.txt") {
into('subfolder3')
}
}

但是您不能在使用filter 操作时使用FileCopyDetails.getFile()!
这是一个神秘的 Gradle 错误,在这里解释:https://discuss.gradle.org/t/combining-eachfile-filter-results-in-failure/14801/2

查看 Gradle 源代码时,DefaultFileCopyDetails 类包含以下代码:

public File getFile() {
if (filterChain.hasFilters()) {
throw new UnsupportedOperationException();
} else {
return fileDetails.getFile();
}
}

不幸的是,这解释了这个问题。

无论如何,在任何其他情况下,我的 2 个初始问题都有新的答案,谢谢!


更新 3(最终版)

再次感谢 Vampire(他专门针对这个问题打开了一个 Gradle 案例),他为我们提供了针对前一个 filter/getFile bug 的解决方案。

有关详细信息,请参阅他的 https://github.com/gradle/gradle/issues/1588,但是,简而言之,为避免此问题,在 same CopySpec 中,您只需调用 filter < strong>AFTER 调用 eachFile
我确认它正在运行。

最佳答案

如果您更深入地阅读 JavaDoc,您会在 getPath()getRelativePath() 的第一句中找到解释,即 Returns此文件的路径,相对于复制目标的根目录。

在您的第一个示例中,您调用 eachFile 方法的 CopySpec 的复制目标是 generated/subfolder,因此相对路径目标文件是 file-with-tokens.txt

在您的第二个示例中,您调用 eachFile 方法的 CopySpec 的复制目标是生成的,因此目标的相对路径文件是 subfolder/file-with-tokens.txt

CopySpec 的复制目标与相对路径连接起来,您将获得目标文件的完整路径。

如果你G。在您的 eachFile 调用之前添加一个 rename 调用,例如 rename { 'foo-' + it },然后您会看到相对路径将变为foo-file-with-tokens.txt 而源路径仍然是 file-with-tokens.txt


如果您需要文件的源路径,您可以简单地使用FileCopyDetailsfile 属性。每个 FileCopyDetails 也是一个 FileTreeElement(它的父类(super class)),因此有一个指向源文件的文件属性(File 对象)。

请注意,过滤器 可能会受到干扰。如果您在同一复制规范中且在 eachFile 之前有一个 filter,或者在您执行的复制规范的父复制规范中有一个 filter eachFile,无论是之前还是之后,你都会得到一个UnsupportedOperationException。如果您在同一复制规范中的 eachFile 之后执行 filter,它会起作用。参见 https://github.com/gradle/gradle/issues/1588了解更多信息。

关于gradle - Gradle CopySpec.eachFile 中 FileCopyDetails 的评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42670607/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com