如何将任务代码与build.sbt分离

如何将任务代码与build.sbt分离,sbt,Sbt,我已经为我的sbt项目编写了自定义任务,并将其放在build.sbt中。 但是,我希望将任务的代码放在单独的文件中,并将其从build.sbt导入。我创建了包含以下内容的mytask.sbt: lazy val myTask = taskKey[Unit]("my task") myTask := { //doing task } compile <<= (compile in Compile) dependsOn myTask import CommonBuildCod

我已经为我的sbt项目编写了自定义任务,并将其放在
build.sbt
中。 但是,我希望将任务的代码放在单独的文件中,并将其从build.sbt导入。我创建了包含以下内容的
mytask.sbt

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

myTask := {
   //doing task
}
compile <<= (compile in Compile) dependsOn myTask
import CommonBuildCode._

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

myTask := {
    myTaskPerform()
}


compile := {
    myTask.value
    (compile in Compile).value
}
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------------------")
        }
    )
}
但我不知道如何从
build.sbt
中导入此任务,以便使用以下内容:

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

myTask := {
   //doing task
}
compile <<= (compile in Compile) dependsOn myTask
import CommonBuildCode._

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

myTask := {
    myTaskPerform()
}


compile := {
    myTask.value
    (compile in Compile).value
}
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------------------")
        }
    )
}

compile您没有提到您使用的sbt版本,因此以下答案基于0.13.12版本

据我所知,任务必须在sbt文件、插件或扩展构建特性的scala文件对象中定义。 我认为不可能在一个sbt文件中定义任何内容,并在另一个sbt文件中使用它,因此从我的角度来看,您可以选择以下选项:

扩展构建特征 在sbt的更高版本中,这种方法已经被弃用,因此我将不讨论这种方法

在scala文件中定义任务的逻辑。 您可以将任务的声明和逻辑拆分,以便在sbt构建文件中声明任务,但将其逻辑移动到scala文件中。那么您的构建文件可能如下所示:

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

myTask := {
   //doing task
}
compile <<= (compile in Compile) dependsOn myTask
import CommonBuildCode._

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

myTask := {
    myTaskPerform()
}


compile := {
    myTask.value
    (compile in Compile).value
}
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------------------")
        }
    )
}
任务的逻辑可以在project/CommonBuildCode.scala文件中

import sbt._

object CommonBuildCode {

    def myTaskPerform(): Unit = {
        println("-------------------------- myTask called --------------------------")
    }
}
我不知道这是否足以满足您的需要,但它会将build.sbt文件中有关myTask任务的行数保持在最低限度

创建一个简单的插件 使用sbt创建一个插件非常容易,这将给出非常接近您要求的结果。首先创建文件project/MyTaskPlugin.scala,如下所示:

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

myTask := {
   //doing task
}
compile <<= (compile in Compile) dependsOn myTask
import CommonBuildCode._

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

myTask := {
    myTaskPerform()
}


compile := {
    myTask.value
    (compile in Compile).value
}
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------------------")
        }
    )
}
启用项目后,自动导入项目下的任何内容都将自动导入并可在sbt生成文件中使用,并且将应用projectSettings方法中设置的所有设置。因此,现在您需要在build.sbt文件中执行的唯一操作是激活插件:

enablePlugins(MyTaskPlugin)

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

使用插件的另一个好处是,将插件重构到自己的项目中非常容易,可以发布一个jar,其他项目也可以轻松激活它。这可能非常方便,以防myTask在您的项目中成为常见的构建任务。

我删除了我的答案,因为它实际上没有回答您问题中有趣的部分。。。我试着让它与任务定义一起工作,但现在我头痛。我想你的意思是“在scala文件中定义任务的逻辑”,而不是sbt文件。不管怎样,谢谢你的回答,它对我很好。很高兴在这里它帮助了我。感谢您的更正,现在已经修复。答案是:“因此以下答案基于版本0.13.12。”现在SBT 1.x正在广泛使用,答案是否需要重大更新?