Присвоить имя корневому проекту с сохранением агрегации по умолчанию

#sbt

#sbt

Вопрос:

У меня довольно большой проект sbt (около 30 подпроектов). Из того, что я выяснил, sbt будет использовать имя корневого каталога в качестве имени корневого проекта, если ни один из них не объявлен явно build.sbt . В зависимости от того, где извлекается проект, например, в среде CI, это имя может измениться. В настоящее время я использую sbt 1.2.8.

Моя проблема в том, что я хотел бы назначить корню проекта стабильное имя, чтобы я мог, например, запускать все тесты с использованием sbt root/test [0], используя агрегацию корневого проекта по умолчанию для всех подпроектов. Единственный способ, который я нашел до сих пор, чтобы присвоить имя корневому проекту, — это явное объявление проекта. Но это отключит агрегацию по умолчанию.

Есть ли способ присвоить корневому проекту имя, которое сохранит агрегацию по умолчанию для всех подпроектов? Или есть другой способ получить доступ к корневому проекту в командной строке, не полагаясь на его имя?

[0]: проект по умолчанию изменяется при build.sbt использовании onLoad in Global := (Command.process("project ...", _)) compose (onLoad in Global).value . Так что просто запустить sbt test не получится.

Ответ №1:

Вот потенциальное решение без необходимости явно ссылаться на корневой проект.

Учитывая следующую структуру проекта, состоящую из корневого проекта и подпроектов core и util

 build.sbt 
core      
project   
src       
target    
util
  

и следующее определение сборки в build.sbt

 lazy val util = (project in file("util"))
lazy val core = (project in file("core"))
onLoad in Global := { Command.process("project util", _: State) } compose (onLoad in Global).value
ThisBuild / libraryDependencies  = "org.scalatest" %% "scalatest" % "3.0.5" % Test
  

мы могли бы запускать тесты из всех проектов, находясь в любом конкретном подпроекте, определив пользовательскую задачу testAll , которая оценивает test с помощью inAnyProject фильтра области

 val testAll = taskKey[Unit]("Run tests in all projects whilst being in any particular sub-project")
ThisBuild / testAll := Def.taskDyn {
  (Test / test).all(ScopeFilter(inAnyProject))
}.value
  

Теперь выполнение sbt загрузит util подпроект по умолчанию, тем не менее testAll , должны выполняться все тесты из всех проектов:

 sbt:util> testAll
[info] RootSpec:
[info] The Root object
[info] - should say root hello
[info] UtilSpec:
[info] The Util object
[info] - should say util hello
[info] CoreSpec:
[info] The Core object
[info] - should say core hello
[info] Run completed in 349 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Run completed in 309 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Run completed in 403 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 1 s, completed 11-Apr-2019 16:29:26
sbt:util>
  

где RootSpec , CoreSpec , и UtilsSpec находятся в

 src/test/scala/example/RootSpec.scala
core/src/test/scala/example/CoreSpec.scala
util/src/test/scala/example/UtilSpec.scala