开发者

How to set default dependencies for all subprojects in SBT?

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.


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 aggregates 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/)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