代码之家  ›  专栏  ›  技术社区  ›  ruach

SBT中的范围委派是如何工作的?

  •  2
  • ruach  · 技术社区  · 7 年前

    我读过一篇 reference 了解SBT中范围委派的工作方式。

    从上面的参考页中,我摘录了一个练习D。

    ThisBuild / scalacOptions += "-Ywarn-unused-import"
    
    lazy val projD = (project in file("d"))
      .settings(
        test := {
          println((Compile / console / scalacOptions).value)
        },
        console / scalacOptions -= "-Ywarn-unused-import",
        Compile / scalacOptions := scalacOptions.value // added by sbt
      )
    

    如果运行projD/test,您会看到什么?

    列表()

    列表(-Ywarn未使用的导入)

    还有别的吗?

    他们的推理是

    答案是List(-Ywarn unused import)。规则2查找projD/Compile/Zero,规则3查找projD/Zero/console,规则4查找ThisBuild/Zero/Zero。规则1选择projD/Compile/Zero,因为它具有子项目轴projD,并且配置轴的优先级高于任务轴。

    到目前为止,我可以理解为什么编译/控制台/sclacOptions的作用域是projD/编译/零/scalacOptions。这是因为projD/Compile/zero的配置轴比我们想要知道的键(Compile/console/scalacOptions)更具体。

    接下来,Compile/scalacOptions指的是scalacOptions。值,我们接下来需要为projD/Zero/Zero找到一个委托。规则4找到这个build/Zero/Zero,因此它解析为List(-Ywarn unused import)。

    在这里,我不明白为什么这个build/Zero/Zero赢得了projD/Compile/Zero。因为我们要查找的键的范围是projD/zero/zero,所以projD/Compile/zero与Thisbuild相比具有更具体的值[遵循参考中的规则1]。

    我认为原因是Compile/scalacOptions具有scalacOptions的价值。值,该值生成递归定义。然后,我们可以使用projD/Zero/控制台。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Justin Kaeser    7 年前

    我想你只是对解释的第二部分中对差异范围的引用有点困惑。让我们明确地写下示例中的所有作用域:

    ThisBuild / Zero / Zero / scalacOptions += "-Ywarn-unused-import"
    
    lazy val projD = (project in file("d"))
      .settings(
        test := { println((Compile / console / scalacOptions).value) }
      )
    
    projD / Zero / console / scalacOptions -= "-Ywarn-unused-import"
    projD / Compile / Zero / scalacOptions := (projD / Zero / Zero / scalacOptions).value
    

    我必须去掉这两个设置,才能参考 projD ,但除此之外,它的定义是相同的。

    从第一部分开始你就明白了 projD / Compile / Zero / scalacOptions 赢得 projD / Zero / console / scalacOptions ThisBuild / ... .

    现在让我们看看它的价值,并在我们的任务中使用它。但它的价值是什么?指的是 projD / Zero / Zero / scalacOptions 没有明确定义。所以我们需要为它找到一个代表。目前我们还没有与 projD / Compile projD / console 范围内唯一合适的键在范围内 ThisBuild / Zero / Zero .

    我试着在这里举例说明 / scalacOptions 要节省空间,请执行以下操作:

    projD     / Compile / console // the one we need in the task
    projD     / Zero    / console // could be applied by rule 3, but looses to the next one:
    projD     / Compile / Zero    // applies by rule 2 (task scope delegation), defined with next one:
    projD     / Zero    / Zero    // not defined explicitly, so is delegated:
    ThisBuild / Zero    / Zero    // applies by rule 4 (project scope delegation)