在常春藤中检查软件包的最新版本 [英] Check for packages latest version in Ivy

查看:59
本文介绍了在常春藤中检查软件包的最新版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用Ivy进行依赖项管理.为了保证稳定性和可追溯性,我们在常春藤文件中修复了所有依赖项的版本号,并使用transitive=false避免依赖项树变得不受控制.第二个缺点是,它可能需要进行一些测试才能完成ivy文件.

We use Ivy for dependency management. In order to guarantee stability and traceability, we fix version numbers for all dependencies in our ivy files, plus we use transitive=false to avoid dependency trees to grow uncontrolled. The second has only the disadvantage that it may require a few tests to complete the ivy file.

由于我们已经确定了版本号,因此不会就软件包更高版本的存在得到更新.我们不想要的是在构建时获取依赖项的最新版本. 我们想要的是要定期检查可用更新,然后再决定是否以及要更新哪些软件包.

Since we fix version numbers, we don't get updated about the existence of a later version of a package. What we don't want is to get the freshest version of a dependency at build time. What we want is to periodically check for available updates and later decide whether and which packages to update.

作为示例,这是我们从2016年1月14日起的Spring依赖项

As an example, here are our Spring dependencies as of 01/14/2016

    <dependency org="org.springframework"               name="spring-core"                      rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-aop"                       rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-beans"                     rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-context"                   rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-context-support"           rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-expression"                rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-jdbc"                      rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-orm"                       rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-tx"                        rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-web"                       rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-webmvc"                    rev="4.2.4.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework"               name="spring-test"                      rev="4.2.4.RELEASE"     transitive="false"          conf="test->*"/>
    <dependency org="org.springframework.plugin"        name="spring-plugin-core"               rev="1.2.0.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework.plugin"        name="spring-plugin-metadata"           rev="1.2.0.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework.batch"         name="spring-batch-core"                rev="3.0.6.RELEASE"     transitive="false"          conf="runtime->*"/>
    <dependency org="org.springframework.batch"         name="spring-batch-infrastructure"      rev="3.0.6.RELEASE"     transitive="false"          conf="runtime->*"/>

但是我们还有更多.因此,我问是否有一种更聪明的方法来检查所有软件包的可能更新(我们现在有101个软件包).

But we have a lot more. So I am asking if there is a smarter way to check for possible updates for all packages (we now have 101 packages).

Ant的ivy:report将不会显示更高版本的可用性.在Maven上手动检查101个软件包很无聊.

Ant's ivy:report won't show the availability of a later version. Manually checking 101 packages on Maven is boring.

我们也有一个本地Artifactory装置,我想说的是如果它对目的有用的话.

We also have a local Artifactory installation, I'm saying that if it could prove useful for purpose.

有什么主意吗?我想看到的是一个报告,其中包含常春藤文件中软件包的当前和最新版本

Any idea? What I would like to see is a report with current and latest version numbers of packages in an Ivy file

推荐答案

我刚刚找到了一个常春藤任务

I just found an ivy task checkdepsupdate designed to solve your problem:

<target name="resolve" description="Use ivy to resolve classpaths">
    <ivy:resolve/>
    <ivy:checkdepsupdate showTransitive="false" revisionToCheck="latest.release"/>
</target>

以我下面的示例中的ivy文件为例,它将打印以下报告详细信息,这是我的第三方依赖项的最新版本.

Taking the ivy file in my example below it prints the following report detailing, the latest releases for my 3rd party dependencies.

[ivy:checkdepsupdate] Dependencies updates available :
[ivy:checkdepsupdate]   org.slf4j#slf4j-api 1.7.5 -> 1.7.13
[ivy:checkdepsupdate]   org.slf4j#slf4j-log4j12 1.7.5 -> 1.7.13
[ivy:checkdepsupdate]   junit#junit 4.11 -> 4.12

我认为这可能是您想要的.

I think this might be what you are looking for.

冒昧地说出明显的危险,通过设置transitive = false,您将承担管理整个依赖关系树的工作.对于简单的项目,这很好,但是您现在发现这种方法的缺点.像Spring这样的项目已将其可交付成果分成多个jar,以提高灵活性.它仅允许您下载所需的内容,而避免包含一个令人难以置信的大型整体式弹簧罐.

