首页 > 解决方案 > 在函数调用中使用 sbt settingKey

问题描述

我们有一个build.sbt这样的文件,它工作正常:

name := "Foo"
version := "0.1"
scalaVersion := "2.12.8"

def aws(module: String): ModuleID = "com.amazonaws" % module % "1.11.250"

lazy val Core = project
  .settings(
    libraryDependencies ++= Seq(
      aws("aws-java-sdk-s3"),
      aws("aws-java-sdk-dynamodb"),
    )
  )

基本上,该项目有一些 AWS SDK 库依赖项,我们希望避免多次输入groupID(例如“com.amazonaws”)和revision(例如“1.11.250”),这就是我们有这一行的原因:

def aws(module: String): ModuleID = "com.amazonaws" % module % "1.11.250"

但是,由于我们有很多这样的存储库,我们希望将此定义移至自定义sbt-plugin. 首先,我们试试这个:

name := "Foo"
version := "0.1"
scalaVersion := "2.12.8"

val awsVersion = settingKey[String]("The version of aws SDK used for building.") // line 5
def aws(module: String): ModuleID = "com.amazonaws" % module % awsVersion.value // line 6

awsVersion := "1.11.250"

lazy val Core = project
  .settings(
    libraryDependencies ++= Seq(
      aws("aws-java-sdk-s3"),
      aws("aws-java-sdk-dynamodb"),
    )
  )

但是,第 6 行产生了错误:

错误:value只能在任务或设置宏中使用,例如 :=、+=、++=、Def.task 或 Def.setting。

我们的想法是最终将上面的第 5 行和第 6 行移到我们的插件中,以便我们可以像这样使用它:

name := "Foo"
version := "0.1"
scalaVersion := "2.12.8"
awsVersion := "1.11.250"

lazy val Core = project
  .settings(
    libraryDependencies ++= Seq(
      aws("aws-java-sdk-s3"),
      aws("aws-java-sdk-dynamodb"),
    )
  )

针对上述错误的任何解决方案或解决方法?


我们也试过这个:

def aws(module: String, version: String): ModuleID = "com.amazonaws" % module % version

...然后像这样使用:

awsVersion := "1.11.250"

lazy val Core = project
  .settings(
    libraryDependencies ++= Seq(
      aws("aws-java-sdk-s3", awsVersion.value),
      aws("aws-java-sdk-dynamodb", awsVersion.value),
    )
  )

虽然使用起来有点烦人,但它工作得很好,并且它破坏了使用 asettingKey开始的目的。

标签: scalasbt

解决方案


您不能在本地定义的方法(setting如. 这些值只能在其他或定义中使用,即错误消息taskawssettingtasksuch as :=, +=, ++=, Def.task, or Def.setting.

这是你可以做的。

AutoPluginproject文件夹中创建。

import sbt.{AutoPlugin, Def, ModuleID, settingKey}
import sbt.PluginTrigger.AllRequirements
import sbt._

object AwsPlugin extends AutoPlugin {

  override def trigger = AllRequirements

  type GetAWS = String => ModuleID

  object autoImport {
    val awsVersion =
      settingKey[String]("The version of aws SDK used for building.")
    val awsLibrary = settingKey[GetAWS]("Builds given AWS library")
  }

  import autoImport._

  override def projectSettings: Seq[Def.Setting[_]] = Seq(
    awsLibrary := { id =>
      "com.amazonaws" % id % awsVersion.value
    }
  )
}

以这种方式使用它build.sbt

awsVersion in ThisBuild := "1.11.250"

lazy val Core = project
  .settings(
    libraryDependencies ++= Seq(
      awsLibrary.value("aws-java-sdk-s3"),
      awsLibrary.value("aws-java-sdk-dynamodb"),
    )
  )

推荐阅读