2015-06-19 2 views
8

Я хотел бы изобрести систему до динамически обнаруживать подпроекты и автоматически сводить их в мой проект. Или, по крайней мере, настроить это как-то.sbt: динамическая агрегация подпроекта

Для этого я планирую иметь либо папку «modules», либо файл конфигурации, содержащий пути к модулям.

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

В настоящее время я строю в рамках игры с файлом build.sbt. Мне нужно будет добавить петлю следующим образом:

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

Есть ли способ сделать это?

EDIT 3: Код здесь почти работает:

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:_*) 
} 

Редактировать 4: решение

знакомства Дейла Wijnand в ниже.

Об ошибке: RuntimeException: No project 'myModule' in 'file:/Users/me/mysite/modules/myModule'. Я исправил это с помощью раствора из https://stackoverflow.com/a/28820578

+0

Каков вывод 'println (« Найденный модуль »+ folder.getName)'? – Peanut

+0

это «Найден модуль foo» (папка моего модуля называется «foo»). Кажется, что r.depends (модуль) терпит неудачу. Это может быть не объект проекта. По какой-то причине. – Emmanuel

ответ

2

Здесь:

проект/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 
} 

Обратите внимание, убедитесь, что модуль каталоги не содержат build.sbt файлы, определяющие их как проекты, как это вызовет путаницу RuntimeException: No project 'x' in 'file:/x' типа исключение, см. Can't use sbt 0.13.7 with Play subprojects

+0

Это наиболее полное решение. Но я все равно получаю ту же ошибку: RuntimeException: проект 'myModule' в файле:/Users/me/mysite/modules/myModule. Любая идея, почему это было бы? – Emmanuel

+0

Примечание: сам подпроект может быть скомпилирован отлично. – Emmanuel

+0

У меня это есть! Решение находится здесь: http://stackoverflow.com/a/28820578 В основном определение корня проекта дублируется в основных сборках и подпроектах. Решение состоит в том, чтобы удалить определение корневого проекта в build.sbt для подпроектов. // lazy val root = ... – Emmanuel

0

Вы можете попробовать что-то вроде этого:

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 
} 

Примечание: Вдохновленный ответ Дейла, но мне пришлось удалить «CommonSettings», в противном случае он не будет работать для меня ,

+0

Я пробовал что-то подобное. Но root = root.dependsOn() не работает; что val является неизменным. Я получаю ошибку «переназначение в val». Я новичок в Scala, поэтому, пожалуйста, держите меня за руку. – Emmanuel

+0

Решение состоит в том, чтобы сделать корень «var» вместо «val». Теперь у меня что-то почти работает, но у меня другая проблема. Смотрите мой обновленный код выше. – Emmanuel

+0

Прошу прощения; Я потерялся в этом коде. Я не знаю, что такое «t» и «r». – Emmanuel

Смежные вопросы