At the risk of stating the obvious, by setting transitive=false you take upon yourself the job of managing the entire tree of dependencies. For simple projects that's fine but you're now discovering the downsides of this approach. Projects like Spring have deliberately split their deliverables into multiple jars to increase flexibility. It allows you to only download what you need and avoid the inclusion of one incredibly large monolithic spring jar.

我会推荐一些方法来改善您的常春藤体验

I would recommend a couple of things to improve your ivy experience

  1. 拥抱常春藤对传递依赖的管理
  2. 使用动态修订
  3. 发布到存储库,以创建发布记录

传递依赖关系和类路径管理

在我的ivy文件中,通常只包含包含我正在使用的类的模块,让ivy照顾其他依赖项.我还使用常春藤配置按功能对依赖项进行分组.我的最终目标是使用配置来填充Java类路径,因此在编译时需要我的某些依赖关系,而在运行时则需要一些依赖关系,最终测试经常需要发行版中永远不会附带的jar.

Transitive dependencies and classpath management

In my ivy file I will generally only include the module that contains the class I'm using, letting ivy take care of the other dependencies. I also use ivy configurations to group dependencies by function. My end goal is to use configurations to populate a java classpath, so some of my dependencies are required at compile time, others at run-time, finally testing frequently requires jars that would never be shipped with the release.

示例常春藤文件:

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>

    <configurations>
        <conf name="compile" description="Required to compile application"/>
        <conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
        <conf name="test"    description="Required for test only" extends="runtime"/>
    </configurations>

    <dependencies>
        <!-- compile dependencies -->
        <dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>

        <!-- runtime dependencies -->
        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/>

        <!-- test dependencies -->
        <dependency org="junit" name="junit" rev="4.11" conf="test->default"/>
    </dependencies>

</ivy-module>

SLFJ 项目是一个很好的例子,说明了如何使用标准编程API,但是在运行时根据类路径中包含的jar决定特定的实现.在上面的示例中,我告诉我的构建在运行时使用log4j实现jar,这反过来将拉下兼容版本的log4j及其依赖的所有内容.

The SLFJ project is an excellent example of how one would use a standard programming API, but at runtime decide on a particular implementation based on the jars included on the classpath. In the above example I tell my build to use the log4j implementation jar at runtime, which will in turn pull down a compatible version of log4j and everything it depends on.

最后,请注意每个配置如何扩展其他配置?这意味着测试配置将在编译和运行时配置中都包含jar.正是使用junit进行单元测试时需要的.

Finally, note how each configuration extends the other? This means that the test configuration will include the jars in both the compile and runtime configurations. Exactly what I'd need when running a unit test using junit.

这是我在ANT中的标准解析任务:

This is my standard resolve task in ANT:

<target name="resolve" depends="install-ivy" description="Use ivy to resolve classpaths">
    <ivy:resolve/>

    <ivy:report todir='${build.dir}/ivy-reports' graph='false' xml='false'/>

    <ivy:cachepath pathid="compile.path" conf="compile"/>
    <ivy:cachepath pathid="test.path"    conf="test"/>
</target>

编译和测试类路径现在已自动填充并准备用作参考:

The compile and test classpaths are now auto-populated and ready for use as references:

<target name="compile" depends="resolve" description="Compile code">
    <mkdir dir="${build.dir}/classes"/>
    <javac srcdir="${src.dir}" destdir="${build.dir}/classes" includeantruntime="false" debug="true" classpathref="compile.path"/>
</target>

<target name="test" depends="compile" description="Run unit tests">
    <mkdir dir="${build.dir}/test-reports"/>
    <junit printsummary="yes" haltonfailure="yes">
        <classpath>
            <path refid="test.path"/>
            <pathelement path="${build.dir}/classes"/>
        </classpath>
        ..
        ..
    </junit>
</target>

而且resolve任务已经创建了由构建维护的每个类路径的记录.

And the resolve task has created a record of each classpath maintained by the build.

当您发布到一个常春藤存储库时,您可以指定发布类型.这样,ivy可以自动确定特定发行类型的最新发布版本.默认情况下,支持两种发布类型:

