如何设置sbt插件调用范围?

时间:2013-12-01 09:39:25

标签: sbt

val webAssemblyTask = TaskKey[Unit](
  "web-assembly",
  "assembly web/war like run-time package"
)

var out: TaskStreams = _

val baseSettings: Seq[Setting[_]] = Seq(
    webAssemblyOutputDir <<= (sourceManaged) { _ / "build" },
    webAssemblyTask <<= (
    streams,
    target,
    sourceDirectory,
    outputDirProjectName
) map {
  (out_log, targetDir, sourceDir, outputDirProjectName) => {
      out_log.log.info("web-assembly start")
      out_log.log.info("sourceDir:" + sourceDir.getAbsolutePath)
      out_log.log.info("targetDir:" + targetDir.getAbsolutePath)
      val sourceAssetsDir = (sourceDir / "webapp" / "assets").toPath
      val classesAssetsDir = (targetDir / "scala-2.10" / "classes" / "assets").toPath
      Files.createSymbolicLink(classesAssetsDir, sourceAssetsDir)
    }
  }
)

val webAssemblySettings = inConfig(Runtime)(baseSettings)

我写了一个sbt的插件。 我在sbt控制台中键入webAssembly,插件运行正常。 但我想在编译之后运行,在运行之前,我该怎么办呢?

1 个答案:

答案 0 :(得分:2)

如何设置sbt插件调用范围?

我认为您将配置(也称为Maven范围)名称与compilerun等任务混淆。它们恰好具有相关配置,但这并不意味着compile任务与Compile配置相同。

我可以解释这个问题是插件设置如何在其他配置中调用作用域的任务。为此,您使用in方法,例如:key in (Config)key in (Config, task)。解释它的另一种方式可能是如何在配置中确定插件任务的范围。你使用inConfig(Config)(...),你已经在做了。但是你通常希望插件是配置中立的。有关详细信息,请参阅my blog post

我想在编译之后运行,在运行之前,我该怎么办?

这更有意义。在sbt中,你主要关注任务的前提条件。其中一个有用的命令是inspect tree key。您可以为run任务运行该任务,并获取它所依赖的整个任务/设置。在这里,您可以看到它调用compile:compilecompile in Compile的另一种表示法):

helloworld> inspect tree run
[info] compile:run = InputTask[Unit]
[info]   +-runtime:fullClasspath = Task[scala.collection.Seq[sbt.Attributed[java.io.File]]]
[info]   | +-runtime:exportedProducts = Task[scala.collection.Seq[sbt.Attributed[java.io.File]]]
[info]   | | +-compile:packageBin::artifact = Artifact(sbt-sequential,jar,jar,None,List(compile),None,Map())
[info]   | | +-runtime:configuration = runtime
[info]   | | +-runtime:products = Task[scala.collection.Seq[java.io.File]]
[info]   | | | +-compile:classDirectory = target/scala-2.10/sbt-0.13/classes
[info]   | | | +-compile:copyResources = Task[scala.collection.Seq[scala.Tuple2[java.io.File, java.io.File]]]
[info]   | | | +-compile:compile = Task[sbt.inc.Analysis]

这对于根据compile:products命令发现help products,“构建打包的产品”非常有用:

helloworld> help products
Build products that get packaged.

由于runtime:products发生在compile:run之前,如果它取决于您的任务,则会在compile:run之前调用您的任务(inspect tree也会显示run已解决那个)。

为了简化您的插件任务,我只是将其称为sayHello

val sayHello = taskKey[Unit]("something")

sayHello := {
  println("hello")
}

您可以按如下方式重新布线products in Runtime

products in Runtime := {
  val old = (products in Runtime).value
  sayHello.value
  old
}

这将满足“之前运行”部分。您希望确保在compile之后运行此操作。再次,只需向它添加任务依赖:

sayHello := {
  (compile in Compile).value  
  println("hello")
}

当用户运行run任务时,sbt将更正计算依赖关系并在sayHellocompile之间的某个位置运行run任务。