【问题标题】:Adding a library dependency via an sbt plugin - per sub-project通过 sbt 插件添加库依赖项 - 每个子项目
【发布时间】:2016-03-19 03:00:32
【问题描述】:

我正在尝试通过 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 必须指定 jarac 的路径,以便它接受编译器插件参数,就实验而言显示)。因此,在将编译器插件解析为库依赖项后,我们需要通过-Xplugin 注入编译器插件(然后调整其文件路径位置以检查update 的结果)。因此,我们确实需要通过 sbt 插件添加库依赖项。我们还需要为每个子项目执行此操作,因为多项目构建可能包含不同 scala 版本的子项目 - 每个子项目都必须注入二进制兼容的编译器插件,以保持二进制兼容性。

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

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

一对线索?

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

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

【问题讨论】:

  • 这里没有 sbt 的语法高亮显示....
  • 问题解决了吗?

标签: sbt scalac


【解决方案1】:

我想你可能对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
    ...
  }
)

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

【讨论】:

  • 确实我错误地假设了projectSettings 所做的事情,指出这一点会有所帮助。不幸的是,我仍然希望每个子项目都有自己的附加设置 - 这样一个具有不同 scala 版本的子项目的项目将获得插件的相应二进制版本每个子项目 .为此,我观察到像libraryDependencies += compilerPluginOrg % (compilerPluginArtifact + "_" + scalaBinaryVersion.value) % compilerPluginVersion 这样的东西会在所有项目中插入相同的版本,与此相反。因此涉及更多的方案。
  • 那么这意味着您的scalaBinaryVersion 在插件加载后被设置。尝试将您的配置放入自定义设置之后列出的 val 中。坦率地说,我不知道混合版本的 scala 项目将如何工作。标准方法是交叉构建,要么使用 sbt 的过度工程解决方案,要么通过 sbt-extra 提供的++SCALA_VERSION
  • 这不仅仅是关于交叉构建场景本身:例如查看 parboiled2 的构建,scala 版本在所有子项目中指定为 2.11,而整个项目没有指定版本(因此2.10)。除了将这种构建作为病态的借口(我可能不会)之外,我认为这需要为每个子项目引入正确版本的编译器插件。
  • 我可能不知道在 sbt 插件加载 v.s. 之后会设置 scalaBinaryVersion 这样的东西。之前..列举所有可能的含义,我可能完全误解了那里。
猜你喜欢
  • 2019-08-06
  • 2020-01-20
  • 2013-05-28
  • 2013-12-06
  • 2017-08-19
  • 2011-08-27
  • 2019-04-11
  • 1970-01-01
  • 2011-12-16
相关资源
最近更新 更多