我目前正在使用 Maven 构建一个相当普通的Scala 项目。我想同时支持 Scala 2.9.x 和即将推出的 2.10,它们不兼容二进制或源代码。如有必要,我愿意接受转换为 SBT,但我遇到了一些挑战。
我对这个项目的要求是:
单源树(无分支)。我相信尝试为每个 Scala 版本支持多个并发的“主”分支将是错过分支之间错误修复的最快方法。
版本特定的源目录。由于 Scala 版本不兼容源代码,因此我需要能够为特定于版本的源代码指定辅助源目录。
特定于版本的源 jar。最终用户应该能够为他们的 Scala 版本下载正确的源 jar,以及正确的版本特定源,以进行 IDE 集成。
集成部署。我目前使用 Maven 发布插件将新版本部署到 Sonatype OSS 存储库,并希望有一个类似的简单发布工作流。
最终用户 Maven 支持。我的最终用户通常是 Maven 用户,因此准确反映依赖关系的功能性 POM 至关重要。
阴影罐支持。我需要能够生成一个包含我的依赖项子集的 JAR,并从已发布的 POM 中删除阴影依赖项。
我尝试过的事情:
Maven 配置文件。我创建了一组 Maven 配置文件来控制用于构建的 Scala 版本,使用 Maven build-helper 插件来选择版本特定的源代码树。在发布之前,这一直运行良好;
使用分类器来限定版本效果不好,因为源 jar 还需要自定义分类器('source-2.9.2' 等),并且大多数 IDE 工具不知道如何定位它们。
我尝试使用 Maven 属性将 SBT 样式的 _${scala.version} 后缀添加到工件名称,但 Maven 不喜欢工件名称中的属性。
SBT。一旦你可以理解它,它就会很好地工作(尽管有大量文档,但这不是一项小任务)。缺点是似乎没有与 Maven 阴影插件等效的插件。我看过:
前卫。该插件未针对 SBT 0.12.x 进行更新,并且不会从源代码构建,因为它依赖于另一个已更改 groupIds 的 SBT 插件,并且在旧名称下没有 0.12.x 版本。我还没有弄清楚如何指示 SBT 忽略/替换插件依赖项。
一个罐子。这使用自定义类加载从嵌入式 jar 中运行 Main 类,这不是预期的结果;我希望我的项目的类文件与我的阴影依赖项中的(可能重命名的)类文件一起放在 jar 中。
SBT 程序集插件。这可以在一定程度上起作用,但 POM 文件似乎包含我试图遮蔽的依赖项,这对我的最终用户没有帮助。
我接受可能没有解决方案可以满足我对 Scala 的要求,和/或我可能需要编写自己的 Maven 或 Scala 插件来实现目标。但如果可以的话,我想找到一个现有的解决方案。
更新
我接近接受@Jon-Ander 的出色回答,但对我来说仍然有一个出色的部分,那就是统一的发布过程。我的 build.sbt 的当前状态在 GitHub 上。(我将在稍后的答案中复制它以供后代使用)。
sbt-release 插件不支持多版本构建(即,+ release
行为不像人们所希望的那样),这是有道理的,因为发布标记的过程并不真正需要跨版本发生。但我希望这个过程的两个部分是多版本的:测试和发布。
我希望发生的事情类似于两阶段 maven-release-plugin 过程。第一阶段将执行更新 Git 和运行测试的管理工作,在这种情况下,这意味着运行+ test
以便测试所有版本、标记、更新到快照,然后将结果推送到上游。
第二阶段将签出标记版本和+ publish
,这将重新运行测试并将标记版本推送到 Sonatype 存储库。
我怀疑我可以编写releaseProcess
执行这些操作的值,但我不确定我是否可以releaseProcess
在我的build.sbt
. 它可能可以与一些额外的范围一起使用,但是 SBT 的那部分对我来说仍然是奇怪的 majick。
我目前所做的是更改releaseProcess
为不发布。然后我必须手动检查标记的版本并在+ publish
事后运行,这接近我想要的但确实妥协,特别是因为测试仅在发布过程中在当前的 scala 版本上运行。我可以接受一个不像 maven 插件那样的两阶段流程,但确实实现了多版本测试和发布。
任何可以让我完成最后一英里的额外反馈将不胜感激。