Разница в ключах: aggregate
не изменяет classpath и не устанавливает порядок между подпроектами. Рассмотрим следующую многопроектную сборку, состоящую из root
, core
и util
проектов:
├── build.sbt
├── core
│ ├── src
│ └── target
├── project
│ ├── build.properties
│ └── target
├── src
│ ├── main
│ └── test
├── target
│ ├── scala-2.13
│ └── streams
└── util
├── src
└── target
, где
core/src/main/scala/example/Core.scala:
package example
object Core {
def foo = "Core.foo"
}
util/src/main/scala/example/Util.scala
package example
object Util {
def foo =
"Util.foo" + Core.foo // note how we depend on source from another project here
}
src/main/scala/example/Hello.scala:
package example
object Hello extends App {
println(42)
}
Обратите внимание, что Util.foo
имеет путь к классамзависимость от Core.foo
от core
проекта. Если теперь мы попытаемся установить «зависимость», используя aggregate
, например,
lazy val root = (project in file(".")).aggregate(core, util)
lazy val util = (project in file("util"))
lazy val core = (project in file("core"))
, а затем выполнить compile
из root
project
root/compile
, он действительно попытается скомпилироватьвсе агрегированные проекты, однако, Util
потерпят неудачу при компиляции, потому что в них отсутствует зависимость пути к классам:
sbt:aggregate-vs-dependsOn> root/compile
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/core/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/util/target/scala-2.13/classes ...
[error] /Users/mario/IdeaProjects/aggregate-vs-dependson/util/src/main/scala/example/Util.scala:5:18: not found: value Core
[error] "Util.foo" + Core.foo // note how we depend on source from another project here
[error] ^
[error] one error found
[error] (util / Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed 13-Oct-2019 12:35:51
Другой способ увидеть это - выполнить show util/dependencyClasspath
, у которого должна отсутствовать зависимость Core
в выходных данных.
С другой стороны, dependsOn
изменит путь к классам и установит соответствующий порядок между проектами
lazy val root = (project in file(".")).aggregate(core, util)
lazy val util = (project in file("util")).dependsOn(core)
lazy val core = (project in file("core"))
Теперь root/compile
дает
sbt:aggregate-vs-dependsOn> root/compile
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/core/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/util/target/scala-2.13/classes ...
[success] Total time: 1 s, completed 13-Oct-2019 12:40:25
и show util/dependencyClasspath
показывает Core
на пути к классам:
sbt:aggregate-vs-dependsOn> show util/dependencyClasspath
[info] * Attributed(/Users/mario/IdeaProjects/aggregate-vs-dependson/core/target/scala-2.13/classes)
Наконец, aggregate
и dependsOn
не являются взаимоисключающими, на самом деле, это обычная практика использовать оба одновременно, часто aggregate
на root
всех подпроектах, чтобы помочь строительству, в то же время используя dependsOn
для изготовления определенных заказов для определенных подпроектов.