【问题标题】:How can I use an sbt plugin as a dependency in a multi-project build?如何在多项目构建中使用 sbt 插件作为依赖项?
【发布时间】:2015-06-11 12:28:08
【问题描述】:

我有两个使用多项目构建的 sbt 插件项目。我想使用其中一个插件作为另一个插件的依赖项。我能够使用单个项目构建来实现这一点,但是一旦我转向多项目构建,我似乎无法让依赖项正确链接。


我的测试插件

build.sbt

lazy val commonSettings = Seq(
    organization := "com.example",
    name := "my-test-plugin",
    version := "0.1.0-SNAPSHOT",
    scalaVersion := "2.10.5"
)

// The contents of root are largely unimportant here
lazy val root = (project in file(".")).settings(commonSettings: _*)

lazy val plugin = (project in file("plugin"))
    .settings(commonSettings: _*)
    .settings(
        sbtPlugin := true
    )

my-test-plugin/plugin/src/main/scala/PluginTest.scala

package com.example.test

// Sample code I would like to access from another plugin
object PluginTest {
    def foo: Unit = println("test")
}

我的子插件

build.sbt

lazy val commonSettings = Seq(
    organization := "com.sample",
    name := "my-sub-plugin",
    version := "0.1.0-SNAPSHOT",
    scalaVersion := "2.10.5"
)

lazy val root = (project in file(".")).settings(commonSettings: _*)

lazy val plugin = (project in file("plugin"))
    .settings(commonSettings: _*)
    .settings(
        sbtPlugin := true,
        libraryDependencies += Defaults.sbtPluginExtra("com.example" % "my-test-plugin" % "0.1.0-SNAPSHOT", "0.13", "2.10")
    ).dependsOn(root)

my-sub-plugin/plugin/src/main/scala/SubPluginTest.scala

package com.sample.test

object SubPluginTest {
    def bar = com.example.test.PluginTest.foo
}

但是最后一个文件没有编译:

[error] /home/mike/code/sbt-tests/my-sub-plugin/plugin/src/main/scala/SubPluginTest.scala:4: object example is not a member of package com
[error]     def bar = com.example.test.PluginTest.foo
[error]                   ^

当我 publish-localplugin/publish-local 两个项目(而是只编译第二个)时,工件正确解析,但 SubPlugintest.scala 无法编译并出现上述错误,就好像不存在依赖项一样。但是,如果我删除 root 项目并将插件文件放在根目录中(没有惰性 val 或任何东西,只是一个平坦的 build.sbt 结构),它就可以工作。

我在这里错过了什么?

我认为这无关紧要,但我尝试了 0.13.5 和 0.13.8。我也徒劳地尝试在没有sbtPluginExtra 的情况下添加依赖项,并将它们也放入plugins.sbt 中(我认为这行不通,但是嘿)。

编辑:

依赖 jar 出现在本地并正确解析:

$ jar tf ~/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/jars/my-test-plugin.jar
META-INF/MANIFEST.MF
com/
com/example/
com/example/test/
com/example/test/PluginTest$.class
com/example/test/PluginTest.class

$ jar tf ~/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/jars/my-test-plugin_2.10.jar
META-INF/MANIFEST.MF
com/
com/example/
com/example/test/
com/example/test/DummyCode.class
com/example/test/DummyCode$.class

【问题讨论】:

  • 你确定你做了plugin/publishLocal吗?如果你这样做jar tf /path/to/my-test-plugin.jar会发生什么,类文件是否存在?
  • @sschaef 似乎发布正确。我为“父”插件做了publishLocalplugin/publishLocal。罐子与类/对象一起存在。我还将所有内容推送到一个小型 git 存储库(请参阅我的编辑)。
  • @m-z 不幸的是我无法复制它。我创建了一个要点,其中包含我如何更改您的 repo(来自当前的主 10c0547)的差异,以及我所做的事情的记录,以尝试确定我们正在做的不同的事情。你能看看吗? gist.github.com/dwijnand/f787a3327803e07acfe8
  • @DaleWijnand 我对要点发表了评论。基本上,如果我删除my-sub-plugin 中的root 依赖项,它似乎可以工作。但是它们都在那里,要么是缺少包的编译错误,要么是奇怪的二进制冲突(这很奇怪,因为具有两个依赖项的单个项目是可以的)。
  • @DaleWijnand 有没有机会恢复您在上面评论中提到的要点?现在是 404。

