简体   繁体   English

通过示例发布到本地Ivy缓存并从中解析

[英]Publishing to and resolving from Local Ivy Cache by Example

I think the most astonishing thing here is that this functionality is baked in by default to Maven and Gradle, yet, there are no traces of its existence in the Ant/Ivy landscape (see for yourself!). 我认为这里最令人吃惊的是,默认情况下,此功能已引入Maven和Gradle,但是在Ant / Ivy环境中没有任何痕迹(请亲自看看!)。


I have inherited a suite of JVM components that use Ant/Ivy as their build/dependency system. 我继承了一套使用Ant / Ivy作为其构建/依赖系统的JVM组件。 There are lots of dependencies between each of these components, which means making a change to one of them usually has a ripple effect requiring you to update Ivy dependencies and publish new version of upstream dependencies. 这些组件中的每个组件之间都有很多依赖关系,这意味着对其中之一进行更改通常会产生连锁反应,从而要求您更新Ivy依赖关系并发布上游依赖关系的新版本。

The old team maintaining these projects handled local development by publishing snapshot jars to a snapshot repo. 维护这些项目的旧团队通过将快照jar发布到快照仓库来处理本地开发。 I would like to replace this paradigm with a new one whereby snapshots are published to/resolved from the local Ivy cache. 我想用一种新的范例来代替,将快照发布到本地Ivy缓存/从中解析快照。

I was able to find this very similar question but found the answer a bit lacking on details (particularly a fully stitched-together code snippet), in part because the question lacked any specific code examples. 我能够找到这个非常相似的问题,但发现答案缺少细节(尤其是完全缝合在一起的代码段),部分原因是该问题缺少任何特定的代码示例。 So I have created an SSCCE here and have pushed 2 GitHub repos: 所以我在这里创建了一个SSCCE ,并推送了2个GitHub存储库:

  • fizzbuzz-model , a Java library that defines a data model (some meaningless POJOs) fizzbuzz-model ,一个定义数据模型的Java库(一些无意义的POJO)
  • fizzbuzz-app , a simple executable jar that depends on fizzbuzz-model as a dependency fizzbuzz-app ,一个简单的可执行jar,它依赖于 fizzbuzz-model

What I am looking for here are the exact (that is, actual code , not pseudo-code) changes (likely to build.xml , ivy.xml or ivy-settings.xml , or all three!) that will allow me to use the following local dev/test cycle: 我在这里寻找的是允许我使用的确切的 (即实际代码 ,而不是伪代码)更改(可能是build.xmlivy.xmlivy-settings.xml或所有这三个!)。以下本地开发/测试周期:

  1. I make a change to fizzbuz-model and publish the change locally to the Ivy cache, preferably as a snapshotted version (such as 1.0.0-SNAPSHOT or similar) 我对fizzbuz-model进行了更改, fizzbuz-model更改本地发布到常春藤缓存,最好是作为快照版本(例如1.0.0-SNAPSHOT或类似版本)发布
  2. From inside of the fizzbuzz-app root directory, I run ant resolve which pulls in those changes from the cached snapshot fizzbuzz-app根目录内部,我运行ant resolve ,它从缓存的快照中提取那些更改
  3. Now I can make use of those changes in fizzbuzz-app 现在我可以在fizzbuzz-app利用这些更改

Though not a hard requirement, I would ideally like to not have to manage version numbers manually. 尽管不是硬性要求,但理想情况下,我还是希望不必手动管理版本号。 That is, when I publish fizzbuzz-model locally, it overwrites the current binary with the same version (again, like fizzbuz-model-1.0.0-SNAPSHOT.jar ) instead of incrementing the buildnumber to, say, fizzbuzz-model-1.0.1-SNAPSHOT.jar or similar). 也就是说,当我在本地发布fizzbuzz-model ,它会使用相同版本(再次类似于fizzbuz-model-1.0.0-SNAPSHOT.jar覆盖当前二进制文件,而不是将内部版本号增加到例如fizzbuzz-model-1.0.1-SNAPSHOT.jar或类似名称)。 That way all I have to do when testing locally is publish fizzbuzz-model and resolve fizzbuzz-app . 这样,在本地测试时我要做的就是发布fizzbuzz-model并解决fizzbuzz-app

Currently, when I publish fizzbuzz-model , I get the following errors: 当前,当我发布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)

To reproduce locally, clone both those projects and follow their READMEs, starting with fizzbuzz-model . 要在本地复制,请从fizzbuzz-model开始,克隆这两个项目并遵循其自述文件。 Can anyone spot where I'm going awry? 谁能发现我要去哪里? Feel free to answer here and/or submit a PR, whichever you prefer! 随意在这里回答和/或提交PR,无论您喜欢哪个! And thanks! 谢谢!

The error indicates that ivy cannot find a file to be published, in the local build workspace. 该错误表明ivy在本地构建工作区中找不到要发布的文件。 It is not a snapshot issue. 这不是快照问题。

The problem is here : 问题在这里

<ivy:publish resolver="local" pubrevision="1.0.0-SNAPSHOT" >
  <artifacts pattern="dist/[artifact]-[revision].[ext]" />
</ivy:publish>

