2015-06-19 11 views
8

Vorrei inventare un sistema su in modo dinamico per scoprire i sottoprogetti e aggregarli automaticamente nel mio progetto. O almeno configuralo in qualche modo.sbt: aggregazione dinamica del sottoprogetto

Per fare questo, ho intenzione di avere una cartella "moduli" o un file di configurazione opzionale contenente percorsi ai moduli.

In ogni caso avrei bisogno di ciclo attraverso le sottocartelle (o ciclo in un elenco di percorsi da un file di configurazione), e aggregati ogni sottoprogetto. Non so come farlo.

Attualmente sto costruendo nel framework Play con il file build.sbt. Avrei bisogno di aggiungere il ciclo in questo modo:

name := "mysite" 
version := "1.0" 
scalaVersion := "2.11.1" 
lazy val root = (project in file(".")).enablePlugins(PlayJava) 
//pseudocode: 
foreach(folder in the 'modules' folder) { 
    lazy val module = (project in file(folder)).enablePlugins(PlayJava) 
    root = root.dependsOn(module).aggregate(module) 
} 

C'è un modo per farlo?

EDIT 3: Il codice qui è quasi lavorando:

object MyBuild extends Build { 
    name := "mysite" 
    version := "1.0" 
    scalaVersion := "2.11.6" 

    var m = new File("modules") 
    var list = Seq[ProjectReference]() 
    var deps = Seq[ClasspathDependency]() 
    if (m.exists) { 
    val subs = m.listFiles.filter (_.isDirectory).foreach { folder => 
     var modulePath = new File("modules", folder.getName) 
     println("Found module " + modulePath) 
     lazy val module:ProjectRef = ProjectRef(modulePath,folder.getName) 
     lazy val dep:ClasspathDependency = ClasspathDependency(module, None) 
     list = list :+ module 
     deps = deps :+ dep 
    } 
    } 

    lazy val root = Project(id = "mysite", base = file(".")).enablePlugins(PlayJava).aggregate(list:_*).dependsOn(deps:_*) 
} 

Edit 4: La soluzione di

See Dale Wijnand di seguito.

Informazioni sull'errore: RuntimeException: No project 'myModule' in 'file:/Users/me/mysite/modules/myModule'. Ho risolto questo utilizzando la soluzione da https://stackoverflow.com/a/28820578

+0

Qual è l'output di 'println (" Modulo trovato "+ folder.getName)'? – Peanut

+0

è "Found module foo" (la mia cartella dei moduli è denominata "foo"). Sembra che r.depends (module) non riesca. Potrebbe non essere un oggetto Project. Per qualche ragione. – Emmanuel

risposta

2

Qui:

progetto/Build.scala

import sbt._ 
import sbt.Keys._ 

import play.sbt._ 
import play.sbt.Play.autoImport._ 

object Build extends Build { 
    val commonSettings: Seq[Setting[_]] = Seq(
    scalaVersion := "2.11.7" 
) 

    lazy val modules = (file("modules") * DirectoryFilter).get.map { dir => 
    Project(dir.getName, dir).enablePlugins(PlayJava).settings(commonSettings: _*) 
    } 

    lazy val root = (project in file(".")) 
    .enablePlugins(PlayJava) 
    .settings(
     name := "mysite", 
     version := "1.0" 
    ) 
    .settings(commonSettings: _*) 
    .dependsOn(modules map (m => m: ClasspathDependency): _*) 
    .aggregate(modules map (m => m: ProjectReference): _*) 

    override lazy val projects = root +: modules 
} 

nota, assicurarsi che le directory dei moduli non contengono anche build.sbt file li definiscono come progetti che causerà confusione RuntimeException: No project 'x' in 'file:/x' tipo eccezione, vedere Can't use sbt 0.13.7 with Play subprojects

+0

Questa è la soluzione più completa finora. Ma sto ancora ricevendo lo stesso errore: RuntimeException: nessun progetto 'myModule' in 'file:/Users/me/mysite/modules/myModule'. Qualche idea sul perché sarebbe? – Emmanuel

+0

Nota: il sottoprogetto stesso può essere compilato correttamente. – Emmanuel

+0

Ce l'ho! La soluzione è qui: http://stackoverflow.com/a/28820578 Fondamentalmente la definizione radice del progetto è duplicata nelle build principali di build e sotto-progetto. La soluzione è rimuovere la definizione del progetto root in build.sbt per i sottoprogetti. // lazy val root = ... – Emmanuel

0

Si può provare qualcosa di simile:

import sbt._ 
import sbt.Keys._ 

import play.sbt._ 
import play.sbt.Play.autoImport._ 

object Build extends Build { 

    lazy val modules = (file("modules") * DirectoryFilter).get.map { dir => 
    Project(dir.getName, dir).enablePlugins(PlayJava) 
    } 

    lazy val root = (project in file(".")) 
    .enablePlugins(PlayJava) 
    .settings(
     name := "mysite", 
     version := "1.0" 
    ) 
    .dependsOn(modules map (m => m: ClasspathDependency): _*) 
    .aggregate(modules map (m => m: ProjectReference): _*) 

    override lazy val projects = root +: modules 
} 

Nota: Ispirato dalla risposta di Dale, ma ho dovuto rimuovere il "commonSettings", altrimenti non avrebbe funzionato per me .

+0

Ho provato qualcosa di simile. Ma root = root.dependsOn() non funziona; quella val è immutabile. Ottengo un errore di "riassegnazione a val". Sono un principiante di Scala quindi ti prego tienimi la mano con questo. – Emmanuel

+0

La soluzione è rendere la radice "var" anziché "val". Ora ho qualcosa che funziona, ma ho un problema diverso. Vedi il mio codice aggiornato sopra. – Emmanuel

+0

Mi dispiace; Sono perso in questo codice. Non so cosa siano "t" e "r". – Emmanuel

Problemi correlati