Как установить зависимости по умолчанию для всех подпроектов в SBT?

Попытка понять, как настроить подпроекты SBT. Как правильно установить зависимости по умолчанию для всех моих подпроектов?

Я попробовал это, но мои подпроекты не получали каких-либо зависимостей (они загрузились нормально).

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

Затем, основываясь на этом, я попробовал следующее. Это сработало, но это не то, что я ожидал сделать. Не проще ли было установить зависимости по умолчанию для всех подпроектов?

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

Изменить: Следует отметить, что есть лучший способ использовать Akka, но просто иллюстрировал мою точку зрения.

3 ответа

Решение

Используйте наследование и миксины:

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

}

Обычное решение - поместить зависимости в класс для каждого подпроекта, как вы это делали с Proj-классом. Обычно вам нужен один класс для каждого подпроекта, так как они часто имеют уникальные зависимости.

Если вы ленивы, вы можете объявить класс с зависимостями в строке:

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)

В приведенном выше примере (для продукта х) xY модуль зависит от xBase модуль.

Объект Dependencies позволяет легко повторно использовать зависимости в модулях.

С тех пор многое изменилось, и с sbt 0.13.x теперь возможно "установить зависимости по умолчанию для всех моих подпроектов", используя project/RootBuild.scala в корневом проекте, который aggregate s другие подпроекты (которым они затем делегируют установку разрешения) следующим образом:

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

С resolvers set, подпроекты тоже будут установлены.

[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 Для корневого проекта это выглядит следующим образом:

lazy val root = project in file(".") aggregate (a, b)

lazy val a = project dependsOn b

lazy val b = project

Обратитесь к официальной документации sbt по поводу определения сборки.scala.

Однако существует другой (лучший?) Способ определения общей конфигурации с областью действия ThisBuild.

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/"

С выше RootBuild.scala построить определение и build.sbt где я использовал in ThisBuild для настройки параметров для всей сборки, конфигурация сборки закончилась двумя resolvers по умолчанию в настройке мультипроекта.

[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/)
Другие вопросы по тегам