如何编辑sbt执行publishLocal/publish时生成的ivy.xml文件
sbt 自定义修改publishLocal生成的ivy.xml方案
即使配置ThisBuild / publishMavenStyle := true,sbt执行publishLocal时仍会同步生成ivy.xml与pom文件:publish操作不会把ivy.xml上传到远程仓库所以无影响,但其他sbt项目依赖本地发布的快照版本时,会优先读取ivy.xml而非pom文件。针对已经通过ThisBuild / pomPostProcess := ???实现pom自定义编辑、需要同等能力修改ivy.xml的需求,可直接通过以下无插件方案实现:
- 核心实现原理
sbt没有提供命名对标pomPostProcess的ivy文件处理钩子,但负责生成ivy.xml对应XML结构的内置任务makeIvyXml是可自定义改写的,处理逻辑和pomPostProcess完全一致,直接操作XML节点即可。 - 具体实现代码
直接在项目的build.sbt中追加如下配置,替换其中的节点修改逻辑为实际业务规则即可:
ThisBuild / makeIvyXml := { val originalIvyNode = (ThisBuild / makeIvyXml).value // 此处编写自定义XML修改逻辑,和pomPostProcess的写法完全通用 originalIvyNode match { case root @ <ivy-module>{children @ _*}</ivy-module> => <ivy-module version={root \@ "version"}> { children.map { // 示例:按需替换、删除、新增节点,以下为示例逻辑可直接删除替换 case <dependencies>{deps @ _*}</dependencies> => <dependencies> { deps.filterNot(dep => (dep \@ "org") == "com.example" && (dep \@ "name") == "unwanted-dep") } </dependencies> case restNode => restNode } } </ivy-module> case unchanged => unchanged } }
- 补充说明
- 该方案适配所有sbt 1.x正式版本,不需要引入第三方插件,属于sbt原生任务链路支持的改写方式,不存在版本兼容问题
- 如果需要做字符串级别的特殊替换(比如修正XML转义问题、写入非标准标注),可以挂钩
deliverLocal任务,在任务执行完成后拿到落盘的ivy.xml文件路径,读取内容修改后再覆盖写回即可;优先推荐XML节点操作方式,避免手动改字符串导致的文件格式损坏 - 配置完成后执行
publishLocal,写入本地ivy仓库的ivy.xml就是修改后的版本,其他依赖该本地快照的sbt项目会直接读取到修改后的配置
内容的提问来源于stack exchange,提问作者Keith Alcock
相关产品推荐
相关产品推荐

