如何在库中支持多个 Scala 版本

2023-12-21

我有一个相当正常的斯卡拉项目 https://github.com/FasterXML/jackson-module-scala/目前正在使用 Maven 构建。我想同时支持 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 构建帮助器插件来选择特定于版本的源代码树。在发布之前,这种方法一直运行良好。

    • 使用分类器来限定版本效果不佳,因为源 jar 还需要自定义分类器(“source-2.9.2”等),并且大多数 IDE 工具不知道如何找到它们。

    • 我尝试使用 Maven 属性将 SBT 样式 _${scala.version} 后缀添加到工件名称中,但 Maven 不喜欢工件名称中的属性。

  • SBT。一旦你能理解它,它就会很好地工作(尽管有大量的文档,但这不是一个小任务)。缺点是似乎没有相当于 Maven 阴影插件。我看过:

    • 混淆者。该插件未针对 SBT 0.12.x 进行更新,并且不会从源代码构建,因为它依赖于另一个已更改 groupId 的 SBT 插件,并且旧名称下没有 0.12.x 版本。我还没有弄清楚如何指示 SBT 忽略/替换插件依赖项。

    • 一罐。这使用自定义类加载来从嵌入的 jar 中运行主类,这不是期望的结果;我希望我的项目的类文件与我的阴影依赖项中的类文件(可能已重命名)一起位于 jar 中。

    • SBT 组装插件。这在一定程度上可以发挥作用,但 POM 文件似乎包含我试图隐藏的依赖项,这对我的最终用户没有帮助。

我承认可能没有一个解决方案可以满足我对 Scala 的需求,并且/或者我可能需要编写自己的 Maven 或 Scala 插件来实现目标。但如果可以的话,我想找到一个现有的解决方案。

Update

我快要接受@Jon-Ander 的优秀了answer https://stackoverflow.com/a/13880582/9700但对我来说还有一件突出的事情,那就是统一的发布流程。我目前的状态build.sbt 位于 GitHub 上 https://github.com/FasterXML/jackson-module-scala/blob/3c8da09fc40fb5419205295ccf3e63e3ba42e66e/build.sbt。 (我将在稍后的答案中为后代复制它)。

sbt-release 插件不支持多版本构建(即+ release的行为并不像人们希望的那样),这在某种程度上是有道理的,因为发布标记的过程实际上并不需要跨版本发生。但我希望该过程的两个部分是多版本的:测试和发布。

我希望发生的是类似于两阶段 maven-release-plugin 过程的事情。第一阶段将完成更新 Git 和运行测试的管理工作,在本例中这意味着运行+ test这样所有版本都经过测试、标记、更新到快照,然后将结果推送到上游。

第二阶段将检查标记版本并+ publish,这将重新运行测试并将标记的版本推送到 Sonatype 存储库。

我怀疑我可以写releaseProcess执行这些操作的值,但我不确定是否可以支持多个releaseProcess我的价值观build.sbt。它可能可以与一些额外的范围一起使用,但 SBT 的那部分对我来说仍然很奇怪。

我目前所做的是改变releaseProcess不发布。然后我必须手动检查标记版本并运行+ publish事实上,这接近我想要的,但确实有所妥协,特别是因为测试仅在发布过程中的当前 scala 版本上运行。我可以接受一个不像 Maven 插件那样是两阶段的流程,但确实实现了多版本测试和发布。

任何可以帮助我度过最后一英里的额外反馈将不胜感激。


其中大部分在单个源代码树中的 sbt 中得到了很好的支持

