Как управлять несколькими взаимозависимыми модулями с SBT и IntelliJ IDEA?
Я разрабатываю несколько модулей с зависимостями между ними и хотел бы работать с ними все вместе в одном проекте IDEA. Я использую sbt-idea для создания проектов IDEA из определений сборки sbt, которые отлично подходят для отдельных проектов. Однако в случае с несколькими модулями все, что я пробовал до сих пор, не совсем работает:
Использовать sbt-idea для генерации IDEA файла .iml для каждого модуля независимо; затем создайте мастер-проект IDEA с нуля, добавьте к нему эти модули. Это делает источники модулей доступными для редактирования в одном окне, но зависимости между ними не отслеживаются (поэтому попытка перехода от некоторого источника в проекте foo к чему-то в строке приведет меня к импортированной библиотечной версии бара, а не к локальным источникам).
Используйте sbt многопроектные сборки (aka subprojects), где родительский проект Build.scala содержит такие вещи, как
lazy val foo = Project(id = "foo", base = file("foo"))
lazy val bar = Project(id = "bar", base = file("bar")) dependsOn(foo)
Это почти работает, поскольку в sbt-идее генерируется мастер-проект IDEA с зависимостями отслеживаемых подпроектов. Есть, однако, два оговорки:
- Кажется, это ограничение sbt, что подпроекты должны жить в подкаталогах главного проекта (т.е.
file("../foo")
не допускается). Это не совсем то, что я хочу (что, если модуль - например, "utils" или "commons" - используется в двух разных мастер-проектах?), Но я могу жить с ним.
- Один из моих подпроектов имеет свои собственные подпроекты; Я не уверен, правильно ли sbt справляется с этими вложенными проектами, но в любом случае они игнорируются sbt-idea. Очевидно, что мне нужно, чтобы вложенные подпроекты включались рекурсивно в главный проект.
Подводя итог: я хотел бы собрать модули, которые могут уже иметь подпроекты в один большой проект IDEA с отслеживаемыми зависимостями для удобного редактирования. Как мне это сделать? Спасибо!
Ответы
Ответ 1
Похоже, что ограничение sbt заключается в том, что подпроекты должны жить в подкаталогах главного проекта (т.е. файл ( "../foo" ) не допускается). Это не совсем то, что я хочу (что, если модуль - например, "utils" или "commons" package - используется в двух разных мастер-проектах?), Но я могу жить с ним.
С sbt 13.5 и intellij 13.x вы можете указать зависимость между проектами с относительным путем, используя Build.scala.
Скажем, у вас есть два проекта: основной проект commons и еще один проект foo, оба проживающие в общем каталоге code/
- создать Build.scala под кодом /foo/project/
-
поместите этот фрагмент кода. Build.scala
object ProjectDependencies {
val commons = RootProject(file("../commons"))
}
object ProjectBuild extends Build {
import ProjectDependencies._
lazy val root = Project(id = "foo", base = file(".")).dependsOn(commons)
}
-
Создайте проект IntelliJ через sbt sbt gen-idea
Ответ 2
Подход с многопроектной сборкой является правильным. У вас может быть вложенное дерево подпроектов произвольной длины, но вы не можете иметь модуль, принадлежащий нескольким родительским проектам. Это имеет смысл, и в Maven бывает то же самое.
Причина в том, что было бы сложно иметь один и тот же модуль в нескольких проектах и синхронизировать источники. Обычный рабочий процесс следующий:
- У вас есть проект, к которому принадлежит модуль, где вы изменяете источник модуля.
- Вы публикуете модуль в своем локальном репозитории
- В других проектах, где вам нужен модуль, вы объявляете его как libraryDependency
Если вы хотите загрузить модуль, который не относится к текущему проекту внутри Idea, это, однако, возможно, поскольку вы можете добавить это как внешний модуль в рабочую область:
- SBT-IDEA создает файлы .iml для вашего проекта и импортирует их в рабочей области
- Вы можете добавить other.iml других проектов в рабочую область
- Если вы изменяете внешние SBT-модули, которые вы вручную добавили в рабочую область, вы должны переиздать их, чтобы получить изменения visibile в "основном" проекте, который видит, что эти внешние модули являются "libraryDependency"