范围在sbt中很重要。我完全没问题。但也有一些委托规则允许您构建设置的分层结构。我想用它来为更具体的规则带来额外的设置。为什么测试范围设置不能保持正确的值?
import sbt._
import Keys._
object TestBuild extends Build {
val sourceExample = settingKey[Seq[String]]("example source for setting dependency")
val targetExample = settingKey[Seq[String]]("example of a dependent setting")
override lazy val settings = super.settings ++ Seq (
sourceExample := Seq("base"),
targetExample := "extended" +: sourceExample.value,
sourceExample in Test += "testing"
)
}
的例子给了我意想不到的输出:
> show compile:sourceExample
[info] List(base)
> show test:sourceExample
[info] List(base, testing)
> show compile:targetExample
[info] List(extended, base)
> show test:targetExample
[info] List(extended, base)
我希望test:targetExample
是List(extended, base, testing)
不List(extended, base)
。一旦我得到结果,我立即找出它为什么如图所示工作。 test:targetExample
代表来自*:targetExample
的计算值,但不是用于在嵌套范围内计算它的规则。
这种行为给我编写自己的插件带来了两个困难。我有额外的工作来在每个范围内定义与插件开发人员相同的规则。我必须记住内部任务的范围定义以正确使用它作为用户。
我该如何克服这种不便?我想介绍的调用设置的语义,而不是的调用值。什么技巧可以为它工作?
P.S. libraryDependencies in Test
看起来更简洁,使用% test
。
我应该清楚地知道,我完全理解sbt派生值,就像它在文档中描述的一样。它的工作原理就是让它工作。
但是我为什么要服从规则?我看到他们完全违反直觉。 Sbt引入了继承语义,它不同于以前如何定义继承。当你写
trait A { lazy val x : Int = 5 }
trait B extends A { lazy val y : Int = x * 2}
trait C extends A { override lazy val x : Int = 3 }
你期望(new B with C).y
是6,不知道10,这将是真正10可让您正确使用这种继承的,但离开你的欲望寻找实现继承的更多常规手段。您甚至可以根据name->value
字典编写自己的实现。根据编程的第十个规则,你可以继续进行。
因此,我正在寻找一种能够根据常见语言实现继承语义的黑客攻击。作为一个起点,我可能会建议编写command来扫描所有设置并明确将它们从父母推送到孩子。而且每次运行sbt时都会自动调用该命令。
但是它对我来说似乎太脏了,所以我很好奇,如果有更优美的方式来实现类似的语义。
如果还有更多设置,我应该怎么做?可以使用'libraryDependencies'作为例子。它不是每个任务定义的,因为它太麻烦,并且实现了自定义推理机制。这是'%test'依赖性定义的一部分。 – ayvango
@ayvango我不确定我是否正确地得到它,但你可以添加不作为范围的设置作为另一个'lazy val',并将其添加到'settings',而不通过'inConfig'方法进行范围设置。但是,如果你在'basePluginSettings'中定义它,我想它也可以工作,你只是不要在配置中覆盖它 – lpiepiora