使用SBT输入任务获取设置和参数

时间:2013-11-20 09:16:35

标签: scala sbt

我编写了一个SBT plugin,允许SBT用户在他们的项目中定义可以从SBT本身运行的任意任务(加载完整的类路径和依赖关系)。

功能正文如下所示

  def installTask(taskName: String, taskDescription: String = "") = {
    TaskKey[Unit](taskName, taskDescription) <<= (dependencyClasspath in Runtime)
      .map(loadTask(_, "tasks", taskName.capitalize))
      .map(_.run)
  }


  private def loadTask(dependencies: Keys.Classpath, taskPackage:String, className: String) = {
    val dependenciesUrls = dependencies.map(_.data.toURI.toURL).toArray
    val classLoader = new URLClassLoader(dependenciesUrls, null)
    val taskClass = s"$taskPackage.$className"
    classLoader.loadClass(taskClass).newInstance().asInstanceOf[Runnable]
  }

所以人们可以在他们的SBT文件中执行此操作

import SbtTasks._

installTask("seedDB")

当调用sbt seedDB tasks.SeedDB将在应用程序上下文中执行时。

现在问题 - 我需要这样做但接受参数。我已经理解了如何接受参数

  def installTaskWithArgs(taskName: String, taskDescription: String = "") = {
    val input = InputKey[Unit](taskName, taskDescription)

    input := {
      val args: Seq[String] = Def.spaceDelimited("<arg>").parsed
      println(args)
    }
  }

但是我无法弄清楚如何在这个上下文中访问InputTask中dependencyClasspath的值

  val dc = (dependencyClasspath in Runtime)

我也尝试过命令,但它们看起来有点麻烦,所有内容似乎都会提升InputTasks over Commands。

那么 - 我如何接受任务中的参数,同时还可以访问dependencyClasspath

注意:为简洁起见,代码已被省略,请原谅任何明显的排除

2 个答案:

答案 0 :(得分:1)

我认为inputTaskDyn是你的朋友:

input :=
  Def.inputTaskDyn {
    val args = Def.spaceDelimited("<arg>").parsed
    val dc = (dependencyClasspath in Runtime).value
    ...
  }.evaluated

有关某些背景信息以及进一步阅读的链接,请参阅https://github.com/sbt/sbt/issues/999

答案 1 :(得分:0)

经过几天的实验,我终于找到了一个可行的解决方案,

def installTaskWithArgs(taskName: String, taskDescription: String = "") = {
    val input = InputKey[Unit](taskName, taskDescription)

    input := {
      val args: Seq[String] = Def.spaceDelimited("<arg>").parsed
      val dc = (dependencyClasspath in Runtime).result.value.toEither.right.get
      println(args)
      println(dc)
    }
 }

我想特别提出行

val dc = (dependencyClasspath in Runtime).result.value.toEither.right.get

虽然这不是最稳定的路线(它假定是快乐的路径),但这至少是一个很好的起点(并且目前我的需求是有效的)