runMain 中的 sbt 非法动态引用 [英] sbt illegal dynamic reference in runMain

查看:38
本文介绍了runMain 中的 sbt 非法动态引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to run a code generator, and passing it the filename to write the output:

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

推荐答案

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

Your code snippet has two problems:

  1. 您使用 { ... }.value 而不是 { ... }.taskValue.资源生成器的类型是 Seq[Task[Seq[File]]] 并且当你做 value 时,你得到的 Seq[File] 不是任务[序列[文件]].这会导致合法的编译错误.
  2. 动态变量file用作toTask的参数,当前宏实现禁止.
  1. You use { ... }.value instead of { ... }.taskValue. The type of resource generators is Seq[Task[Seq[File]]] and when you do value, you get Seq[File] not Task[Seq[File]]. That causes a legitimate compile error.
  2. The dynamic variable file is used as the argument of toTask, which the current macro implementation prohibits.

为什么是静态的?

Sbt 强制任务实现对其他任务具有静态依赖关系.否则,sbt 无法执行任务重复数据删除,也无法在 inspect 命令中提供正确的信息.这意味着您在任务中执行的任何任务评估都不能依赖于变量(只有在运行时才知道的值),正如 toTask 中的 file 所做的那样.

Why static?

Sbt forces task implementations to have static dependencies on other tasks. Otherwise, sbt cannot perform task deduplication and cannot provide correct information in the inspect commands. That means that whichever task evaluation you perform inside a task cannot depend on a variable (a value known only at runtime), as your file in toTask does.

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

To overcome this limitation, there exists dynamic tasks, whose body allows you to return a task. Every "dynamic dependency" has to be defined inside a dynamic task, and then you can depend on the hoisted up dynamic values in the task that you return.

以下 Scastie 是您任务的正确实现.我复制粘贴了代码,以便人们可以快速查看,但请转到该 Scastie 以检查它是否成功编译并运行.

The following Scastie is the correct implementation of your task. I copy-paste the code so that folks can have a quick look, but go to that Scastie to check that it successfully compiles and runs.

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 错误,您的任务实现是否应该正确编译?

Discussion

If you had fixed the taskValue error, should your task implementation correctly compile?

在我看来,是的,但我还没有看到内部实现足以断言您的任务实现不会妨碍任务重复数据删除和依赖项提取.如果没有,非法的参考检查应该消失.

In my opinion, yes, but I haven't looked at the internal implementation good enough to assert that your task implementation does not hinder task deduplication and dependency extraction. If it does not, the illegal reference check should disappear.

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

This is a current limitation of sbt that I would like to get rid of, either by improving the whole macro implementation (hoisting up values and making sure that dependency analysis covers more cases) or by just improving the "illegal references checks" to not be over pessimistic. However, this is a hard problem, takes time and it's not likely to happen in the short term.

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

If this is an issue for you, please file a ticket in sbt/sbt. This is the only way to know the urgency of fixing this issue, if any. For now, the best we can do is to document it.

这篇关于runMain 中的 sbt 非法动态引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