scala - 如何在 SBT 中的 onLoad Hook 上应用设置更改?

标签 scala sbt

我在 SBT 中有一些设置,我需要在加载的插件执行一些副作用后生成值。 onLoad Hook 似乎是执行此操作的最佳位置。钩子(Hook)接收一个 State,转换它并返回一个新的。使用 State 方法很容易安排命令,但更改设置似乎并不容易。

我首先尝试了以下代码,它失败了,因为它似乎导致对 onLoad 的递归调用,并且由于重复的 actor 名称(可能是递归的产物)而失败。

onLoad in Global := (onLoad in Global).value andThen { state =>
  val settings = generateMySettings
  Project.extract(state).append(settings, state)
}

我看到的另一种选择是直接在 State 中调用 putupdate 方法,但这看起来很丑陋并且容易出错。有更好/更清洁的方法吗?

最佳答案

github sbt repo 上有一个很好的例子,说明如何在 onLoad Hook 中“重新连接”项目设置:https://github.com/sbt/sbt-community-plugins/blob/master/project/Dependencies.scala

我不确定为什么 onLoad Hook 可能会被执行多次,但解决您的问题的方法是简单地定义一个 bool 标志属性,以便在该标志尚未触发时有条件地仅调用您的 Hook 一次。

在提到的例子中,他们就是这样做的,

trait GenerateMySettingsStartup extends Build {
  private lazy val generated =  AttributeKey[Boolean]("my-settings-generated")
  def generateCommandName = "generate-my-settings"

  private final def fixState(state: State): State = 
    if(state.get(generated) getOrElse false) {
      state
    } else {
      // >>> generate and append your settings here <<<
      state.put(generated, true)
    }

  private def initialize = Command.command(generateCommandName)(fixState(_))

  final def generateSettings: Seq[Setting[_]] = Seq(
    commands += initialize,
    // initialize onLoad task if not yet defined
    onLoad in Global <<= (onLoad in Global) ?? idFun[State],
    // append generateCommandName onLoad handler
    onLoad in Global <<= (onLoad in Global) apply ( _ andThen (generateCommandName :: _))
  )
}

然后只需将 GenerateMySettingsStartup#generateSettings 应用到您的项目设置。

附言不确定我是否完全正确,但在这里我认为 onLoad Hook 是通过 Command 定义的,因为它可以访问可能未在某些范围内定义的状态,这只是一个疯狂的猜测所以如果我的假设是错误的请澄清我,谢谢!

关于scala - 如何在 SBT 中的 onLoad Hook 上应用设置更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27760279/

相关文章:

generics - 如何在 Scala 中传递原始类型?

scala - 为什么我的jar 看不到环境中的HBase 配置?

scala - 玩转 2.0 Scala 和异步回调

scala - 如何使用 SBT 编译测试而不运行它们

scala - 从 Scala 源访问 SBT 设置

scala - OCI错误 “/opt/docker/bin/my_job”:使用sbt docker:publishLocal没有此类文件或目录

scala - SBT 子项目相互依赖关系

java - 无法连接到 grpc 服务器并获取 'First received frame was not SETTINGS'

scala - 如何构建使用 sbt 作为构建系统的项目?

scala - 使用SBT将生成的JAR文件发布到Maven