我目前正在开发一个使用 Kotlin DSL (KTS) 进行 Gradle 配置的 Android 项目,并且在设置自定义 Gradle 任务来处理某些文件时遇到问题。我的目标是创建一个任务,将特定目录的文本文件作为输入,处理它们,并将输出写入另一个目录。
这是我当前在 build.gradle.kts 中的设置:
tasks.register<Copy>("processTextFiles") {
from("src/main/text") // Input directory
into("build/processed-text") // Output directory
include("**/*.txt") // Only include text files
}
虽然此配置适用于简单的复制操作,但我需要扩展任务来处理文件(例如,对文件内容应用转换)。我不知道如何:
我尝试过的:
tasks.register("processTextFiles") {
val inputDir = file("src/main/text")
val outputDir = file("build/processed-text")
doLast {
inputDir.walk().forEach { file ->
if (file.extension == "txt") {
val content = file.readText()
val processedContent = content.replace("oldString", "newString")
File(outputDir, file.name).writeText(processedContent)
}
}
}
}
这可行,但我觉得它不是惯用的 Kotlin DSL,并且没有利用 Gradle 的输入/输出跟踪功能。
增量构建:我了解到 Gradle 的增量构建功能依赖于 @Input 和 @Output 的正确使用,但我不确定如何为我的自定义任务正确注释这些属性。我尝试使用inputs.dir(inputDir)和outputs.dir(outputDir),但是每次构建时任务仍然运行,即使输入没有改变。
任务类型:我还尝试扩展 DefaultTask 类来创建完全自定义的任务,但遇到了属性声明和任务操作中访问文件的问题。
Gradle 版本:8.2
Kotlin 版本:1.8.10
Android Gradle 插件:8.1.0
提前感谢您的帮助!
我不知道如何:
- 修改此任务以对文件内容执行转换(例如,替换文本文件中的某些字符串)。
您可以使用
filter
方法(docs):
tasks.register<Copy>("processTextFiles") {
filter { eachLineInFile ->
eachLineInFile.replace("%SOME_PLACEHOLDER%", "someValue")
}
}
文件中的每一行都会调用 lambda,并替换为 lambda 的返回值。
- 确保任务仅在输入文件更改时运行(增量构建)。
- 定义适当的@Input和@Output注释(如果需要)以确保Gradle正确跟踪依赖关系。
Gradle 将根据传递给
from
和 into
方法的位置为您执行所有这些操作,因为 Copy
任务的编写方式不同。