如何从build.sbt中分离任务代码

时间:2016-09-26 00:06:22

标签: sbt

我为自己的sbt项目编写了自定义任务,并将其放在build.sbt中。 但是,我想将任务的代码放在单独的文件中并从build.sbt导入它。我创建了包含类似内容的mytask.sbt

lazy val myTask = taskKey[Unit]("my task")

myTask := {
   //doing task
}

但我不知道如何从build.sbt内导入此任务,因此我可以使用以下内容:

compile <<= (compile in Compile) dependsOn myTask

我知道有插件概念,但我认为这对我的需求来说太过分了。我想要的只是分开一些代码。

1 个答案:

答案 0 :(得分:5)

您没有提及您正在使用的sbt版本,因此以下答案基于版本0.13.12。

据我所知,任务必须在sbt文件,插件或扩展Build trait的scala文件对象中定义。 我不认为它可能在一个sbt文件中定义任何东西,并在另一个文件中使用它,所以从我的角度来看,你有这些选择:

扩展构建特征 这种做事方式已经在sbt的后期版本中被弃用,所以我不会进入那个。

在scala文件中定义任务的逻辑。 您可以将声明和任务逻辑分开,以便在sbt构建文件中声明任务,但将其逻辑移动到scala文件中。然后你的构建文件可能是这样的:

import CommonBuildCode._

val myTask = taskKey[Unit]("my task")

myTask := {
    myTaskPerform()
}


compile := {
    myTask.value
    (compile in Compile).value
}

你的任务逻辑可以在文件项目/ CommonBuildCode.scala

import sbt._

object CommonBuildCode {

    def myTaskPerform(): Unit = {
        println("-------------------------- myTask called --------------------------")
    }
}

我不知道这对你来说已经足够了,但是它会将你的build.sbt文件中关于myTask任务的行数保持在最低限度。

创建一个简单的插件 使用sbt创建插件非常容易,这样可以得到非常接近你要求的结果。首先像这样创建文件项目/ MyTaskPlugin.scala:

import sbt._

object MyTaskPlugin extends AutoPlugin {

    object autoImport {
        val myTask = taskKey[Unit]("my task")
    }

    import autoImport._

    override def projectSettings = Seq(
        myTask := {
            println("--------------- myTask called from a plugin------------------")
        }
    )
}

启用项目后,autoImport项目下的任何内容都将自动导入并可在sbt构建文件中使用,并且将应用projectSettings方法中设置的所有设置。所以现在你在build.sbt文件中唯一需要做的就是激活插件:

enablePlugins(MyTaskPlugin)

compile := {
    myTask.value
    (compile in Compile).value
}

使用插件的另一个好处是,将插件重构到自己的项目中非常容易,它可以发布一个jar,可以很容易地被其他项目激活。如果myTask被证明是您项目中的常见构建任务,那么这可能非常方便。