我已阅读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-unused-import)
其他什么?
他们的推理是
答案是List(-Ywarn-unused-import)。规则2找到projD / Compile / Zero,规则3找到projD / Zero / console,规则4找到ThisBuild / Zero / Zero。规则1选择projD / Compile / Zero,因为它具有子项目轴projD,并且配置轴具有比任务轴更高的优先级。
到目前为止,我能理解为什么Compile / console / sclacOptions将作用于projD / Compile / zero / scalacOptions。这是因为与我们想知道的密钥(Compile / console / scalacOptions)相比,projD / Compile / zero的配置轴比projD / zero / console更具体。
接下来,Compile / scalacOptions引用scalacOptions.value,接下来我们需要找到projD / Zero / Zero的委托。规则4找到ThisBuild / Zero / Zero,因此它解析为List(-Ywarn-unused-import)。
在这里,我无法理解为什么ThisBuild / Zero / Zero赢得projD / Compile / Zero。因为我们想要找到的键的范围是projD / zero / zero,所以projD / Compile / zero与Thisbuild [遵循参考中的规则1]相比具有更具体的值。
我认为原因是Compile / scalacOptions具有scalacOptions.value的值,它生成递归定义。然后,我们可以使用projD / Zero / console。
答案 0 :(得分:2)
我认为你对解释第二部分中对差异范围的引用感到有些困惑。让我们明确写下示例中的所有范围:
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)