我有一个简单的多项目,其中根聚合项目a
和b
。根项目加载了我正在编写的插件,该插件应该可以轻松地与我们公司的构建系统集成。
lazy val a = project in file("a")
lazy val b = project in file("b")
现在,我想在插件中定义一些在根项目中没有意义的Setting
,并且每个子项目可以有不同的值。但是,如果我只是将它们定义为
object P extends Plugin {
val kind = settingKey[Kind]("App or Lib?")
val ourResolver = settingKey[Resolver]("...")
override def projectSettings = Seq(
// I want this to only be defined in a and b, where `kind` is defined
ourResolver <<= kind { k => new OurInternalResolver(k) }
)
}
然后sbt会抱怨无法定义ourResolver
,因为根项目中未定义kind
。
有没有办法为此设置指定范围(ourResolver
),以便在除根项目之外的每个聚合项目中定义?
或者我是否必须将其设为SettingKey[Option[_]]
并默认将其设为None
?
编辑:我有很多设置,逐渐依赖kind
然后依赖ourResolver
等等,这些设置应该只定义在哪里(读取) :“在项目范围中,”)kind
已定义。为示例代码添加了ourResolver
以反映这一点。
答案 0 :(得分:1)
但是,如果我只是将它们定义为....
设置密钥并没有什么神奇之处。密钥只是String
条目与类型绑定。所以你可以按照你现在的方式定义你的密钥就好了。
有没有办法为此设置指定范围,以便在除根项目之外的每个聚合项目中定义设置?
设置包含以下四项内容:
def evaluate(Settings[Scope]): T
)如果您没有另行指定,则您的设置已限定为构建定义中的特定项目。
lazy val a = (project in file("a")).
settings(commonSettings: _*).
settings(
name := "a",
kind := Kind.App,
libraryDependencies ++= aDeps(scalaVersion.value)
)
lazy val b = (project in file("b")).
settings(commonSettings: _*).
settings(
name := "b",
kind := Kind.Lib,
libraryDependencies ++= bDeps(scalaVersion.value)
)
lazy val root = (project in file(".")).
settings(commonSettings: _*).
settings(
name := "foo",
publishArtifact := false
).
aggregate(a, b)
在上文中,kind := Kind.App
设置的范围是项目a
。所以这会在字面上回答你的问题。
sbt会抱怨在根项目中没有定义类型。
这部分我不清楚发生了什么。加载构建时会发生这种情况吗?或者当你在sbt shell中输入kind
时会发生什么?如果您在启动时看到它可能意味着您有一个尝试依赖kind
密钥的任务/设置。请勿加载设置,或重新实现设置,以免使用kind
。
避免此问题的另一种方法可能是放弃使用根聚合。切换到子项目并运行任务或使用ScopeFilter
构建显式聚合。
答案 1 :(得分:0)
我最终通过利用derive创建DerivedSetting
的方法来实现这一目标。然后,sbt 将在定义其依赖项的每个范围内自动扩展这些设置。
因此我现在可以将我的插件编写为:
object P extends Plugin {
val kind = settingKey[Kind]("App or Lib?")
val ourResolver = settingKey[Resolver]("...")
def derivedSettings = Seq(
// I want this to only be defined in a and b, where `kind` is defined
ourResolver <<= kind { k => new OurInternalResolver(k) }
) map (s => Def.derive(s, trigger = _ != streams.key))
override def projectSettings = derivedSettings ++ Seq( /* other stuff */ )
}
如果我在kind
和a
的{{1}}中定义b
,那么build.sbt
也将最终在这些范围内定义。