我认为这里最令人惊讶的是,这个功能是默认嵌入到Maven和Gradle中的,然而,在Ant/Ivy环境中却没有它存在的痕迹(你自己看看吧!)
我继承了一套使用Ant/Ivy作为构建/依赖系统的JVM组件。这些组件之间有很多依赖关系,这意味着对其中一个组件进行更改通常会产生连锁反应,要求您更新Ivy依赖关系并发布上游依赖关系的新版本。
维护这些项目的旧团队通过将快照jar发布到快照仓库来处理本地开发。我想用一个新的范例来取代这个范例,即快照从本地Ivy缓存发布到/解析。
我能够找到这个非常相似的问题,但发现答案有点缺乏细节(特别是一个完全拼接在一起的代码片段),部分原因是问题缺乏任何特定的代码示例。所以我在这里创建了一个SSCCE,并推送了2个GitHub repos:
- fizzbuzz-model,定义数据模型(一些无意义的pojo)的Java库
- fizzbuzz-app,一个简单的可执行jar, 依赖于
fizzbuzz-model
作为依赖项
我在这里寻找的是确切的(即实际代码,而不是伪代码)更改(可能是build.xml
, ivy.xml
或ivy-settings.xml
,或全部三个!),这将允许我使用以下本地开发/测试周期:
- 我对
fizzbuz-model
进行更改,并将更改本地发布到Ivy缓存,最好是作为快照版本(如1.0.0-SNAPSHOT
或类似) - 在
fizzbuzz-app
根目录中,我运行ant resolve
,它从缓存的快照 中提取这些更改现在我可以在
fizzbuzz-app
中使用这些更改虽然不是一个硬性要求,但我理想地希望而不是必须手动管理版本号。也就是说,当我在本地发布fizzbuzz-model
时,它用相同的版本(再次,像fizzbuz-model-1.0.0-SNAPSHOT.jar
一样)覆盖当前二进制文件,而不是将构建号增加到fizzbuzz-model-1.0.1-SNAPSHOT.jar
或类似的版本)。这样,在本地测试时,我所要做的就是发布fizzbuzz-model
并解析fizzbuzz-app
。
目前,当我发布fizzbuzz-model
,我得到以下错误:
/Users/myuser/workspace/fizzbuzz-model/build.xml:52: impossible to publish artifacts for hotmeatballsoup#fizzbuzz-model;1.0: java.io.IOException: missing artifact hotmeatballsoup#fizzbuzz-model;1.0.0-SNAPSHOT!fizzbuzz-model.pom
at org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:225)
at org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:172)
要在本地复制,克隆这两个项目并遵循它们的readme,从fizzbuzz-model
开始。谁能发现我在哪里走错了?请随意在这里回答和/或提交PR,无论您喜欢哪一种!和谢谢!
该错误指示ivy无法在本地构建工作区中找到要发布的文件。这不是快照的问题。
问题在这里:
<ivy:publish resolver="local" pubrevision="1.0.0-SNAPSHOT" >
<artifacts pattern="dist/[artifact]-[revision].[ext]" />
</ivy:publish>
您在模式中包含了一个"修订",但不幸的是,您在本地创建的jar与此命名约定不匹配。它既没有修改,又有一个错别字(应该是"fizzbuzz",而不是"fizzbuzz"):
<target name="dist" depends="clean,compile">
<jar jarfile="dist/fizzbuz-model.jar" basedir="build/main" />
</target>
我预测更多的问题,因为您正在尝试配置ivy来模拟Maven存储快照修订的方式。这需要Maven从未正式记录的额外元数据文件。我强烈建议将已发布的文件推送到Maven存储库管理器,以获得格式正确的SNAPSHOT存储。
下面是从ivy
向Maven仓库发布工件的示例- 使用IVY将SNAPSHOT工件发布到Maven -有什么魔力?
- https://support.sonatype.com/hc/en-us/articles/213465388-How-do-I-configure-my-Ivy-build-to-deploy-artifacts-to-Nexus-
<标题>建议解决方案
我已经按照请求提交了Pull请求,并提出了关于如何优先使用本地ivy存储库而不是快照版本的建议:
- fizzbuzz-model - (Pull request)
- fizzbuzz-app - (Pull request)
总而言之,模型在每次新构建时都会发布一个新的修订
<target name="publish" depends="clean,dist">
<!-- Determine build number from previously published revisions -->
<ivy:buildnumber resolver="local" organisation="${ivy.organisation}" module="${ivy.module}" revision="${target.release}"/>
<!-- Resolve ivy dependencies and create a Maven POM file -->
<ivy:deliver deliverpattern="dist/ivy.xml" pubrevision="${ivy.new.revision}" status="release"/>
<ivy:makepom ivyfile="dist/ivy.xml" pomfile="dist/fizzbuzz-model.pom" />
<!-- Publish the local repo. Defaults to ~/.ivy2/local -->
<ivy:publish resolver="local" pubrevision="${ivy.new.revision}" >
<artifacts pattern="dist/[artifact].[ext]" />
</ivy:publish>
</target>
它在应用代码中被用作动态依赖项,总是检索其他模块的最新发布版本。
<dependencies>
<dependency org="hotmeatballsoup" name="fizzbuzz-model" rev="latest.integration" conf="compile->default" />
</dependencies>
指出:
- 作为奖励,POM文件也正在生成,严格来说,除非您将工件推送到Maven仓库,否则它是不必要的。
<标题> 的背景像ivy这样的依赖管理器出现在Maven普遍流行之前(我记得Maven 1.0被普遍讨厌的时候),所以ivy没有完全实现Maven的工作流程也就不足为奇了。
Maven一直是一个非常固执己见的工具。令人困惑的是,它支持两种发布工件的方法。作为一个释放或快照。在我看来,这是在尝试使用Maven进行持续部署时造成最大摩擦的原因,在持续部署中,应该考虑发布所有的版本。但不可否认的是,Maven是分发所有基于Java的二进制文件的通用方式。Maven存储库可以作为一个集成点,支持多种构建技术,Maven、Gradle或ANT/Ivy。
因此,首先需要接受的是,快照开发工作流对于Maven来说是非常特殊的,并且据我所知,还没有被任何其他存储库格式复制。
在其他存储库中,一个版本的版本号总是唯一的。这适用于官方版本、候选版本或开发版本。另一方面,Maven快照永远不会完成。这是什么意思呢?如果我今天基于版本"1.0-SNAPSHOT"进行构建,那么明天的依赖关系可能会完全不同。这是因为每个新的快照构建将在幕后创建一个新的时间戳工件,以覆盖先前存储的二进制文件。
Ivy有不同的机制来支持开发构建(不同并不意味着更好)。可以依赖于开发中的最新版本,但这总是在构建时显式地解决。当将工件发布到ivy存储库时,方便的交付任务能够创建完全解析的ivy文件。对于所使用的依赖的版本,从来没有任何歧义。
所以在结论中,首先要考虑是否真的需要支持快照工作流。除非您打算使用Maven与其他团队集成,否则强迫ivy遵循它不支持的工作流是不明智的。
标题>标题>