2010-12-02 10 views
10

Tratando de entender cómo configurar SBT subprojects. ¿Cuál es la forma correcta de establecer dependencias predeterminadas para todos mis subproyectos?¿Cómo se configuran las dependencias predeterminadas para todos los subproyectos en SBT?

Intenté esto, pero mis subproyectos no recogían ninguna de las dependencias (se descargaron bien).

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

Luego, basado en this intenté lo siguiente. Funcionó, pero no es lo que esperaba tener que hacer. ¿No hay algo más simple para establecer dependencias por defecto para todos los subproyectos?

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

Editar: debería indicar que hay un better way utilizar Akka, pero fue simplemente ilustra mi punto.

Respuesta

15

Uso herencia y 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" 
    }  

} 
+0

Diz iz nice. Me gusta dat rasit! –

+2

¿Estás bien, amigo?;) –

1

es habitual la solución para poner las dependencias en una clase para cada sub proyecto, al igual que lo hizo con la clase Proy. Por lo general, necesita una clase por subproyecto, ya que a menudo tienen dependencias únicas.

Si usted es perezoso, se puede declarar la clase con las dependencias en línea:

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) 

En el ejemplo anterior (para el producto x), el módulo xY depende del módulo de xBase.

El objeto Dependencias facilita la reutilización de las dependencias en los módulos.

1

Muchas cosas han cambiado desde entonces, y con 0.13.x SBT es posible ahora "para establecer dependencias predeterminadas para todos mis proyectos sub" usando project/RootBuild.scala en el proyecto raíz que aggregate s los otros sub-proyectos (que luego delegar el establecimiento resolución) de la siguiente manera:

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

con el conjunto resolvers, los sub-proyectos tendrán que establece, también.

[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 para el proyecto de la raíz es el siguiente:

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

lazy val a = project dependsOn b 

lazy val b = project 

consultar la documentación oficial del SBT sobre .scala Build Definition.

Sin embargo, hay otra (¿mejor?) Forma de definir una configuración común con el alcance 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/" 

Con la definición RootBuild.scala acumulación arriba y build.sbt donde solía in ThisBuild que alcance la configuración de todo el diseño, la configuración de generación terminó con dos resolvers siendo por defecto en la configuración multi-proyecto.

[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/) 
+2

Esto no tiene nada que ver con la agregación, sino con la definición de configuraciones en el nivel de compilación, que los proyectos luego delegan. En general, lo mejor es declarar la configuración de cada proyecto utilizando los mecanismos normales de reutilización de Scala. –

+0

@MarkHarrah, acabas de plantear un punto válido que me hizo cambiar la respuesta para incluir 'ThisBuild'. ¿Cómo se ve esto ahora? –

+1

Solo use los mecanismos de reutilización estándar de Scala. Por ejemplo, defina una secuencia de configuraciones comunes en un val y añádalas a cada proyecto. Menos conceptos para aprender de esa manera. –

Cuestiones relacionadas