无法从 AutoPlugin 的命令运行自定义 sbt 任务

Posted

技术标签:

【中文标题】无法从 AutoPlugin 的命令运行自定义 sbt 任务【英文标题】:Unable to run custom sbt task from AutoPlugin's command 【发布时间】:2014-10-07 20:15:31 【问题描述】:

我尝试了所有我能想到的方法,但运行 taskB 仍然会出现错误消息,即如果我将它放在自定义配置中,则任务未在 */*:taskB*/cmd:taskB 中定义。

Command.command("doStuff", Help.more("doStuff", "whatever")) 
      (state: State) =>
        val e = Project.extract(state)

        val taskA = taskKey[Seq[String]]("A")
        val taskB = taskKey[Seq[File]]("B")

        val cmdConfig = config("cmd")

        val newState = e.append(
          inConfig(cmdConfig)(Seq(
              taskA := 
                // do stuff
              ,
              taskB := 
                // do stuff
              
            )
          )
          , state
        )

        val result: (State, Seq[File]) = e.runTask(taskB in cmdConfig, newState)
)

在调试它时,似乎该任务在搜索它的structure.data 中不存在。

【问题讨论】:

您是否需要专门从命令中添加任务,或者只是让命令调用任务? 关键是让命令调用它们。如果它没有崩溃(我注释掉了 e.runTask 部分),那么这些任务就可以从 SBT 访问,标准 */*:taskB。我在 e.runTask() 中尝试了各种轴组合,但始终找不到任务,我尝试调试它,但那里真的很难。 gist.github.com/l15k4/7e553b49606312fb133f 【参考方案1】:

首先,我假设您只想从命令中调用任务,而您并不关心是否通过修改该命令中的状态来添加它们。

如果是这样,我会以更标准的方式进行操作,因为它是由 AutoPlugins 完成的。

import sbt._
import Keys._

object MyPlugin extends AutoPlugin 

  object autoImport 
    val taskA = taskKey[Seq[String]]("Task A")
    val taskB = taskKey[Seq[File]]("Task B")
  

  import autoImport._

  val cmdConfig = config("cmd")

  override def projectConfigurations = Seq(cmdConfig)

  // this is optional of course, you can also enable plugin manually
  override def trigger = allRequirements

  override def projectSettings = 
    Seq(commands += doStuffCommand) ++
    inConfig(cmdConfig)(Seq(
      taskA := 
        println("TASK A")
        Seq("A", "B")
      ,
      taskB := 
        println("TASK B")
        Seq(file("."))
      
    ))


  lazy val doStuffCommand =
   Command.command("doStuff", Help.more("doStuff", "whatever")) 
     (state: State) =>
     val e = Project.extract(state)
     val (newState, bResult) = e.runTask(taskB in cmdConfig, state)
     newState
   


除此之外,您可能根本不需要命令,只需让一些任务调用另一个任务会更简单。

【讨论】:

lpiepiora 你拯救了我的一天,我应该专注于插件文档而不是命令文档。我仍然想知道为什么以命令为中心的解决方案不起作用。我需要使用命令,因为我正在通过状态将服务器实例上的引用从一个命令传递到另一个命令,以便在启动它之后您可以控制它。顺便说一句,您能否在projectConfigurations 上添加评论并解释它有什么用处?我猜如果你想添加一个使用这个Configuration的设置,你必须在之前“注册”它? 顺便说一句,波兰有多少公司在使用 Scala?在捷克***仍然只有 2 个,我预计兴趣会比现在更多。 @Sloin 关于第一点。是的,你必须告诉 sbt 你的配置。通常你可以在project 上做,比如project.configs(YourConfiguration)。但是,使用 AutoPlugins,您可以使用 projectConfigurations 在插件激活后自动添加它们。所以基本上我认为你可以说你的假设是正确的。关于第二点 - 对不起,我无法详细说明这一事实,因为我不知道。我们目前在我工作的公司没有使用它,它更像是我的一种爱好,因为我喜欢这种语言的表现力。 请问您知道如何在此命令中访问构建定义项目类路径吗?如果有人使用这个插件/命令,那么runTask(fullClasspath in Compile, state)runTask(fullClasspath in Runtime, state) 和任何其他Keys.classpath 只返回没有构建定义项目依赖项的类路径,例如像这样的插件。这样在有人运行命令时我就无法访问我自己的插件类路径。

以上是关于无法从 AutoPlugin 的命令运行自定义 sbt 任务的主要内容,如果未能解决你的问题,请参考以下文章

Capistrano 3:运行自定义 shell 命令时无法识别捆绑器

使用 sbt-projectmatrix 创建 AutoPlugin。如何设置scalaVersion?

无法从 prometheus-adapter 检索自定义指标

SBT AutoPlugin 缺少添加的工件

从命令提示符使用自定义命令参数运行 WPF 应用程序

使用自定义 sbt 插件