我有兴趣写一个任务,创建我的项目的启动器,完全不涉及sbt。值得庆幸的是,sbt知道所有信息,因此我可以创建自己的启动器。在交互模式下,这四个命令向我显示了创建启动器所需的所有信息,但它们只是将它们打印出来,而我无法进一步处理它们
show java-options
show unmanaged-jars
show managed-classpath
我想进一步处理这三个任务的结果,但是知道我不知道该怎么做。维基中的任务防御非常令人困惑,并且<< =运算符甚至更多。
答案 0 :(得分:2)
创建任务并不多。我假设你看了wiki关于它,并且不明白的东西。我想你会做这样的例子:
val stringTask = TaskKey[String]("string-task")
stringTask <<= (sampleTask, intTask) map { (sample: Int, intValue: Int) =>
"Sample: " + sample + ", int: " + intValue
}
<<=
方法只是说stringTask
的定义取决于其他任务。
另一方面,也许你需要一个跑步者,而不是一个任务。
遗憾的是,写一个跑步者并不是那么简单。我在this project。这是它的定义:
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)) )
}