Trying to understand how to set up SBT subprojects. What is the correct way to set default dependencies for all my sub projects?
I tried this, but my sub projects weren't picking up any of the dependencies (they downloaded fine).
import sbt._
class MyProjects(info: ProjectInfo) extends DefaultProject(info)
{
val projA = project("projA", "ProjectA")
val projB = project("projB", "ProjectB")
val akkaRepo = "Akka maven2 repo" at "http://www.scalablesolutions.se/akka/repository/"
val multiverseRepo = "Multiverse maven2 repo" at "http://multiverse.googlecode.com/svn/maven-repository/releases/"
val guiceyFruitRepo = "GuiceyFruit Maven2 repo" at "http://guiceyfruit.googlecode.com/svn/repo/releases/"
val jBossRepo = "JBoss maven2 repo" at "https://repository.jboss.org/nexus/content/groups/public/"
val junit = "junit" % "junit" % "4.5" % "test"
val scalatest = "org.scalatest" % "scalatest" % "1.2" % "test"
val akka = "se.scalablesolutions.akka" % "akka-core_2.8.0" % "0.10"
}
Then, based on this I tried the following. It worked, but it's not what I was expecting to have to do. Isn't there a simpler was to set default dependencies for all subprojects?
import sbt._
class MyProjects(info: ProjectInfo) extends DefaultProject(info)
{
val projA = project("projA", "ProjectA", new Proj(_))
val projB = project("projB", "ProjectB", new Proj(_))
val akkaRepo = "Akka maven2 repo" at "http://www.scalablesolutions.se/akka/repository/"
val multiversRepo = "Multiverse maven2 repo" at "http://multiverse.googlecode.com/svn/maven-repository/releases/"
val guiceyFruitRepo = "GuiceyFruit Maven2 repo" at "http://guiceyfruit.googlecode.com/svn/repo/releases/"
val jBossRepo = "JBoss maven2 repo" at "https://repository.jboss.org/nexus/content/groups/public/"
class Proj(info:ProjectInfo) extends DefaultProject(info){
val junit = "junit" % "junit" % "4.5" % "test"
val scalatest = "org.scalatest" % "scalatest" % "1.2" % "test"
val akka = "se.scalablesolutions.akka" % "akka-core_2.8.0" % "0.10"
}
}
Edit: Should point out there is an better way to use Akka, but was just illustrating my point.
The libraryDependencies key Most of the time, you can simply list your dependencies in the setting libraryDependencies . It's also possible to write a Maven POM file or Ivy configuration file to externally configure your dependencies, and have sbt use those external configuration files.
This is part of SBT which play uses as a build tool. Specifically this is an import statement. The percent symbol % is a actually a method used to build dependencies. The double percent sign %% injects the current Scala version - this allows you to get the correct library for the version of scala you are running.
clean – delete all generated sources, compiled artifacts, intermediate products, and generally all build-produced files. reload – reload the build, to take into account changes to the sbt plugin and its transitive dependencies.
Use inheritance and mixins:
import sbt._
class ModularProject(info: ProjectInfo) extends DefaultProject(info){
lazy val childProject = project("projA", "ProjectA",
new DefaultProject(_)
with Repositories
with GlobalDependencies
with AkkaDependencies)
trait Repositories{
lazy val akkaRepo = "Akka maven2 repo" at
"http://www.scalablesolutions.se/akka/repository/"
lazy val multiversRepo = "Multiverse maven2 repo" at
"http://multiverse.googlecode.com/svn/maven-repository/releases/"
lazy val guiceyFruitRepo = "GuiceyFruit Maven2 repo" at
"http://guiceyfruit.googlecode.com/svn/repo/releases/"
lazy val jBossRepo = "JBoss maven2 repo" at
"https://repository.jboss.org/nexus/content/groups/public/"
}
trait GlobalDependencies{
lazy val junit = "junit" % "junit" % "4.5" % "test"
lazy val scalatest = "org.scalatest" % "scalatest" % "1.2" % "test"
}
trait AkkaDependencies{
lazy val akka = "se.scalablesolutions.akka" % "akka-core_2.8.0" % "0.10"
}
}
The normal solution is to put the dependencies in a class for each sub project, just like you did with the Proj-class. Usually you need one class per sub project, since they often have unique dependencies.
If you are lazy, you can declare the class with the dependencies in-line:
object Dependencies {
....
lazy val jodaTime = "joda-time" % "joda-time" % ...
lazy val scalaTime = "org.scala-tools" % "time" % ...
lazy val redis = "com.redis" % "redisclient" % ...
}
val xBase = project("x-base", "x-base", new DefaultProject(_) {
val jodaTime = Dependencies.jodaTime
val scalaTime = Dependencies.scalaTime
})
val xY = project("x-y", "x-y", new DefaultProject(_) { val redis = Dependencies.redis }, xBase)
In the example above (for the product x), the xY
module depends on the xBase
module.
The Dependencies object makes it easy to re-use the dependencies in the modules.
A lot has changed since, and with sbt 0.13.x it's now possible "to set default dependencies for all my sub projects" using project/RootBuild.scala
in the root project that aggregate
s the other subprojects (that they then delegate setting resolution to) as follows:
import sbt._
import Keys._
object RootBuild extends Build {
override lazy val settings = super.settings ++
Seq(resolvers += "Akka maven2 repo" at "http://www.scalablesolutions.se/akka/repository/")
}
With the resolvers
set, the subprojects will have it set, too.
[root]> resolvers
[info] a/*:resolvers
[info] List(Akka maven2 repo: http://www.scalablesolutions.se/akka/repository/)
[info] b/*:resolvers
[info] List(Akka maven2 repo: http://www.scalablesolutions.se/akka/repository/)
[info] root/*:resolvers
[info] List(Akka maven2 repo: http://www.scalablesolutions.se/akka/repository/)
build.sbt
for the root project is as follows:
lazy val root = project in file(".") aggregate (a, b)
lazy val a = project dependsOn b
lazy val b = project
Consult the official documentation of sbt about .scala Build Definition.
There's however another (better?) way to define a common configuration with the ThisBuild scope.
lazy val root = project in file(".") aggregate (a, b)
lazy val a = project dependsOn b
lazy val b = project
resolvers in ThisBuild += "JBoss maven2 repo" at "https://repository.jboss.org/nexus/content/groups/public/"
With the above RootBuild.scala
build definition and build.sbt
where I used in ThisBuild
to scope the setting for the entire build, the build configuration ended up with two resolvers
being default in the multi-project setup.
[root]> resolvers
[info] a/*:resolvers
[info] List(Akka maven2 repo: http://www.scalablesolutions.se/akka/repository/, JBoss maven2 repo: https://repository.jboss.org/nexus/content/groups/public/)
[info] b/*:resolvers
[info] List(Akka maven2 repo: http://www.scalablesolutions.se/akka/repository/, JBoss maven2 repo: https://repository.jboss.org/nexus/content/groups/public/)
[info] root/*:resolvers
[info] List(Akka maven2 repo: http://www.scalablesolutions.se/akka/repository/, JBoss maven2 repo: https://repository.jboss.org/nexus/content/groups/public/)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With