When you publish to an ivy repository you can specify the release type. This allows ivy to automatically determine the latest published version of a particular release type. By default two types of release are supported:

  1. 整合
  2. 发布

前者对应于Snapshot版本的Maven概念.在组织内另一个团队的控制下构建了二进制文件,但尚未发布.后者当然是针对完全批准和发布的二进制文件,非常适合第三方依赖.

The former corresponds to the Maven concept of Snapshot releases. Built binaries under the control of another team within your organisation, but not ready for release yet. The latter is of course for binaries that are fully approved and released, ideal for 3rd party dependencies.

以下是显示两个动态修订:

<dependencies>
    <!-- compile dependencies -->
    <dependency org="myorg" name="teamA" rev="latest.integration" conf="compile->default"/>
    <dependency org="myorg" name="teamB" rev="latest.integration" conf="compile->default"/>
    <dependency org="myorg" name="teamC" rev="latest.integration" conf="compile->default"/>
    <dependency org="org.slf4j" name="slf4j-api" rev="latest.release" conf="compile->default"/>

    <!-- runtime dependencies -->
    <dependency org="org.slf4j" name="slf4j-log4j12" rev="latest.release" conf="runtime->default"/>

    <!-- test dependencies -->
    <dependency org="junit" name="junit" rev="latest.release" conf="test->default"/>
</dependencies>

这样可以实现您的愿望.您的版本会自动注册来自第三方项目的新依赖项.

So this would achieve your desire. Your build would automatically register new dependencies from 3rd party projects.

时间不会停滞不前,项目的依赖关系树也不会停滞不前.由于大量的直接依赖关系,现代Java程序可能会非常困惑以解决依赖关系.

Time does not stand still nor does a project's dependency tree. Due to the high number of direct dependencies a modern Java program may have it can become very confusing to resolve the dependencies.

但是....如何重现旧版本?我们可能会标记我们的源代码,但是如何在那个时间点跟踪.

But.... How does one reproduce an older build? We might tag our source code, but how does one keep track of the dependencies at that point in time.

我决定将每个发行版发布到Maven存储库中:

I decide to publish each release into a Maven repository:

这是一个片段

<target name="prepare" description="Generate POM">
    <!-- Optional: Intermediate file containing resolved version numbers -->
    <ivy:deliver deliverpattern="${build.dir}/ivy.xml" pubrevision="${publish.revision}" status="release"/>

    <!-- Generate the Maven POM -->
    <ivy:makepom ivyfile="${build.dir}/ivy.xml" pomfile="${build.dir}/donaldduck.pom"/>
</target>

<target name="publish" depends="init,prepare" description="Upload to Nexus">
    <ivy:publish resolver="nexus-deploy" pubrevision="${publish.revision}" overwrite="true" publishivy="false" >
        <artifacts pattern="${build.dir}/[artifact](-[classifier]).[ext]"/>
    </ivy:publish>
</target>

由于我使用的是 Nexus ,因此我需要为模块生成Maven POM文件.请注意任务交付 makepom ?第一个将创建一个临时的常春藤文件,其中包含每个依赖项的已解析版本号.这意味着Maven中生成的POM文件包含了我用来构建代码的真实版本.

Since I'm using Nexus I need to generate a Maven POM file for my module. Notice the use of the tasks deliver and makepom? The first will create a temp ivy file containing the resolved version numbers of each of my dependencies. This means the resultant POM file in Maven contains the real versions I used to build my code.

您可以扩展这个想法,并在已发布的二进制文件中另外发布以下内容:

You could expand upon this idea and additionally publish the following alongside your released binary:

  • Javadocs jar
  • 源代码jar
  • 常春藤报告罐子
  • Junit报告jar

我认为发行版本库应该是您发行版本的不变记录,并且是对源代码版本库的重要补充.确实,在大型企业组织中,这种基于文件的发行记录可能会比源代码存储库技术(Clearcase-> Subversion-> Git-> ??)的寿命更长.

In my opinion the release repository should be the unchanging record for your release and important compliment to the source code repository. Indeed in a large corporate organisation, this kind of file based release record could outlive your source code repository technology (Clearcase -> Subversion -> Git -> ??).

这篇关于在常春藤中检查软件包的最新版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