0

I have two sbt plugin projects that both use multi-project builds. I would like to use one of the plugins as a dependency for the other. I was able to get this working with single project builds, but once I move to the multi-project build, I can't seem to get the dependencies to link up correctly.


my-test-plugin

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

my-sub-plugin

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
}

But the last file doesn't compile:

[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]                   ^

When I publish-local and plugin/publish-local both projects (rather, just compile the second), the artifacts resolve correctly, but SubPlugintest.scala fails to compile with the above error, as if the dependency isn't there. However, if I remove the root projects and put the plugin files in root (without lazy vals or anything, just a flat build.sbt structure), it works.

What am I missing here?

I don't think it's relevant, but I tried 0.13.5 and 0.13.8. I've also fruitlessly tried adding the dependency without sbtPluginExtra, and putting them in plugins.sbt as well (I didn't think that would work, but hey).

Edit:

The dependency jars appear exist locally and resolve correctly:

$ 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
Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • Are you sure you did a `plugin/publishLocal`? What happens if you do `jar tf /path/to/my-test-plugin.jar`, do the classfiles exist? – kiritsuku Apr 07 '15 at 08:59
  • @sschaef It seems to be published correctly. I did both `publishLocal` and `plugin/publishLocal` for the "parent" plugin. The jars are there with the classes/objects. I've also pushed all of it to a small git repo (see my edit). – Michael Zajac Apr 07 '15 at 14:51
  • @m-z Unfortunately I can't reproduce it. I've created a gist with the diff of how I changed your repo (from current master 10c0547), as well as a transcript of what I did, in an attempt to try and nail down what we're doing differently. Can you have a look? https://gist.github.com/dwijnand/f787a3327803e07acfe8 – Dale Wijnand Apr 09 '15 at 22:33
  • @DaleWijnand I made a comment on the gist. Basically, if I remove the `root` dependencies in `my-sub-plugin`, it seems to work. But with them both there, it's either the compile error from the missing package, or a strange binary conflict (which is very odd, because a single project with both dependencies is ok). – Michael Zajac Apr 10 '15 at 15:35
  • @DaleWijnand any chance to restore the gist you've mentioned in the comment above? It's 404 now. – Haspemulator Jul 11 '16 at 13:11

1 Answers1

2

You're not setting a distinct name for each module:

my-test-plugin

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

my-sub-plugin

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

As you can see, publishing in my-test-plugin works:

> ;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

But note the publish paths:

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. A non-sbt-plugin called my-test-plugin cross-built for Scala 2.10.
  2. An sbt-plugin called my-test-plugin, cross-built for Scala 2.10 and sbt 0.13.

This has an impact when trying to resolve my-test-plugin in my-sub-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)

Try and specify different names for each module and it should work.

Dale Wijnand
  • 6,054
  • 5
  • 28
  • 55