Search code examples
scalasbtreleaseivymulti-project

sbt, couple questions: dependsOn


I have some questions about SBT:

1) I'm wondering why there is an option to use 'dependOn' clause. I fully understand that it joins projects.

lazy val projectA = Project("A", file("a"))
lazy val projectB = Project("B", file("b")).dependsOn(projectA)

What i don't like in this code: you can't specify version of projectA in projectB. it always aggregates latest condition of projectA. Why to split your application to multiproject if every subproject is tightly coupled with each other?

There is an another option. We can publish subproject in binary repository with version and add it as dependency in settings.

Why not to use this code:

lazy val projectA = project("A", file("a"))
lazy val projectB = Project("B", file("b")).settings(libraryDependencies ++= Seq("groupOfA" %% "A" % "versionOfA"))

Of couse, you need to have binary repository for this. But it's not a problem, you can install nexus locally (it supports almost everything and free to use), or use oss.sonatype.org.

2) This question is related to the first question, i don't understand why there is 'publishLocal' task. As i know SBT uses Ivy2 repository, but when you publish your project to nexus or oss.sonatype.org you publish it to maven2 repo. And the problem occurs when sbt detects locally published and cached from maven. It throws errors. I think this is sbt bug (https://github.com/sbt/sbt/issues/2687). I don't use publishLocal anymore, i don't understand why not to have installed binary repository on your machine if you want to split your application into mulpiple components.


Solution

  • As you noted, libraryDependencies is strictly more powerful than dependsOn for multi-project management, at the cost of increased complexity.

    You don't even need to install a separate binary repository, your local repo is quite good enough to publish to with publishLocal.

    Which brings us to your next question, that is why use publishLocal when it publishes to Ivy by default? Two things: first, set up the local publish to publish in Maven style: http://www.scala-sbt.org/0.13/docs/Publishing.html#Modifying+the+generated+POM (publishMavenStyle := true).

    Second, regarding the problem when you have the same version locally published and cached from Maven Central. Short answer: don't do that. If you publish to Maven Central, you should be using local publishes for testing only, and should publishLocal only 'SNAPTSHOT' versions. You should be publishing only fixed version numbers to Maven Central. Then there's no conflict. It's how Maven was designed; version numbers should be immutable and 'SNAPSHOT's should be for testing only.