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

在SBT中定义子项目之间的插件依赖关系? 编辑:,sbt,Sbt,既然我提出了悬赏,我想我应该重申一下这个问题 一个SBT项目p,有两个子项目a和B,如何设置B对a具有插件依赖性,这是一个SBT插件 给P一个插件依赖于a是不起作用的,因为a依赖于P中的其他东西,这会导致一个循环依赖关系图 它必须是一个插件依赖项,因为a是运行Bs测试套件所需的插件 dependsOn不起作用,因为它必须是插件依赖项 我想知道你们俩中的任何一个 如何做到这一点,或者 为什么这是不可能的,以及下一个最好的替代方案是什么 编辑:澄清这是一个插件依赖,因为构建依赖是不明确的这个

既然我提出了悬赏,我想我应该重申一下这个问题

一个SBT项目
p
,有两个子项目
a
B
,如何设置
B
a
具有插件依赖性,这是一个SBT插件

  • P
    一个插件依赖于
    a
    是不起作用的,因为
    a
    依赖于
    P
    中的其他东西,这会导致一个循环依赖关系图
  • 它必须是一个插件依赖项,因为
    a
    是运行
    B
    s测试套件所需的插件
  • dependsOn
    不起作用,因为它必须是插件依赖项
我想知道你们俩中的任何一个

  • 如何做到这一点,或者
  • 为什么这是不可能的,以及下一个最好的替代方案是什么

编辑:澄清这是一个插件依赖,因为构建依赖是不明确的

这个答案可能包括解决方案


简而言之,通过该链接设置
exportJars:=true
,并在Compile中获取(子)项目
exportedProducts的jar文件路径,你有一个带有子项目a和B的父项目P。然后你声明a依赖于P。但是P是a和B的集合,因此依赖于a。所以你已经在a和P之间存在循环依赖关系。这永远不会起作用


你必须把p分成两部分:A依赖的部分(我们称之为A')和其余部分(我们称之为p_-rest)。然后你扔掉P,做一个新的项目P_rest,由a',a和B组成,a依赖于a'

当您有一个带有“项目p和两个子项目a和B”的多项目构建配置时,它归结为以下配置:

构建.sbt

lazy val A, B = project
addSbtPlugin("org.example" % "example-plugin" % "1.0")

lazy val plugins = project in file(".") dependsOn(file("../A"))
// http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin
sbtPlugin := true

name := "example-plugin"

organization := "org.example"

version := "1.0"
MyPlugin.newSettings
根据设计,这意味着您将拥有一个隐式根项目,例如
p
(但名称是任意的):

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

在SBT项目中定义插件的唯一方法是使用
project
目录,该目录是
plugins
项目的构建定义-这意味着定义项目
a
的插件依赖关系的唯一方法是使用以下内容:

项目/插件.sbt

lazy val A, B = project
addSbtPlugin("org.example" % "example-plugin" % "1.0")

lazy val plugins = project in file(".") dependsOn(file("../A"))
// http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin
sbtPlugin := true

name := "example-plugin"

organization := "org.example"

version := "1.0"
MyPlugin.newSettings
在这个构建配置中,
plugins
项目依赖于另一个SBT项目,而这个SBT项目恰好是我们的
A
,它又是一个插件项目

A/build.sbt

lazy val A, B = project
addSbtPlugin("org.example" % "example-plugin" % "1.0")

lazy val plugins = project in file(".") dependsOn(file("../A"))
// http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin
sbtPlugin := true

name := "example-plugin"

organization := "org.example"

version := "1.0"
MyPlugin.newSettings
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(...)
}
目录
A
中的两个文件--
build.sbt
MyPlugin.scala
构成了插件项目

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

B/build.sbt

lazy val A, B = project
addSbtPlugin("org.example" % "example-plugin" % "1.0")

lazy val plugins = project in file(".") dependsOn(file("../A"))
// http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin
sbtPlugin := true

name := "example-plugin"

organization := "org.example"

version := "1.0"
MyPlugin.newSettings
这就是你在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]          ^
正如您可能已经注意到的,
newTask
(来自项目
A
的插件)在(默认)根项目和项目
B
中可用,但在
A

中不可用,这不能像我希望的那样完成,因为子项目不能有根项目没有的SBT插件。另一方面,它包含多个备选方案,无疑对将来遇到此问题的任何人都有用

编辑:嗯,最后提到的备选方案(sbt脚本等)很难使用。我的最终解决方案是在repo中有一个单独的项目(不是子项目),通过它的常春藤坐标依赖于原始项目,并使用bash发布第一个项目,进入第二个项目并运行其测试

sbt publishLocal; cd test; sbt test; cd ..

我一直认为SBT这样做的目的是为了避免做这种bash体操,但绝望的时候需要采取绝望的措施……

你的
subB/project/build.SBT
看起来怎么样?您还应该看到。在我看来,这个问题没有帮助,因为它只涉及如何将源插件(如
subA
)添加到根项目的构建中,而不是添加到子项目(如
subB
)中。我需要能够将
subA
添加到
subB
s build而不是root,因为如果root依赖于
subA
并且
subA
是由root构建的,我有这种循环依赖性,什么都不管用。只是一个简单的建议:试着把东西放在
subB/build.sbt
中,而不是像你描述的
subB/project/build.sbt
中。问题是我放在
subB/project/build.sbt
中的东西是一个sbt插件(或至少参考
subA
,这是一个SBT插件).AFAICT将其放入
subB/build.sbt
不会做正确的事情,因为它需要插件的结果在
subB/build.sbt
中可见。你能澄清一下为什么你需要它们都是同一父项目的子项目吗?A是否依赖于直接在P或另一个子项目中的东西?它需要是一个插件de然而,依赖性不是一个正常的依赖性,所以你的过程(我认为)描述不起作用。看起来很有希望,但仍然不能解决让
B
依赖
A
作为插件而不依赖
P
的问题。另一个awnser可能会解决如何减轻子项目之间的依赖性/聚合性的问题。+1获得一个我未能给出的令人惊讶的详细答案了解大多数(但这是因为我的sbt学习曲线-whe