sbt multimodule project

0

Hej,

Chciałbym zrobić sobie przykładowy projekt wielomodułowy w sbt. Zależności formowały by się w diament.

            common
         /         \
        /           \
       /             \
    module_a     module_b
       \              /
        \            /
         \          /
            parent
 

Ułożenie folderów jest płaskie, tj, mam główny folder projektu z build.sbt parenta i 3 projekty per moduł. Chciałbym żeby po odpaleniu głównego pliku budowały się wszystkie moduły. Natomiast po odpaleniu buildu z pojedynczego modułu, tylko te które są od niego zależne.
Czyli zależności kształtują się tak:
common -> module a
common -> module b
[module a, module b] -> parent

Niestety, gdy w module a chcę się odwołać do commona, to dostaję błąd:
[error] java.lang.AssertionError: assertion failed: Directory C:\Users\Krzysiek\Desktop\multimodule_sbt\common is not contained in build root C:\Users\Krzysiek\Desktop\multimodule_sbt\module_a

Mógłbym ustawić wszystko w parencie, ale wtedy nie mógłbym kompilować pojedynczych modułów i starciłbym trochę na elastyczności.

Czy znacie może rozwiązanie tego problemu?

To co wymodziłem (tylko moduł a)
https://bitbucket.org/krzysiek050/sbtmultimoduleexample.git

Wołam ludzi którzy wypowiadali się o scali, ale to nie jest wyłączność. Jeżeli znasz odpowiedź, a nie jesteś wymieniony, to i tak proszę Cię o pomoc :)
@Wibowit @Krolik @Koziołek

2

Zrób normalny build w pliku Build.scala zamiast w plikach sbt.
Ja to widzę tak:
Deklarujesz moduł commonsów, deklarujesz moduł A (.dependsOn(commons), to samo z modułem B
i w root dajesz .aggregate(commons, moduleA, moduleB)

lazy val root: Project = Project(
    "root",
    file("."),
    settings = buildSettings 
  ).aggregate(moduleA, moduleB)

  lazy val moduleA: Project = Project(
    "moduleA",
    file("moduleA"),
    settings = buildSettings 
  ).dependsOn(commons)

 lazy val moduleB: Project = Project(
    "moduleB",
    file("moduleB"),
    settings = buildSettings 
  ).dependsOn(commons)


  lazy val commons = Project(
    "commons",
    file("commons"),
    settings = buildSettings 
  )

1

Ja w swoim projekcie chyba trochę przekombinowałem. Chciałem mieć możliwość odpalenia testów z wszystkich modułów oraz szukania obiektów z metodą main z wszystkich modułów i skończyłem z czymś takim: https://github.com/tarsa/SortAlgoBox/blob/e3aaf1bb6b894e571c8be0b1bf2ac888c12a006d/project/MainBuild.scala
Mimo wszystko możesz się powzorować.

0

To co proponujecie zadziała, ale chodzi mi właśnie o to, żeby odseparować buildy poszczególnych modułów. Czyli zmieniajac coś w module_a, zmienić tylko jego build, a główny zostawić w spokoju. Jeżeli zrobię płaską strukturę i odwołam się z głównego builda, tak jak sugerujecie, to stracę tą możliwość.

Zrób normalny build w pliku Build.scala zamiast w plikach sbt.

Oboje przedstawiliście swój build w pliku .scala. Ale w oficjalnym tutorialu do sbt zalecają własnie pliki sbt. We wcześniejszych wersjach nie było innej możliwości zdefiniowania wielomodułowych projektów oprócz buildu w pliku .scala, ale teraz jest inaczej. Czy to są stare przyzwyczajenia, czy jednak nadal ta forma ma jakieś zalety na plikiem sbt?

1 użytkowników online, w tym zalogowanych: 0, gości: 1