scala - 值查找解析为 sbt 插件中的错误范围

标签 scala sbt

我正在尝试为我的项目编写一个用于处理资源的 sbt 插件。简而言之,它是在 sbt 中制作的 maven 配置文件。当我检查 prod:dictionary 时,我得到了这个 Map 的预期状态,但是,当我尝试 prod:expandParameters 时,我得到一个空的 map 。我如何从运行命令的确切配置范围内获取 dictionary 的值?

项目/ResourceFiltering.scala

import sbt._
import sbt.Keys._
import sbt.internal.util.ManagedLogger
import scala.util.matching.Regex

object ResourceFiltering extends AutoPlugin {

  override def trigger = AllRequirements

  sealed trait Keys {
    lazy val expandParameters = taskKey[Unit]("")

    lazy val extensions = settingKey[Seq[String]]("")
    lazy val pattern    = settingKey[Regex]("")
    lazy val dictionary = settingKey[Map[String, String]]("")
  }

  object autoImport extends Keys

  import autoImport._

  override val projectSettings: Seq[Def.Setting[_]] = Seq(
    Zero / extensions := Seq("conf", "properties", "xml"),
    Zero / pattern    := """(\$\{()\})""".r,
    Zero / dictionary := Map.empty,
    expandParameters := {
      val log: ManagedLogger = streams.value.log
      log.info(s"""|Parameter expansion
                   |Configuration: $configuration
                   |Extensions: ${extensions value}
                   |Pattern: ${pattern value}
                   |Dictionary: ${dictionary value}
                """.stripMargin)
    }
  )
}

build.sbt

enablePlugins(ResourceFiltering)

lazy val Prod  = config("prod")  extend Compile describedAs "Scope to build production packages."
lazy val Stage = config("stage") extend Compile describedAs "Scope to build stage packages."
lazy val Local = config("local") extend Compile describedAs "Scope to build local packages."

lazy val root = (project in file("."))
  .configs(Prod, Stage, Local)
  .settings(sharedSettings)

lazy val sharedSettings = 
  prodSettings ++ stageSettings ++ localSettings

lazy val defaults = Defaults.configSettings ++ Defaults.configTasks ++ Defaults.resourceConfigPaths

lazy val prodSettings = inConfig(Prod)(defaults ++ Seq(
  dictionary ++= Profiles.prod
))

lazy val stageSettings = inConfig(Stage)(defaults ++ Seq(
  dictionary ++= Profiles.stage
))

lazy val localSettings = inConfig(Local)(defaults ++ Seq(
  dictionary ++= Profiles.local
))

项目/Profiles.scala

lazy val default: Map[String, String] = local

lazy val local: Map[String, String] = Map("example" -> "local")

lazy val stage: Map[String, String] = Map("example" -> "stage")

lazy val prod: Map[String, String] = Map("example" -> "prod")

最佳答案

分析 Plugins Best Practices我会就配置和范围界定提出以下建议。

globalSettings 中提供默认值,而不是像这样在 projectSettings 中提供默认值

override lazy val globalSettings = Seq(
  dictionary := Map.empty
)

接下来像这样将expandParameters 的基础配置收集到它自己的序列中

lazy val baseResourceFilteringSettings: Seq[Def.Setting[_]] = Seq(
  extensions := Seq("conf", "properties", "xml"),
  pattern := """(\$\{()\})""".r,
  expandParameters := {
    val log: ManagedLogger = streams.value.log
    log.info(
      s"""|Parameter expansion
          |Configuration: $configuration
          |Extensions: ${extensions value}
          |Pattern: ${pattern value}
          |Dictionary: ${dictionary value}
       """.stripMargin
    )
  }
)

请注意 dictionary 未在 baseResourceFilteringSettings 中初始化,而是默认来自 globalSettings

现在我们已经处理了我们的默认值并且我们有了我们的基本配置,所以我们可以像这样使用 inConfig 通过配置范围继续“特化”它

lazy val localSettings = inConfig(Local)(defaults ++ Seq(
  dictionary ++= Profiles.local
) ++ baseResourceFilteringSettings)