You have included a "revision" in the pattern but unfortunately the jar you created locally does not match this naming convention. 您已经在模式中包括了“修订”,但是很遗憾,您在本地创建的jar与该命名约定不匹配。 It's missing both the revision and thereis a typo (should be "fizzbuzz", not "fizbuz"): 它既缺少修订版,也没有错字(应该是“ fizzbuzz”,而不是“ fizbuz”):

<target name="dist" depends="clean,compile">
  <jar jarfile="dist/fizzbuz-model.jar" basedir="build/main" />
</target>

I predict further issues because you are attempting to configure ivy to emulate the way Maven stores snapshot revisions. 我预计会有进一步的问题,因为您正在尝试配置ivy以模拟Maven存储快照修订版的方式。 This requires additional metadata files that have never been officially documented by Maven. 这需要Maven从未正式记录过的其他元数据文件。 I would highly recommend pushing your published file to a Maven repository manager for the correctly formatted SNAPSHOT storage. 我强烈建议将发布的文件推送到Maven存储库管理器中,以正确格式化SNAPSHOT存储。

The following are examples of publishing artefacts to a Maven repo from ivy 以下是从常春藤将文物发布到Maven回购中的示例


Suggested solution 建议的解决方案

I have submitted to Pull requests as requested with my suggestion on how a local ivy repository can be used in preference to snapshot releases: 我已根据请求提交了Pull请求,并提出了有关如何优先于快照发行版使用本地ivy存储库的建议:

In summary the model publishes a new revision with every fresh build 总而言之,模型每发布一个新版本都会发布一个新修订。

<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>

And this is used as a dynamic dependency in the app code, always retrieving the lastest published release of the other module. 并在应用程序代码中用作动态依赖项,始终检索其他模块的最新发布版本。

<dependencies>
    <dependency org="hotmeatballsoup" name="fizzbuzz-model" rev="latest.integration" conf="compile->default" />
</dependencies>

Notes: 笔记:

  • As a bonus a POM file is also being generated, strictly speaking it's not necessary unless you're pushing artifacts to a Maven repo. 作为奖励,还可以生成POM文件,严格来说,除非您将工件推送到Maven存储库,否则没有必要。

Background 背景

Dependency managers like ivy come from a time before Maven's universal popularity (I remember when Maven 1.0 was universally hated), so it's unsurprising that ivy doesn't exactly implement the Maven's workflow. 像ivy这样的依赖管理器来自Maven普遍流行之前的时间(我记得Maven 1.0受到普遍憎恨的时候),因此常春藤没有完全实现Maven的工作流就不足为奇了。

Maven is and always has been a highly opinionated tool. Maven一直以来都是一个自以为是的工具。 Confusingly it supports two ways to publish an artifact. 令人困惑的是,它支持两种发布工件的方式。 As a release or as a snapshot. 作为发行版或快照。 In my opinion this is what causes the most friction when attempting to use Maven for continuous deployment, where all releases should be considered for release. 在我看来,这是尝试使用Maven进行连续部署时造成最大摩擦的原因,在该部署中应考虑所有发行版。 But it cannot be denied that Maven is the universal way to distribute all Java based binaries. 但是不能否认,Maven是分发所有基于Java的二进制文件的通用方法。 Maven repositories can serve as a single integration point supporting multiple build technologies, Maven, Gradle or ANT/Ivy. Maven存储库可以用作单个集成点,支持Maven,Gradle或ANT / Ivy等多种构建技术。

So one needs to first accept that the snapshot development workflow is very peculiar to Maven, and to the best of my knowledge has not been replicated by any other repository formats. 因此,首先需要承认快照开发工作流程是Maven特有的,并且据我所知,其他任何存储库格式都没有复制过。

In other repositories the version number for a release is always unique. 在其他存储库中,发行版的版本号始终是唯一的。 That applies to official releases, candidate release or development releases. 这适用于官方发行版,候选发行版或开发发行版。 A Maven snapshot, on the other hand, is never finalized. 另一方面,Maven快照永远不会完成。 What do I mean by that? 那是什么意思 If I build against version "1.0-SNAPSHOT" today, the dependency could be completely different tomorrow. 如果我今天使用版本“ 1.0-SNAPSHOT”进行构建,则明天的依赖关系可能会完全不同。 That is because each new snapshot build will either create a new timestamped artefact behind the scenes to just overwrite the previously stored binary. 这是因为每个新的快照构建都会在后台创建一个新的带有时间戳记的伪像,以覆盖先前存储的二进制文件。

Ivy has a different mechanism for supporting development builds (Different does not mean better). Ivy具有不同的支持开发版本的机制(不同并不意味着更好)。 One can depend on the latest version in development, but this will always be explicitly resolved at build time. 一个人可以依赖于开发中的最新版本,但这始终会在构建时得到明确解决。 When one publishes an artefact to an ivy repository then the handy deliver task is capable of creating a fully resolved ivy file. 当将文物发布到常春藤存储库时,便捷的交付任务便能够创建一个完全解析的常春藤文件。 There is never any ambiguity about what version of a dependency was used. 对于使用哪个版本的依赖关系,从没有任何歧义。

So in conclusion, first make a call on whether you actually need to support a snapshot workflow. 因此,总而言之,首先请致电您是否确实需要支持快照工作流。 Unless you intend to integrate with other teams using Maven it is unwise to force ivy to follow a workflow it was not designed to support. 除非您打算使用Maven与其他团队集成,否则强迫常春藤遵循原本不支持的工作流程是不明智的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM