gpt4 book ai didi

scala - runMain 中的 sbt 非法动态引用

转载 作者:行者123 更新时间:2023-12-03 23:59:48 32 4
gpt4 key购买 nike

我正在尝试运行代码生成器,并将文件名传递给它以写入输出:

resourceGenerators in (proj, Compile) += Def.task {
val file = (resourceManaged in (proj, Compile)).value / "swagger.yaml"
(runMain in (proj, Compile)).toTask(s"api.swagger.SwaggerDump $file").value
Seq(file)
}.value

但是,这给了我:

build.sbt:172: error: Illegal dynamic reference: file
(runMain in (proj, Compile)).toTask(s"api.swagger.SwaggerDump $file").value

最佳答案

您的代码片段有两个问题:

  1. 您使用 { ... }.value 而不是 { ... }.taskValue。资源生成器的类型是 Seq[Task[Seq[File]]],当你执行 value 时,你得到的不是 Seq[File] 任务[序列[文件]]。这会导致合法的编译错误。
  2. 动态变量file用作toTask的参数,当前宏实现禁止使用。

为什么是静态的?

Sbt 强制任务实现对其他任务具有静态依赖性。否则,sbt 无法执行任务重复数据删除,也无法在 inspect 命令中提供正确的信息。这意味着您在任务中执行的任何任务评估都不能依赖于变量(仅在运行时已知的值),就像您在 toTask 中的 file 一样。

为了克服这个限制,存在动态任务,其主体允许您返回任务。每个“动态依赖项”都必须在动态任务中定义,然后您可以在返回的任务中依赖提升的动态值。

动态解决方案

The following Scastie是你的任务的正确执行。我复制粘贴代码以便人们可以快速查看,但转到 Scastie 检查它是否成功编译和运行。

resourceGenerators in (proj, Compile) += Def.taskDyn {
val file = (resourceManaged in (proj, Compile)).value / "swagger.yaml"
Def.task {
(runMain in (proj, Compile))
.toTask(s"api.swagger.SwaggerDump $file")
.value
Seq(file)
}
}.taskValue

讨论

如果您修复了 taskValue 错误,您的任务实现是否应该正确编译?

在我看来,是的,但我还没有充分研究内部实现来断言您的任务实现不会阻碍任务重复数据删除和依赖项提取。如果没有,非法引用检查应该消失。

这是 sbt 当前的一个限制,我想通过改进整个宏实现(提升值并确保依赖分析涵盖更多情况)或仅仅改进“非法引用检查”来摆脱不要过于悲观。然而,这是一个难题,需要时间,而且短期内不太可能发生。

如果这对您来说是个问题,请在 sbt/sbt 中提交工单。这是了解解决此问题(如果有)的紧迫性的唯一方法。目前,我们能做的最好的事情就是记录下来。

关于scala - runMain 中的 sbt 非法动态引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43865941/

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