SBT插件——编译前执行自定义任务

Posted

技术标签:

【中文标题】SBT插件——编译前执行自定义任务【英文标题】:SBT plugin -- execute custom task before compilation 【发布时间】:2018-10-29 02:59:03 【问题描述】:

我刚刚编写了我的第一个 SBT Autoplugin,它有一个自定义任务,可以生成一个设置文件(如果该文件不存在)。当任务被显式调用时,一切都按预期工作,但我希望在使用插件编译项目之前自动调用它(不让项目修改它的 build.sbt 文件)。有没有办法做到这一点,或者我是否需要覆盖compile 命令?如果是这样,谁能指出我这样做的例子?任何帮助将不胜感激! (如果我遗漏了一些简单的东西,我深表歉意!)谢谢!

【问题讨论】:

【参考方案1】:

您可以使用dependsOn 定义任务之间的依赖关系,并通过重新分配覆盖范围内任务(如compile in Compile)的行为。

添加到build.sbt 文件中的以下行可以作为示例:

lazy val hello = taskKey[Unit]("says hello to everybody :)")

hello :=  println("hello, world") 

(compile in Compile) := ((compile in Compile) dependsOn hello).value

现在,每次运行compile,都会打印hello, world

[IJ]sbt:foo> compile
hello, world
[success] Total time: 0 s, completed May 18, 2018 6:53:05 PM

此示例已使用 SBT 1.1.5 和 Scala 2.12.6 进行了测试。

【讨论】:

如果我理解正确,对于每个使用 Autoplugin 的项目,(compile in Compile)... 都必须添加到 build.sbt 中,对吗?我正在寻找一种在 Autoplugin 中定义任务的方法,以便在编译之前执行它(不需要使用插件的项目来更改其构建文件)。这可能吗,也许与您发布的内容有所不同? (如果我误解了,我深表歉意......仍在努力掌握创建插件的窍门!) 一旦我将它移到插件中的(覆盖)项目设置中,这似乎确实起到了作用。误会深表歉意...感谢您的帮助! 覆盖lazy val projectSettings = Seq( (Compile / compile) := ((Compile / compile) dependsOn generateXmlMeta).value ) 这对我不起作用。请建议【参考方案2】:
val runSomeShTask = TaskKey[Unit]("runSomeSh", " run some sh")
    lazy val startrunSomeShTask = TaskKey[Unit]("runSomeSh", " run some sh")
    startrunSomeShTask := 
      val s: TaskStreams = streams.value
      val shell: Seq[String] = if (sys.props("os.name").contains("Windows")) Seq("cmd", "/c") else Seq("bash", "-c")
      // watch out for those STDOUT , SDERR redirection, otherwise this one will hang after sbt test ... 
      val startMiniosh: Seq[String] = shell :+ " ./src/sh/some-script.sh"
      s.log.info("set up run some sh...")
      if (Process(startMinioSh.mkString(" ")).! == 0) 
        s.log.success("run some sh setup successful!")
       else 
        throw new IllegalStateException("run some sh setup failed!")
      
    

    // or only in sbt test 
    // test := (test in Test dependsOn startrunSomeShTask).value
    (compile in Compile) := ((compile in Compile) dependsOn startrunSomeShTask).value

【讨论】:

以上是关于SBT插件——编译前执行自定义任务的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义 sbt 插件

你如何在 sbt 中编写任务?

Android Gradle 插件Gradle 自定义 Plugin 插件 ⑤ ( 自定义插件中获定义方法 | 在插件中创建 Gradle 任务 | 代码示例 )

无法从 AutoPlugin 的命令运行自定义 sbt 任务

在SBT构建中的多项目构建中的自定义任务

SBT 插件 %%% 在哪里定义?