7

我正在尝试通过 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根项目的覆盖中添加库依赖项时 - 如下所示 - 依赖项似乎解决了,但这没用,因为它会应用相同的所有子项目的二进制版本,这违背了手头任务的性质(一些子项目自然会因二进制不兼容而崩溃)。另外我认为它会覆盖根的设置,而这里的目标是附加一个设置而不是覆盖现有设置。

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

一对线索?

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

  2. 应用+=libraryDepenencies上面,甚至不会影响 的输出inspect libraryDependencies,这与在 an 的一个override lazy val projectSettings块中使用相同的习语不同AutoPlugin

4

1 回答 1

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
    ...
  }
)

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

于 2015-12-13T18:09:00.367 回答