标签: scala sbt


【解决方案1】:

您没有为每个模块设置不同的name

我的测试插件

> ;show root/name ;show plugin/name
[info] my-test-plugin
[info] my-test-plugin

我的子插件

> ;show root/name ;show plugin/name
[info] my-sub-plugin
[info] my-sub-plugin

如您所见,在my-test-plugin 中发布有效:

> ;root/publishLocal ;plugin/publishLocal
[info] Wrote /Users/dnw/Desktop/sbt-tests/my-test-plugin/target/scala-2.10/my-test-plugin_2.10-0.1.0-SNAPSHOT.pom
[info] :: delivering :: com.example#my-test-plugin_2.10;0.1.0-SNAPSHOT :: 0.1.0-SNAPSHOT :: integration :: Sat Apr 11 09:16:15 BST 2015
[info]  delivering ivy file to /Users/dnw/Desktop/sbt-tests/my-test-plugin/target/scala-2.10/ivy-0.1.0-SNAPSHOT.xml
[info]  published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/poms/my-test-plugin_2.10.pom
[info]  published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/jars/my-test-plugin_2.10.jar
[info]  published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/srcs/my-test-plugin_2.10-sources.jar
[info]  published my-test-plugin_2.10 to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/docs/my-test-plugin_2.10-javadoc.jar
[info]  published ivy to /Users/dnw/.ivy2/local/com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/ivys/ivy.xml
[success] Total time: 0 s, completed 11-Apr-2015 09:16:15
[info] Wrote /Users/dnw/Desktop/sbt-tests/my-test-plugin/plugin/target/scala-2.10/sbt-0.13/my-test-plugin-0.1.0-SNAPSHOT.pom
[info] :: delivering :: com.example#my-test-plugin;0.1.0-SNAPSHOT :: 0.1.0-SNAPSHOT :: integration :: Sat Apr 11 09:16:15 BST 2015
[info]  delivering ivy file to /Users/dnw/Desktop/sbt-tests/my-test-plugin/plugin/target/scala-2.10/sbt-0.13/ivy-0.1.0-SNAPSHOT.xml
[info]  published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/poms/my-test-plugin.pom
[info]  published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/jars/my-test-plugin.jar
[info]  published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/srcs/my-test-plugin-sources.jar
[info]  published my-test-plugin to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/docs/my-test-plugin-javadoc.jar
[info]  published ivy to /Users/dnw/.ivy2/local/com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/ivys/ivy.xml
[success] Total time: 0 s, completed 11-Apr-2015 09:16:15

但请注意发布路径:

com.example/my-test-plugin_2.10/0.1.0-SNAPSHOT/jars/my-test-plugin_2.10.jar
com.example/my-test-plugin/scala_2.10/sbt_0.13/0.1.0-SNAPSHOT/jars/my-test-plugin.jar
  1. 一个名为 my-test-plugin 的非 sbt 插件为 Scala 2.10 交叉构建。
  2. 一个名为 my-test-plugin 的 sbt 插件,为 Scala 2.10 和 sbt 0.13 交叉构建。

这会在尝试解析my-sub-plugin 中的my-test-plugin 时产生影响:

[error] Modules were resolved with conflicting cross-version suffixes in {file:/Users/dnw/Desktop/sbt-tests/my-sub-plugin/}root:
[error]    com.example:my-test-plugin <none>, _2.10
java.lang.RuntimeException: Conflicting cross-version suffixes in: com.example:my-test-plugin
    at scala.sys.package$.error(package.scala:27)
    at sbt.ConflictWarning$.processCrossVersioned(ConflictWarning.scala:46)
    at sbt.ConflictWarning$.apply(ConflictWarning.scala:32)

尝试为每个模块指定不同的名称,它应该可以工作。

【讨论】:

  • 啊。我之前尝试过,但我猜是其他问题导致它失败,所以我错误地继续前进。感谢您的帮助。
  • 没问题。感谢您的回购,它帮助设置了所有要分析的部分。
猜你喜欢
  • 2017-08-19
  • 2016-05-28
  • 2015-09-24
  • 2014-04-28
  • 2016-09-22
  • 2014-02-18
  • 1970-01-01
  • 2014-08-05
  • 2011-12-16
相关资源
最近更新 更多