在SBT中定义子项目之间的插件依赖关系?

Li *_*oyi 9 sbt

编辑:

自从我提出赏金后,我想我应该重申一下这个问题

一个SBT项目怎么能P有两个子项目,A并且B设置了B一个插件依赖A,这是一个SBT插件?

  • 赋予P插件依赖性A不起作用,因为A依赖于其他内容P,这导致循环依赖图
  • 它必须是一个插件依赖项,因为它A是运行B测试套件所需的插件.
  • dependsOn 不起作用,因为,它必须是一个插件依赖

我想知道其中任何一个

  • 怎么做,或
  • 为什么这是不可能的,以及接下来最好的选择是什么.

编辑:澄清它是一个插件依赖,因为构建依赖是模糊的

Jac*_*ski 12

如果您有一个带有"项目P和两个子项目A和B"的多项目构建配置,则归结为以下配置:

build.sbt

lazy val A, B = project
Run Code Online (Sandbox Code Playgroud)

根据设计,"如果没有为构建中的根目录定义项目,则sbt会创建一个默认的项目来聚合构建中的所有其他项目." 这意味着你将有一个隐含的根项目,比如说P(但名称是任意的):

[plugin-project-and-another]> projects
[info] In file:/Users/jacek/sandbox/so/plugin-project-and-another/
[info]     A
[info]     B
[info]   * plugin-project-and-another
Run Code Online (Sandbox Code Playgroud)

这为我们提供了预期的项目结构.关于定义B和之间的插件依赖性A.

在SBT项目定义插件的唯一方法就是使用project目录这就是plugins项目的构建定义- "一个插件定义为<主要项目> /项目/项目." 这意味着定义项目插件依赖项的唯一方法A是使用以下方法:

项目/ plugins.sbt

addSbtPlugin("org.example" % "example-plugin" % "1.0")

lazy val plugins = project in file(".") dependsOn(file("../A"))
Run Code Online (Sandbox Code Playgroud)

在这个构建配置中,plugins项目依赖于另一个SBT项目,而这个项目恰好是我们A的插件项目.

A/build.sbt

// http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin
sbtPlugin := true

name := "example-plugin"

organization := "org.example"

version := "1.0"
Run Code Online (Sandbox Code Playgroud)

A/MyPlugin.scala

import sbt._

object MyPlugin extends Plugin
{
    // configuration points, like the built in `version`, `libraryDependencies`, or `compile`
    // by implementing Plugin, these are automatically imported in a user's `build.sbt`
    val newTask = taskKey[Unit]("A new task.")
    val newSetting = settingKey[String]("A new setting.")

    // a group of settings ready to be added to a Project
    // to automatically add them, do
    val newSettings = Seq(
        newSetting := "Hello from plugin",
        newTask := println(newSetting.value)
    )

    // alternatively, by overriding `settings`, they could be automatically added to a Project
    // override val settings = Seq(...)
}
Run Code Online (Sandbox Code Playgroud)

这两个文件 - build.sbt以及MyPlugin.scala目录中的A- 构成了插件项目.

唯一缺少的是定义项目的插件A设置B.

B/build.sbt

MyPlugin.newSettings
Run Code Online (Sandbox Code Playgroud)

这就是你在SBT中可以做的事情.如果您想拥有多项目构建配置并且(子)项目之间具有插件依赖性,除了上面描述的内容之外,您没有太多选择.

话虽如此,让我们看看项目中的插件A是否可访问.

[plugin-project-and-another]> newTask
Hello from plugin
[success] Total time: 0 s, completed Feb 13, 2014 2:29:31 AM
[plugin-project-and-another]> B/newTask
Hello from plugin
[success] Total time: 0 s, completed Feb 13, 2014 2:29:36 AM
[plugin-project-and-another]> A/newTask
[error] No such setting/task
[error] A/newTask
[error]          ^
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到,newTask(来自项目的插件A)可以在(默认)根项目和项目中使用B,但不能在A.


Li *_*oyi 1

正如 Jacek 所说,这不能按照我的意愿完成,因为子项目不能有根项目没有的 SBT 插件。另一方面,邮件列表上的讨论包含几种替代方案,毫无疑问对将来遇到此问题的任何人都有用。

编辑:嗯,最后提到的替代方案(sbt 脚本等)使用起来既困难又笨重。我的最终解决方案是在存储库内有一个单独的项目(而不是子项目),该项目通过常春藤坐标依赖于原始项目,并使用 bash 发布第一个项目,进入第二个项目并运行其测试

sbt publishLocal; cd test; sbt test; cd ..
Run Code Online (Sandbox Code Playgroud)

我一直认为像 SBT 这样的事情的目的是避免做这种猛烈的体操,但绝望的时刻需要绝望的措施......