3

sbt をまったく使わないプロジェクトのスターターを作成するタスクを書きたいと思っています。ありがたいことに、sbt はすべての情報を知っているので、独自のスターターを作成できます。インタラクティブ モードでは、これらの 4 つのコマンドで、スターターを作成するために必要なすべての情報が表示されますが、出力されるだけで、それ以上処理できません。

show java-options
show unmanaged-jars
show managed-classpath

これら 3 つのタスクの結果をさらに処理したいのですが、その方法がわかりません。wiki のタスク定義は非常にわかりにくく、<<= 演算子はさらに混乱を招きます。

4

1 に答える 1

2

タスクを作成することはあまりありません。ウィキを見て、何かわからなかったと思います。次の例のようにすると思います。

val stringTask = TaskKey[String]("string-task")
stringTask <<= (sampleTask, intTask) map { (sample: Int, intValue: Int) =>
    "Sample: " + sample + ", int: " + intValue
}

この<<=メソッドは、 の定義がstringTask他のタスクに依存していることを単純に示しています。

一方、Task ではなく Runner が必要な場合もあります。

残念ながら、ランナーの作成はそれほど単純ではありません。私はこのプロジェクトに参加しています。その定義は次のとおりです。

class MyRunner(subproject: String, config: ForkScalaRun) extends sbt.ScalaRun {
  def run(mainClass: String, classpath: Seq[File], options: Seq[String], log: Logger): Option[String] = {
    log.info("Running " + subproject + " " + mainClass + " " + options.mkString(" "))

    val javaOptions = classpathOption(classpath) ::: mainClass :: options.toList
    val strategy = config.outputStrategy getOrElse LoggedOutput(log)
    val process =  Fork.java.fork(config.javaHome,
                                  config.runJVMOptions ++ javaOptions,
                                  config.workingDirectory,
                                  Map.empty,
                                  config.connectInput,
                                  strategy)
    def cancel() = {
      log.warn("Run canceled.")
      process.destroy()
      1
    }
    val exitCode = try process.exitValue() catch { case e: InterruptedException => cancel() }
    processExitCode(exitCode, "runner")
  }
  private def classpathOption(classpath: Seq[File]) = "-classpath" :: Path.makeString(classpath) :: Nil
  private def processExitCode(exitCode: Int, label: String) = {
    if(exitCode == 0) None
    else Some("Nonzero exit code returned from " + label + ": " + exitCode)
  }
}

そして、次のように使用されます。

runner in Compile in run <<= (thisProject, taskTemporaryDirectory, scalaInstance, baseDirectory, javaOptions, outputStrategy, javaHome, connectInput) map {
  (tp, tmp, si, base, options, strategy, javaHomeDir, connectIn) =>
    new MyRunner(tp.id, ForkOptions(scalaJars = si.jars, javaHome = javaHomeDir, connectInput = connectIn, outputStrategy = strategy,
      runJVMOptions = options, workingDirectory = Some(base)) )
}
于 2012-04-23T18:32:21.307 に答える