gpt4 book ai didi

scala - SBT sourceGenerators 任务 - 仅在文件更改时执行

转载 作者:行者123 更新时间:2023-12-03 22:36:32 25 4
gpt4 key购买 nike

在我的 SBT 项目中,我有一个输入文件 src/main/greeting/Greeting.txt具有以下内容:

Hello, world!

这是我的 build.sbtGreeting.txt 生成 Scala 源代码文件:
sourceGenerators in Compile += Def.task{
println("GENERATING FILES")
val inputFile = file("src/main/greeting/Greeting.txt")
val generatedFile =
(sourceManaged in Compile).value / "scala" / "Main.scala"
val greeting = IO.read(inputFile).trim
IO.write(
generatedFile,
s"""object Main extends App { println("${greeting}") }"""
)
Seq(generatedFile)
}.taskValue

build.sbt工作正常,除了它运行我的任务来生成 Scala 源 每次我编译/运行我的项目。我希望它仅在 Greeting.txt 时运行这些任务-文件已更改。我怎样才能做到这一点?

MCVE

生成项目的 Bash 脚本:
#!/bin/bash
mkdir sourceGeneratorsExample
cd sourceGeneratorsExample
mkdir -p src/main/scala
mkdir -p src/main/greeting
echo "Hello, world!" >> src/main/greeting/Greeting.txt
cat <<HEREDOC > build.sbt
sourceGenerators in Compile += Def.task{
println("GENERATING FILES")
val inputFile = file("src/main/greeting/Greeting.txt")
val generatedFile =
(sourceManaged in Compile).value / "scala" / "Main.scala"
val greeting = IO.read(inputFile).trim
IO.write(
generatedFile,
"object Main extends App { println(\"" + greeting + "\") }"
)
Seq(generatedFile)
}.taskValue
HEREDOC

重复文件/文档
  • This是 2012 年的答案,从那时起发生了很多变化。
  • current reference manual建议使用“sbt.Tracked.{ inputChanged, outputChanged }等”,但没有对此进行扩展,并且手册中的其他任何地方都没有提到 Tracked 对象。
  • 最佳答案

    您可以使用 FileFunction.cached ,这是一个:

    Generic change-detection helper used to help build / artifact generation / etc. steps detect whether or not they need to run.



    它使用缓存文件夹,SBT 会在其中自动保存文件更改的记录。与 FileFunction.cached ,您的 build.sbt可能看起来像这样:
    sourceGenerators in Compile += Def.task{

    // * Create a cached function which generates the output files
    // only if the input files have changed.
    // * The first parameter is a file instance of the path to
    // the cache folder
    // * The second parameter is the function to process the input
    // files and return the output files
    val cachedFun = FileFunction.cached(
    streams.value.cacheDirectory / "greeting"
    ) { (in: Set[File]) =>

    println("GENERATING FILES")

    val generatedFile =
    (sourceManaged in Compile).value / "scala" / "Main.scala"
    val greeting = IO.read(in.head).trim
    IO.write(
    generatedFile,
    "object Main extends App { println(\"" + greeting + "\") }"
    )
    Set(generatedFile)
    }

    // get the input file
    val inputFile = file("src/main/greeting/Greeting.txt")

    // put the input file into a `Set` (as required by `cachedFun`),
    // pass it to the `cachedFun`,
    // convert the result to `Seq` (as required by `Def.task`)
    cachedFun(Set(inputFile)).toSeq

    }.taskValue
    FileFunction.cached的第一个参数是一个目录,用于存储缓存信息(例如输入文件的哈希值)。在这里,我们通过了 streams.value.cacheDirectory / "greeting" ,这将在 target 内的某处创建一个缓存子目录-目录。好处是他的目录会在任务 clean时自动清理。正在运行。
    cached 的第一个参数列表方法需要两个额外的可选 inStyleoutStyle参数,确定如何检测更改(例如,通过修改日期,或通过比较哈希值)。请注意,在旧版本的 SBT 中,这两个参数是必需的,因此您的 cachedFun看起来有点像这样:
    val cachedFun = FileFunction.cached(
    cacheBaseDirectory = streams.value.cacheDirectory / "greeting",
    inStyle = FilesInfo.lastModified,
    outStyle = FilesInfo.exists
    )(cachedFunBodyImpl)
    FileFunction.cached 的第二个参数列表-method 接受一个映射 Set 的函数输入文件到 Set的输出文件。仅当输入文件已更改时才调用它。

    您可以找到有关旧版 SBT 的更多信息 here (SBT 0.13.5),在 cached 上扩展和文件跟踪样式。引用:

    There are two additional arguments for the first parameter list that allow the file tracking style to be explicitly specified. By default, the input tracking style is FilesInfo.lastModified, based on a file's last modified time, and the output tracking style is FilesInfo.exists, based only on whether the file exists. The other available style is FilesInfo.hash, which tracks a file based on a hash of its contents.



    第一个代码片段已经使用 SBT 1.2.8 进行了测试。第二个代码段也应该适用于较早的 0.13.x 版本。

    关于scala - SBT sourceGenerators 任务 - 仅在文件更改时执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33897874/

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