请注意我们如何将 baseResourceFilteringSettings 的范围限定为 Local 配置,以及 dictionary++= Profiles.local

现在执行 ;reload;local:expandParameters 应该输出

[info] Parameter expansion
[info] Configuration: SettingKey(This / This / This / configuration)
[info] Extensions: List(conf, properties, xml)
[info] Pattern: (\$\{()\})
[info] Dictionary: Map(example -> local)

我们在哪里看到 Dictionary: Map(example -> local) 根据需要。

这里是ResourceFiltering的完整代码

object ResourceFiltering extends AutoPlugin {

  override def trigger = AllRequirements

  sealed trait Keys {
    lazy val expandParameters = taskKey[Unit]("")

    lazy val extensions = settingKey[Seq[String]]("")
    lazy val pattern = settingKey[Regex]("")
    lazy val dictionary = settingKey[Map[String, String]]("")

    lazy val baseResourceFilteringSettings: Seq[Def.Setting[_]] = Seq(
      extensions := Seq("conf", "properties", "xml"),
      pattern := """(\$\{()\})""".r,
      expandParameters := {
        val log: ManagedLogger = streams.value.log
        log.info(
          s"""|Parameter expansion
              |Configuration: $configuration
              |Extensions: ${extensions value}
              |Pattern: ${pattern value}
              |Dictionary: ${dictionary value}
           """.stripMargin
        )
      }
    )
  }

  object autoImport extends Keys
  import autoImport._

  override lazy val globalSettings = Seq(
    dictionary := Map.empty
  )
}

也考虑像这样将配置定义移动到插件中

object ResourceFiltering extends AutoPlugin {

  override def trigger = AllRequirements

  sealed trait Keys {
    lazy val Prod = config("prod") extend Compile describedAs "Scope to build production packages."
    lazy val Stage = config("stage") extend Compile describedAs "Scope to build stage packages."
    lazy val Local = config("local") extend Compile describedAs "Scope to build local packages."

    lazy val expandParameters = taskKey[Unit]("")

    lazy val extensions = settingKey[Seq[String]]("")
    lazy val pattern = settingKey[Regex]("")
    lazy val dictionary = settingKey[Map[String, String]]("")

    lazy val baseResourceFilteringSettings: Seq[Def.Setting[_]] = Seq(
      extensions := Seq("conf", "properties", "xml"),
      pattern := """(\$\{()\})""".r,
      expandParameters := {
        val log: ManagedLogger = streams.value.log
        log.info(
          s"""|Parameter expansion
              |Configuration: $configuration
              |Extensions: ${extensions value}
              |Pattern: ${pattern value}
              |Dictionary: ${dictionary value}
           """.stripMargin
        )
      }
    )
  }

  object autoImport extends Keys
  import autoImport._

  override lazy val globalSettings = Seq(
    dictionary := Map.empty
  )

  override val projectSettings: Seq[Def.Setting[_]] =
    inConfig(Stage)(baseResourceFilteringSettings) ++
      inConfig(Prod)(baseResourceFilteringSettings) ++
      inConfig(Local)(baseResourceFilteringSettings)
}

这样我们就不必记住将 baseResourceFilteringSettings 添加到配置范围,只需编写即可

lazy val localSettings = inConfig(Local)(defaults ++ Seq(
  dictionary ++= Profiles.local
)

关于scala - 值查找解析为 sbt 插件中的错误范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58188804/

相关文章:

Scala Spark 1.5.2 RDD[任一[A,B]]

scala - 我可以为 route 的所有入口点创建默认的 OPTIONS 方法指令吗?

具有多个领域的SBT凭证文件

java - 查看 SBT 发出的确切 java 命令

scala - 为 Seq 提供 Get 实例

Scala:使用依赖注入(inject)协调类型类

playframework - 无法使用 sbt 创建 Play 框架 Web 应用程序?

scala - 为什么单个 Play Framework 应用程序中有许多 "target"文件夹?

scala - 使用 sbt 加载 github 项目时发生 AttributeKeyID 冲突

scala - 如何修复 sbt 1.3.0 加载项目中的 "Could not find proxy for val base"错误