通过 sbt 插件添加库依赖项 - 每个子项目 [英] Adding a library dependency via an sbt plugin - per sub-project

查看:68
本文介绍了通过 sbt 插件添加库依赖项 - 每个子项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 sbt 插件添加库依赖项.依赖项应该添加到每个子项目的二进制 scala 版本中,所以我遍历每个子项目.

I am trying to add a library dependency through an sbt plugin. The dependency should be added to each sub-project per its binary scala version, so I iterate through each subproject.

  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 += 附加库依赖的痕迹,也没有发出任何错误,留下后续步骤故障转移丢失的依赖.这种技术可能有什么问题?

However this is not working - the printed output shows no trace of a library dependency being appended through libraryDependencies in projRef +=, nor is any error issued, leaving subsequent steps to fail over the missing dependency. What might be wrong with this technique?

你首先会问为什么需要这个?为什么要通过这样的 sbt 插件添加库依赖项?

You will ask why is this needed in the first place? why add a library dependency through an sbt plugin like that?

虽然我们在 sbt 中有 addCompilerPlugin,但它不能用于有参数的编译器插件(-Xplugin 必须为 scalac 指定一个 jar 的路径,对于就实验而言,它接受编译器插件参数).因此,我们需要在将编译器插件解析为库依赖项后通过 -Xplugin 注入它(然后修改其文件路径位置以检查 update 的结果).因此,我们确实需要通过 sbt 插件添加库依赖项.我们还需要为每个子项目执行此操作,因为多项目构建可能包含不同 Scala 版本的子项目 - 每个子项目都必须注入一个二进制兼容的编译器插件,以保持二进制兼容性.

Although we have in sbt addCompilerPlugin, it cannot be used for compiler plugins that have arguments (-Xplugin with a path to a jar must be specified to scalac, for it to accept compiler plugin arguments, as far as experimentation shows). Hence we need to inject the compiler plugin via -Xplugin after having it resolved as a library dependency (then fiddle its file path location inspecting the result of update). Hence we do need to add a library dependency via an sbt plugin. And we further need to do this per sub-project, as a multi-project build may house sub-projects of varying scala versions - each one must have a binary compatible compiler plugin injected, in order to maintain binary compatibility.

顺便说一句,这可能会照亮我一头雾水的事情:在根项目的 projectSettings 覆盖中添加库依赖项时 - 如下所示 - 依赖项似乎解决了,但这没有用,因为它将对所有子项目应用相同的二进制版本,这违背了手头任务的性质(一些子项目自然会因二进制不兼容而崩溃).另外我认为它会覆盖根的设置,而这里的目标是附加一个设置而不是覆盖现有设置.

By the way, and this might illuminate something I'm in the dark over: When adding the library dependency in a projectSettings override for the root project - as below - the dependency seems to resolve, but that is useless, as it will apply the same binary version to all sub-projects, which is against the nature of the task at hand (some sub-projects will naturally crash over binary incompatibility). Also I think it will override the root's settings whereas the goal here is to append a setting not to override existing settings.

object Plugin extends AutoPlugin {
  override lazy val projectSettings = Seq(
    ...
}

一对线索?

  1. 为每个子项目附加 scalacOptions - 使用相同的技术 - 很简单.

  1. Appending scalacOptions per sub-project - using the same technique - simply works.

+= 应用到上面的 libraryDepenencies,甚至不影响 inspect libraryDependencies 的输出,这与使用相同的习惯用法不同在 AutoPluginoverride lazy val projectSettings 块内.

Applying += to libraryDepenencies above, does not even affect the output of inspect libraryDependencies, unlike when using the same idiom inside a an override lazy val projectSettings block of an AutoPlugin.

推荐答案

我想您可能对 projectSettings 是什么感到困惑.如果您扩展 AutoPlugin,您可以定义为每个项目应用的默认设置(在默认设置之上),请参阅 https://github.com/sbt/sbt/blob/v0.13.9/main/src/main/scala/sbt/Plugins.scala#L81

I think you might be confused about what projectSettings is. If you extend AutoPlugin, you can define the default settings that are applied (on top of the defaults) for each project, see https://github.com/sbt/sbt/blob/v0.13.9/main/src/main/scala/sbt/Plugins.scala#L81

这意味着您可以使用典型的Setting/Task 符号简单地在此处添加您的人工制品,例如

This means you could simply add your artefact here using the typical Setting / Task notation, e.g.

def projectSettings = Seq(
  libraryDependencies += {
    val bin = scalaBinaryVersion.value
    ...
  }
)

注意这是+=,而不是:=.这有帮助吗?

note that this is +=, not :=. Does that help?

这篇关于通过 sbt 插件添加库依赖项 - 每个子项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