我试图通过sbt插件添加库依赖项。应该按照其二进制scala版本将依赖项添加到每个子项目中,因此我遍历每个子项目。
private def inject(): State => State = { state =>
val extracted: Extracted = Project.extract(state)
val enrichedLibDepSettings = extracted.structure.allProjectRefs map { projRef =>
val projectScalaVersion = (scalaBinaryVersion in projRef)
libraryDependencies in projRef +=
compilerPluginOrg % (compilerPluginArtifact + "_" + projectScalaVersion.value) % compilerPluginVersion % "provided"
}
val newState = extracted.append(enrichedLibDepSettings, state)
val updateAfterLibAppend = extracted.structure.allProjectRefs map { projRef =>
println("running update: " + EvaluateTask(extracted.structure, update, newState, projRef)) }
state
}
但是这不起作用 - 打印输出显示没有通过libraryDependencies in projRef +=
附加的库依赖关系的跟踪,也没有发出任何错误,留下后续步骤来故障转移缺少的依赖项。这种技术可能有什么问题?
你会问为什么首先需要这个?为什么通过像这样的sbt插件添加库依赖?
虽然我们在sbt addCompilerPlugin
中,但它不能用于具有参数的编译器插件(-Xplugin
必须将指向jar的路径指定给scalac,因为它接受编译器插件参数,就实验而言)。因此,我们需要在将其解析为库依赖项之后通过-Xplugin
注入编译器插件(然后调整其文件路径位置以检查update
的结果)。因此我们需要通过sbt插件添加库依赖项。我们还需要为每个子项目执行此操作,因为多项目构建可能包含不同scala版本的子项目 - 每个项目都必须注入二进制兼容的编译器插件,以保持二进制兼容性。
顺便说一句,这可能会照亮我在黑暗中的事情:
在根项目的projectSettings
覆盖中添加库依赖项时 - 如下所示 - 依赖性似乎已解决,但这是无用的,因为它将相同的二进制版本应用于所有子项目,这是针对手头任务的性质(一些子项目自然会崩溃二进制不兼容)。另外我认为它将覆盖root的设置,而这里的目标是附加一个不覆盖现有设置的设置。
object Plugin extends AutoPlugin {
override lazy val projectSettings = Seq(
...
}
为每个子项目附加scalacOptions - 使用相同的技术 - 只需工作。
将+=
应用于上面的libraryDepenencies
,甚至不会影响inspect libraryDependencies
的输出,这与在override lazy val projectSettings
块的AutoPlugin
块内使用相同的习惯用法不同{{1}}。
答案 0 :(得分:4)
我想你可能会对projectSettings
的内容感到困惑。如果您展开AutoPlugin
,则可以定义每个项目应用的默认设置(在默认值之上),请参阅https://github.com/sbt/sbt/blob/v0.13.9/main/src/main/scala/sbt/Plugins.scala#L81
这意味着您只需使用典型的Setting
/ Task
符号添加您的人工制品,例如
def projectSettings = Seq(
libraryDependencies += {
val bin = scalaBinaryVersion.value
...
}
)
请注意,这是+=
,而不是:=
。这有帮助吗?