代码之家  ›  专栏  ›  技术社区  ›  Martin Senne

如何动态调用SBT InputTask?

  •  2
  • Martin Senne  · 技术社区  · 10 年前

    我想创建一个新的自定义 InputTask ( testOnlyCustom )

    • 这就需要 testOnly 与给定的参数相同 仅测试自定义
    • 也许,基于SBT设置( condition ),调用另一个任务(让我们调用它 pre ) 之前 调用testOnly。这里,我必须强制“顺序”执行。

    因此:

    If condition is true
      testOnlyCustom com.dummy.TestSuite calls
        pre and then
        testOnly com.dummy.TestSuite
    
    If condition is false
      testOnlyCustom com.dummy.TestSuite calls
        testOnly com.dummy.TestSuite
    

    虽然我能够通过 testCustom 参考 之前 test (因此没有争论),我无法解决问题 仅测试自定义 输入任务 习惯于

    这是我的代码:

    import sbt._
    import sbt.Keys._
    import sbt.Def._
    import sbtsequential.Plugin._
    
    
    object Simple extends sbt.Plugin {
    
      import SimpleKeys._
    
      object SimpleKeys {
        lazy val condition = SettingKey[Boolean]("mode", "The mode.")
    
        lazy val pre = TaskKey[Unit]("test-with-pre", "Do some pre step.")
    
        lazy val testWithPre = TaskKey[Unit]("test-with-pre", "Run pre task beforehand")
        lazy val testCustom = TaskKey[Unit]("test-custom", "Run pre (depending on condition) and then test.")
    
        lazy val testOnlyWithPre = InputKey[Unit]("test-only-with-pre", "Run selected tests (like test-only in SBT) with pre executed before.")
        lazy val testOnlyCustom = InputKey[Unit]("test-only-configured", "Run pre (depending on condition) and then call test-only.")
      }
    
      lazy val baseSettings: Seq[sbt.Def.Setting[_]] = Seq(
    
        // this is working
        testWithPre := test.value,
        testWithPre <<= testWithPre.dependsOn( pre ),
    
        testCustom := Def.taskDyn {
          val c = condition.value
    
          if (c) {
            testWithPre
          } else {
            test
          }
        }.value,
    
    
        //
        // this is the part, where my question focuses on
        //
        testOnlyWithPre := testOnly.evaluated,
        testOnlyWithPre <<= testOnlyWithPre.dependsOn( pre ),
    
        // is this the correct approach?
        testOnlyCustom := Def.inputTaskDyn {
          // ???????????????????????????????
          Def.task()
        }.evaluated
      )
    
      lazy val testSimpleSettings: Seq[sbt.Def.Setting[_]] = baseSettings
    }
    
    1. inputTaskDyn 怎么走?它到底是干什么的?我刚刚选择了它,因为它似乎是动态版本 InputTasks 。不幸的是 输入任务Dyn .
    2. 可以通过以下方式强制“顺序”执行吗 dependsOn 像我一样?我已经看到SBT 0.13.8包含 Def.sequantial 。但这似乎不适用于InputTasks?
    3. 如何转换 输入任务 进入 Task (与taskDyn/inputTaskDyn一起使用),但仍坚持 evaluated 而不是使用显式解析器?或者是否有方法重用 仅测试 解析器?
    4. 有人能再说明一下吗 .evaluated .parsed 属于 输入任务 。具体是什么 InputTask.parse 在引擎盖下做什么?

    如果有人能提供一个有效的解决方案,那就太好了!

    提前非常感谢

    马丁

    3 回复  |  直到 10 年前
        1
  •  1
  •   Jan-David Salchow    6 年前

    为了记录在案,SBT 1等效值为

    testOnlyWithPre := test.dependsOn(pre).value

    testOnlyWithPre := testOnly.dependsOn(pre).evaluated

        2
  •  0
  •   Martin Senne    10 年前

    我能想到的最佳解决方案是

        testOnlyCustom := Def.inputTaskDyn {
          val args: Seq[String] = spaceDelimited("").parsed
          val c = condition.value
    
          if (c) {
            testOnlyWithPre.toTask(" " + args.head)
          } else {
            testOnly.toTask(" " + args.head)
          }
        }.evaluated
    

    但这仍然迫使我使用新的解析器( spaceDelimited )并且我不能(重新)使用testOnly解析器。

    知道如何重用解析器吗?

        3
  •  0
  •   Martin Senne    10 年前

    其他意见

    第一 ,OlegYch_在Freenode#sbt上指出,sbt 0.13.9执行 Inputtask 可以通过

    def runInputTask[T](key: InputKey[T], input: String, state: State): (State, T)
    

    在里面 sbt.Extracted.scala .

    第二 ,testOnly解析器可以通过 sbt.Defaults#inputTests .

    推荐文章