【发布时间】:2014-05-26 15:09:09
【问题描述】:
我想在开源项目之前为我的项目创建一个 sbt 插件。
该项目在运行应用程序的开始时附加一个 Java 代理,以检测它以进行各种类型的分析。代理写出文本文件以供以后处理。
我希望能够写一个sbt插件,可以
- 有一个名为
runWithProfiling的run的替代品,它启动一个新的java 进程,将代理添加到参数列表中,并传递所有用户命令。 - 退出时,我想调用一些任意的后处理代码来生成 HTML 报告
我大致知道如何创建新命令,但我不知道如何最好地实现 run 的替代方法...我不想通过复制 @ 的所有代码来重新发明轮子987654324@ 可以。有没有一种方法可以调用run,但确保我的参数被传递(一次)并且它绝对是一个新的java进程?
另外,能够为测试做同样的事情会很棒。
更新:这是我目前拥有的代码,但它存在一些问题,标记为TODOs
import sbt._
import Keys._
import sbt.Attributed.data
object LionPlugin extends Plugin {
val lion = TaskKey[Unit]("lion", "Run a main class with lions-share profiling.")
override val projectSettings = Seq(
fork := true,
javaOptions ++= Seq(
"-Xloggc:gc.log", "-XX:+PrintGCDetails", "-XX:+PrintGCDateStamps",
"-XX:+PrintTenuringDistribution", "-XX:+PrintHeapAtGC"
// TODO: need to get hold of the local jar file for a particular artifact
// IMPL: pass the jar as the agent
),
lion <<= (
runner,
fullClasspath in Runtime,
mainClass in Runtime,
streams in Runtime
) map runLion
)
// TODO: update to a task that can take parameters (e.g. number of repeats, profiling settings)
def runLion(runner: ScalaRun, cp: Classpath, main: Option[String], streams: TaskStreams): Unit = {
assert(runner.isInstanceOf[ForkRun], "didn't get a forked runner... SBT is b0rk3d")
println("RUNNING with " + runner.getClass)
// TODO: ask user if main is None, like 'run' does
val m = main.getOrElse("Scratch")
// TODO: get the user's arguments
val args = Nil
runner.run(m, data(cp), args, streams.log)
// IMPL: post-process and produce the report
println("FINISHED")
}
}
【问题讨论】: