【问题标题】:How do scopes influence keys in a build? What is a scope axis?范围如何影响构建中的键?什么是范围轴?
【发布时间】:2014-09-25 06:05:28
【问题描述】:

我试图了解 SBT scope axes 是什么以及它们如何影响构建映射中的作用域键。

有三个范围轴:projectconfigurationtask

  1. 以下元组是构建映射的作用域键吗?

    (项目轴值、配置轴值、任务轴值、无作用域键值)

  2. 或者一个作用域键(概念上)是具有以下三种形式之一的一对?

    (项目轴的值,非作用域键的值)

    (配置轴的值,非作用域键的值)

    (任务轴的值,非作用域键的值)

  3. 或者作用域键是别的什么东西,如果是的话(从概念上)它看起来如何?

所以问题可能是什么是(概念上)作用域键?

  1. 是四元组吗?
  2. 是一对吗?
  3. 是别的什么吗,如果是的话,那么它看起来如何(概念上)?

【问题讨论】:

    标签: sbt


    【解决方案1】:

    来自Custom settings and tasks

    密钥具有以下三种类型之一:SettingKeyTaskKeyInputKey

    键的示例可以是:

    val scalaVersion = settingKey[String]("The version of Scala used for building.")
    

    它在 sbt 中默认可用,并且可以查询你执行的值show:

    > show scalaVersion
    [info] 2.10.4
    

    执行inspect 以了解密钥的详细信息(这不完全是密钥,而是您很快就会了解的设置):

    > inspect scalaVersion
    [info] Setting: java.lang.String = 2.10.4
    [info] Description:
    [info]  The version of Scala used for building.
    [info] Provided by:
    [info]  */*:scalaVersion
    [info] Defined at:
    [info]  (sbt.Defaults) Defaults.scala:236
    [info] Reverse dependencies:
    [info]  *:libraryDependencies
    [info]  *:scalaInstance
    [info]  *:evicted
    [info]  *:dependencyUpdatesData
    [info]  *:update
    [info]  *:allDependencies
    [info] Delegates:
    [info]  *:scalaVersion
    [info]  {.}/*:scalaVersion
    [info]  */*:scalaVersion
    [info] Related:
    [info]  */*:scalaVersion
    

    您可以使用宏 settingKey 定义自己的密钥:

    lazy val abc: sbt.SettingKey[String] = settingKey[String]("My own setting key")
    

    根据sbt.SettingKey的scaladoc:

    标识设置。它由三部分组成:范围、名称和与此键关联的值的类型。范围由 Scope 类型的值表示。名称和类型由 AttributeKey[T] 类型的值表示。实例是使用伴随对象构造的。

    正如您在 scaladoc 中所见,任何 SettingKey 都具有描述设置范围的必需 def scope: Scope。很快就会解释。

    在为它分配一个值(通过计算)之前,您无法看到构建中的键。您通过:=+=++=(更经常使用和推荐)或<++=<+=<<= 运算符(即是 sbt.SettingKey 的 scaladoc 中描述的 Scala 方法。

    abc := "my value"
    

    上面的行等同于下面的行(它们可以互换):

    abc.:=("my value")
    

    正如你在:=的定义中看到的:

    final def :=(v: T): Def.Setting[T]
    

    它的结果是Setting[T]

    所以,这对 (SettingKey[T], Initialize[T]) 或简单地说 (SettingKey[T], T) 是 Setting[T]

    Setting[T] 类型的设置,其中T 是设置评估结果的值的类型,描述了对构建中所有设置的映射的转换。这是构建加载后将在键下可用的值的配方。

    现在,最后一部分,作用域。

    您可能已经注意到,设置总是在范围内。您可以使用 final def in(scope: Scope): SettingKey[T] 更改设置的范围。

    使用inspect 了解设置。

    > inspect abc
    [info] Setting: java.lang.String = my value
    [info] Description:
    [info]  My new setting key
    [info] Provided by:
    [info]  {file:/Users/jacek/sandbox/sbt-theory/}sbt-theory/*:abc
    [info] Defined at:
    [info]  /Users/jacek/sandbox/sbt-theory/build.sbt:3
    [info] Delegates:
    [info]  *:abc
    [info]  {.}/*:abc
    [info]  */*:abc
    

    您可以看到设置将(Delegates 部分)委托给*:abc{.}/*:abc*/*:abc。我将描述为A/B:K 的其他地方是A - 项目轴,B - 配置轴和K 键或任务范围(因为 sbt 允许出现在 @ 之后的属性987654368@).

    猜猜*:abc 的值是多少。 inspect它。

    > inspect *:abc
    [info] Setting: java.lang.String = my value
    [info] Description:
    [info]  My new setting key
    [info] Provided by:
    [info]  {file:/Users/jacek/sandbox/sbt-theory/}sbt-theory/*:abc
    [info] Defined at:
    [info]  /Users/jacek/sandbox/sbt-theory/build.sbt:3
    [info] Delegates:
    [info]  *:abc
    [info]  {.}/*:abc
    [info]  */*:abc
    

    猜猜在全局配置* 中与此构建对应的{.}/*:abc 的值是多少,表示为{.}inspect它。

    > inspect {.}/*:abc
    [info] No entry for key.
    [info] Description:
    [info]  My new setting key
    [info] Delegates:
    [info]  {.}/*:abc
    [info]  */*:abc
    [info] Related:
    [info]  *:abc
    

    abc 设置在ThisBuild(又名thisBuild)范围内没有任何价值。在build.sbt 中使用:

    abc in ThisBuild := "abc in ThisBuild"
    

    inspect 它(在reload 重新加载构建的更改之后):

    > inspect {.}/*:abc
    [info] Setting: java.lang.String = abc in ThisBuild
    [info] Description:
    [info]  My new setting key
    [info] Provided by:
    [info]  {file:/Users/jacek/sandbox/sbt-theory/}/*:abc
    [info] Defined at:
    [info]  /Users/jacek/sandbox/sbt-theory/build.sbt:5
    [info] Delegates:
    [info]  {.}/*:abc
    [info]  */*:abc
    [info] Related:
    [info]  *:abc
    

    build.sbt 的变化如下:

    lazy val abc: sbt.SettingKey[String] = settingKey[String]("My new setting key")
    
    abc := "my value"
    
    abc in ThisBuild := "abc in ThisBuild"
    

    这表示 abc 键在每个范围内具有不同的值 - ThisBuildGlobal。清除?问吧!

    【讨论】:

    • 哇!谢谢Jacek的详细回答!
    • 谢谢!继续询问直到它完成(并且可以成为官方文档的一部分 - 这是我的愿望)。
    • “您将 Initialize[T] 分配给 SettingKey[T]”是什么意思?根据文档, := 方法采用 T 类型的值。我很困惑。 T 是如何初始化 [T] 的?它们有继承关系吗?
    • 我必须解决这个问题,因为 Initialize[T] 位于 < 之类的运算符中,使用频率较低(建议用于更高级的用途)。
    • 如果有两个配置轴值,比如 C1 和 C2,并且有两个项目轴值 P1 和 P2,那么 abc 可以有多少个不同的值会发生什么?九?三乘三?因为配置轴可以是:*,C1,C2 而项目轴可以是 {.},P1,P2?
    猜你喜欢
    • 1970-01-01
    • 2016-10-11
    • 2021-08-12
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    相关资源
    最近更新 更多