通常不需要版本特定的源目录。 Scala 程序往往是源兼容的——事实上经常如此 交叉建筑(http://www.scala-sbt.org/release/docs/Detailed-Topics/Cross-Build http://www.scala-sbt.org/release/docs/Detailed-Topics/Cross-Build) 在 sbt 方面拥有一流的支持。

如果您确实需要特定于版本的代码,您可以添加额外的源文件夹。 将其放入 build.sbt 文件中,除了常规的“src/main/scala”之外,还会在交叉构建时添加“src/main/scala-[scalaVersion]”作为每个版本的源目录。 (还有一个插件可用于在版本之间生成垫片,但我还没有尝试过 -https://github.com/sbt/sbt-scalashim https://github.com/sbt/sbt-scalashim)

unmanagedSourceDirectories in Compile <+= (sourceDirectory in Compile, scalaVersion){ (s,v) => s / ("scala-"+v) }

版本特定的源 jar - 请参阅交叉构建,开箱即用

一体化部署——https://github.com/sbt/sbt-release https://github.com/sbt/sbt-release(也有很棒的 git 集成)

Maven 最终用户 -http://www.scala-sbt.org/release/docs/Detailed-Topics/Publishing.html http://www.scala-sbt.org/release/docs/Detailed-Topics/Publishing.html

阴影 - 我用过这个https://github.com/sbt/sbt-assemble https://github.com/sbt/sbt-assembly这对我的需求来说效果很好。 您的程序集插件问题可以通过重写生成的 pom.xml 来解决。 这是一个删除 joda-time 的示例。

pomPostProcess := {
    import xml.transform._
    new RuleTransformer(new RewriteRule{
        override def transform(node:xml.Node) = {
            if((node \ "groupId").text == "joda-time") xml.NodeSeq.Empty else node
        }
    })
}

完整的build.sbt供参考

scalaVersion := "2.9.2"

crossScalaVersions := Seq("2.9.2", "2.10.0-RC5")

unmanagedSourceDirectories in Compile <+= (sourceDirectory in Compile, scalaVersion){ (s,v) => s / ("scala-"+v) }

libraryDependencies += "joda-time" % "joda-time" % "1.6.2"

libraryDependencies += "org.mindrot" % "jbcrypt" % "0.3m"

pomPostProcess := {
    import xml.transform._
    new RuleTransformer(new RewriteRule{
        override def transform(node:xml.Node) = {
            if((node \ "groupId").text == "joda-time") xml.NodeSeq.Empty else node
        }
    })
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在库中支持多个 Scala 版本 的相关文章

随机推荐

  • 访问修饰符有什么用

    编程语言中需要使用访问修饰符吗 如果我们选择所有成员和方法作为私有 那么输出会是什么 See 封装 http en wikipedia org wiki Encapsulation object oriented programming 维
  • java 8 嵌套流

    假设您有这样的结构类 public class Review private Integer idReview private String description private ArrayList
  • Apache 2.4 with mod_wsgi: 403 Forbidden, 无权访问此服务器上的 /calbase

    所以我尝试使用 apache 2 4 和 mod wsgi 和 pythong 3 4 在 Windows 服务器上部署我的 django 项目 在我配置 httpd conf 并尝试启动安装了 mod wsgi 的 apache 之前 它
  • Java 进程中的 Sudo

    我正在开发一个终端应用程序 它允许人们从 Swing GUI 执行 bash 命令 尝试使用 sudo 执行命令时遇到以下问题 sudo cd Users myname Desktop sudo 不存在 tty 且未指定 Askpass 程
  • 为什么在 Spark 数据集上调用缓存需要很长时间?

    我正在加载大型数据集 然后缓存它们以供我的代码中参考 代码看起来像这样 val conversations sqlContext read format com databricks spark redshift option url jd
  • 在 Flask 中获取数据 JSON

    即使遵循这里和那里的许多示例 我也无法在 POST 方法中让我的 API 工作 这是关于它的代码 from flask import Flask jsonify request app route api v1 lists methods
  • RenderPartial 如何确定在哪里可以找到视图?

    好的 谷歌搜索可能会失败 我记得不久前读过这篇文章 但找不到它 我在不同的目录中有一个视图和一个部分视图 我认为 Html RenderPartial partial view name RenderPartial 如何确定要查看的位置 这
  • iBatis 使用 resultMap 和parameterMap 的集合

    我想在 iBatis 查询中传递一组字符串作为参数映射 并返回结果集的字符串集合 这可能吗 示例查询 SELECT FROM some table t WHERE t some column IN values UPDATE some ta
  • 管道在 git for windows 的 bash 中返回空字符串

    编辑 更新到适用于 Windows gt 2 9 0 windows1 的 Git 后问题已解决 免责声明 有些评论提到了这个问题背后的完整 故事 但我决定缩短它 因为它太长而且难以理解 我向您展示尽可能简洁的失败示例 对于那些有兴趣了解问
  • 如何在rmarkdown中使用for循环?

    考虑这个简单的例子 title Untitled output ioslides presentation r setup include FALSE knitr opts chunk set echo FALSE Slide with R
  • 使用 TOMCAT 将大 JSON 数据转为 java RESTful 服务

    我有一个大的 JSON 数据 有没有什么捷径可以使其成为 RESTful 服务 但我需要一个带有 apache TOMCAT 的 java 源代码 有什么捷径吗 也许您需要制作 Restful Web 服务来实现这一点 以 JSON 格式返
  • has_and_belongs_to_many,避免连接表中的重复

    我有一组非常简单的 HABTM 模型 class Tag lt ActiveRecord Base has and belongs to many posts end class Post lt ActiveRecord Base has
  • Java UDP 套接字 - 数据留在服务器端

    我正在使用 UDP 套接字在 Java 中实现一个非常基本的服务器 客户端模型 但我遇到了一个非常奇怪的问题 我想做的就是让用户 客户端 向服务器发送一条消息 然后服务器将其打印出来 我有一个例子 但我遗漏了一些东西 因为我有以下问题 如果
  • EF4.1(代码优先)-如何指定复合关系

    在 Linq to SQL 中 我可以指定一个不必依赖于数据库中现有的外键和 pks 的关系 这对于创建如下所示的复合关系很有用 public class Equipment CableNormalised Association This
  • FileSystemWatcher 状态 未启动

    我正在尝试注册在目录中创建或更改文件时的事件 当我尝试注册事件时 状态保持 未开始 并且事件不起作用 function checkFilestatus Param k try IO File OpenRead k Close Copy It
  • 相当于 git verify-pack -v |排序|尾巴

    In the Git 书籍中有关维护和数据恢复的部分 http git scm com book en v2 Git Internals Maintenance and Data Recovery 有一个名为 删除对象 的小节 斯科特写道
  • 主题不适用于按钮

    我开始玩主题 我能够创建 CSS 并将 CSS 关联到各种表格元素 工作正常 现在我尝试用按钮做同样的事情 但这似乎不起作用 如果我将样式类应用于按钮 那么它就可以工作
  • Groovy 中的 Jenkins 阶段是什么?

    我试图弄清楚 Groovy 语法中的阶段是什么 该语法是什么 stage stage 1 statement 1 statement 2 statement n stage stage 2 statement 1 statement 2 s
  • 尝试升级到 Swift 1.2 时出现令人困惑的编译错误

    我已经能够更新 XCode 6 3 和 Swift 1 2 的代码 没有太大问题 直到我尝试修复 UIHandler 中覆盖的触摸输入功能 我将所有四个触摸功能的签名更新为以下内容 override func touchesBegan to
  • 如何在库中支持多个 Scala 版本

    我有一个相当正常的斯卡拉项目 https github com FasterXML jackson module scala 目前正在使用 Maven 构建 我想同时支持 Scala 2 9 x 和即将推出的 2 10 后者不兼容二进制或源