【问题标题】:How to execute a Command in Task如何在任务中执行命令
【发布时间】:2020-08-19 12:47:32
【问题描述】:

是否可以在 Sbt Task 中执行命令?如果是这样,怎么做?既然指挥部需要一个国家,我怎样才能获得一个?

我正在尝试覆盖默认任务,这是我尝试过的

dist := {
  println("Turning coverage off")
  Command.process("coverageOff")
  dist.value
}

Command.process的签名是(string, state) => _

我还没弄清楚从哪里得到状态

【问题讨论】:

    标签: sbt


    【解决方案1】:

    是的,您可以在任务中运行命令。这是我目前正在做的事情。首先,在构建中定义以下方法:

    /**
      * Convert the given command string to a release step action, preserving and      invoking remaining commands
      * Note: This was copied from https://github.com/sbt/sbt-release/blob/663cfd426361484228a21a1244b2e6b0f7656bdf/src/main/scala/ReleasePlugin.scala#L99-L115
      */
    def runCommandAndRemaining(command: String): State => State = { st: State =>
      import sbt.complete.Parser
      @annotation.tailrec
      def runCommand(command: String, state: State): State = {
        val nextState = Parser.parse(command, state.combinedParser) match {
          case Right(cmd) => cmd()
          case Left(msg) => throw sys.error(s"Invalid programmatic input:\n$msg")
        }
        nextState.remainingCommands.toList match {
          case Nil => nextState
          case head :: tail => runCommand(head.commandLine, nextState.copy(remainingCommands = tail))
        }
      }
      runCommand(command, st.copy(remainingCommands = Nil)).copy(remainingCommands = st.remainingCommands)
    }
    

    然后,只需使用上述定义的实用程序从任务中调用任何命令,例如,runCommandAndRemaining("+myProject/publishLocal")(state.value)

    在你的具体情况下,它应该归结为

    dist := {
      val log = streams.value.log
      log.debug("Turning coverage off")
      runCommandAndRemaining("coverageOff")(state.value)
      dist.value
    }
    

    希望这会有所帮助!

    【讨论】:

    • 您能否解释一下为什么会这样?据我了解,runCommandAndRemaining 只是创建了一个新状态,其中所需的命令处于挂起状态。然而,结果状态在dist 的定义中被简单地丢弃了。还是发生了一些宏观魔术?
    • 这也适用于Command. 定义,如果你只使用runCommandAndRemaining(state)
    【解决方案2】:

    从 gitter 获得一些帮助后,这是不可能的,但是可以做相反的事情,在命令中调用任务。

    因此,如果您的用例是顺序运行命令和任务(反之亦然),您可以这样做

    lazy val newCommand = Command.command("name") { state =>
      val newState = Command.process("comandName", state)
      // run task
      newState
    }
    

    【讨论】:

    • 嗨,Command.process 是什么?它在对象上不存在并且给出的符号未解析
    • 嗨@boyang,这个答案可能已经过时了,我认为接受的答案有效,可能值得一试
    • 事实证明,Command.process 在 sbt 1.0.x 和 1.1.x 中被删除,但在 1.2.x 中被添加回来,语义略有不同。你的作品再次出现,现在应该是正确的答案
    【解决方案3】:

    State可以通过评估state.value得到

    要从任务访问当前状态,请使用 state 任务作为 输入。例如,

    myTask := ... state.value ...

    并且可以使用Command.process 在任务中调用命令,就像这样

    dist := {
      println("Turning coverage off")
      Command.process("coverageOff", state.value)
      dist.value
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      • 2016-11-10
      • 1970-01-01
      相关资源
      最近更新 更多