我希望将SBT用于围绕具有数十个项目的单个Git存储库构建的构建。我希望从构建中获得以下可能性:
现在考虑到这些要求,构建的结构应该是什么?由于要求3,我不能在构建的根目录中使用单个build.sbt
,因为我不想将所有项目设置放在那里,因为它会很多文本,并且单个项目中的每个更改都将反映在顶层。
我还听说根项目和子项目的*.sbt
文件的使用容易出错,一般不推荐(Producing no artifact for root project with package under multi-project build in SBT或How can I use an sbt plugin as a dependency in a multi-project build?,{ {3}}等。我只尝试了在不同级别上使用*.sbt
文件的简单多项目构建,它只是起作用。考虑到上述要求,如果我采用多*.sbt
文件方法,我需要记住哪些陷阱?
答案 0 :(得分:4)
好的,因为到目前为止还没有人发布任何内容,我发现我发布了迄今为止我从SBT单声道存储库中学到的内容。
首先是一些事实:我们的SBT构建包括40多个项目,10个以上的共同项目(在其他项目依赖于它们的意义上),以及与单个产品相关的5组项目(每个项目中有5-7个项目)组)。在每个小组中,通常只有一个小组共同项目。
我们有以下构建结构:
build.sbt
。build.sbt
。project
目录中的几个本地SBT插件。让我们谈谈这些项目。
build.sbt
在此文件中,定义了常规构建结构。也就是说,我们在那里保持跨项目依赖。我们不使用标准commonSettings
方法,如:
val commonSettings = Seq(scalaVersion := "2.12.3", ...)
...
val proj1 = (project in file("p1")).settings(commonSettings)
val proj2 = (project in file("p2")).settings(commonSettings)
...
这对于一个新项目来说太过冗长而容易出错。相反,我们使用一个本地SBT项目,该项目自动应用于构建中的每个项目(稍后将详细介绍)。
build.sbt
在这些文件中,我们通常定义所有项目设置(非自动插件,库依赖项等)。我们不在这些文件中定义跨项目依赖项,因为这并不像预期的那样真正起作用。 SBT按特定顺序加载所有*.sbt
个文件,每个构建中的项目定义都会覆盖以前找到的文件。换句话说,如果您避免(重新)在每个项目*.sbt
文件中定义项目,那么事情就会很好。所有其他设置都可以保留在那里,以避免在主build.sbt
中出现过多的混乱。
我们使用技巧在<root_dir>/project/
目录中定义SBT自动插件,并使它们自动加载到构建中的所有项目。我们使用这些插件自动定义所有项目的设置和任务(适用于Scalastyle,scalafmt,Sonar,部署等)。我们还在那里保持常见设置(scalaVersion等)。我们在<root_dir>/project/
中保留的另一件事是常见的依赖版本(不是插件,只是纯*.scala
文件)。
将SBT用于单声道存储库似乎有效,并且具有某些优点和缺点。
优势:在产品之间重复使用代码非常容易。此外,Scalastyle,scalafmt等常见的SBT内容定义一次,所有新项目都免费获得。升级依赖版本在一个地方为所有项目完成,因此当有人升级版本时,他或她会立即为所有项目执行此操作,以便不同的团队从中受益。这需要团队之间的某些纪律,但到目前为止它对我们有用。
另一个优点是使用通用工具。我们有一个Gerrit + Jenkins持续集成,我们只有一个工作,例如提交前验证。新项目再次免费获得了很多这种机器。
缺点:一,构建加载时间。在前13名&#34; MacBook Pro它可以轻松持续30秒以上(这是从启动SBT到达SBT&#39命令提示符的时间)。如果你能保持SBT不断运转,这并不是那么糟糕。 Intellij刷新构建信息会更糟糕,它可能需要大约15 分钟。我不知道为什么它需要的时间比SBT要长得多,但就是这样。除非绝对必要,否则可以通过避免刷新Intellij来缓解,但这真的很痛苦。
另一个问题是,您无法将单个项目或项目组加载到Intellij IDEA中。您被迫加载整个单声道存储库的构建。如果那是可能的话,那么,我猜,Intellij的情况可能会更好。
另一个缺点是,不能为不同的项目使用不同版本的相同SBT插件。当一个项目由于某种原因无法升级到新的插件版本时,整个存储库必须等待。有时这很有用,也就是说,它可以加快维护工作,并迫使我们将项目保持在维护模式中。但有时对于遗留项目而言,这可能具有挑战性。
总而言之,我们在这种模式下工作了大约一年,我们打算在可预见的未来继续这样做。我们担心的是Intellij IDEA刷新时间长,而且随着我们在此版本中添加更多项目,情况会变得更糟。我们稍后可能会评估替代构建系统,以避免我们单独加载项目以帮助Intellij性能,但SBT似乎可以完成任务。