在 Ivy 中检查包的最新版本
Check for packages latest version in Ivy
我们使用 Ivy 进行依赖管理。为了保证稳定性和可追溯性,我们在 ivy 文件中修复了所有依赖项的版本号,另外我们使用 transitive=false
来避免依赖树不受控制地增长。第二种唯一的缺点是可能需要进行一些测试才能完成 ivy 文件。
由于我们修复了版本号,因此我们不会获得关于是否存在更高版本软件包的更新。我们不希望 是在构建时获取依赖项的最新版本。 我们想要的是定期检查可用的更新,然后决定是否更新以及更新哪些包。
例如,这是截至 2016 年 1 月 14 日的 Spring 依赖关系
<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 个包)。
Ant 的 ivy:report
不会显示更新版本的可用性。在 Maven 上手动检查 101 个包很无聊。
我们还有一个本地 Artifactory 安装,我是说如果它能被证明有用的话。
有什么想法吗?我想看到的是一份包含 Ivy 文件中包的当前和最新版本号的报告
我刚找到一个 ivy 任务 checkdepsupdate 旨在解决您的问题:
<target name="resolve" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:checkdepsupdate showTransitive="false" revisionToCheck="latest.release"/>
</target>
在我下面的示例中使用 ivy 文件,它会打印以下报告详细信息,即我的第 3 方依赖项的最新版本。
[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
我想这可能就是您要找的。
杂项
冒着陈述显而易见的风险,通过设置 transitive=false,您自己承担了管理整个依赖关系树的工作。对于简单的项目,这很好,但您现在发现了这种方法的缺点。 Spring 等项目故意将其可交付成果分成多个 jar 以增加灵活性。它允许您只下载所需的内容,并避免包含一个非常大的整体 spring jar。
我会推荐一些东西来改善你的常春藤体验
- 采用 ivy 的传递依赖管理
- 使用dynamic revisions
- 发布到存储库,以创建发布记录
传递依赖和class路径管理
在我的 ivy 文件中,我通常只包含包含我正在使用的 class 的模块,让 ivy 处理其他依赖项。我还使用 ivy configurations 按功能对依赖项进行分组。我的最终目标是使用配置来填充 java class 路径,因此我的一些依赖项在编译时需要,其他在 run-time,最后经常测试需要永远不会的 jar随版本发布。
常春藤文件示例:
<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,但在运行时根据 class 中包含的 jars 决定特定的实现小路。在上面的示例中,我告诉我的构建在运行时使用 log4j 实现 jar,这将依次下载兼容版本的 log4j 及其依赖的所有内容。
最后,请注意每个配置如何扩展另一个配置?这意味着测试配置将在编译和运行时配置中包含 jar。当 运行 使用 junit 进行单元测试时,这正是我所需要的。
这是我在 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>
编译和测试 class 路径现在 auto-populated 可以用作参考:
<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>
并且解析任务已经为构建维护的每个class路径创建了一个记录。
动态修订
当您发布到 ivy 存储库时,您可以指定发布类型。这允许 ivy 自动确定特定发布类型的最新发布版本。默认支持两种版本:
- 整合
- 发布
前者对应Snapshot发布的Maven概念。在您组织内的另一个团队的控制下构建二进制文件,但尚未准备好发布。后者当然适用于完全批准和发布的二进制文件,非常适合第 3 方依赖项。
下面举例说明两者的理论用法dynamic revisions:
<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>
这样就可以实现你的愿望了。您的构建将自动注册来自 3rd 方项目的新依赖项。
发布到存储库,以创建发布记录
时间不会停滞不前,项目的依赖树也不会停滞不前。由于大量的直接依赖关系,现代 Java 程序可能会在解决依赖关系时变得非常混乱。
但是....如何重现旧版本?我们可能会标记我们的源代码,但是如何在那个时间点.
跟踪依赖关系
我决定将每个版本发布到 Maven 存储库中:
- how to publish 3rdparty artifacts with ivy and nexus
这是一个片段
<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 I need to generate a Maven POM file for my module. Notice the use of the tasks deliver and makepom?第一个将创建一个临时 ivy 文件,其中包含我的每个依赖项的已解析版本号。这意味着 Maven 中生成的 POM 文件包含我用来构建代码的真实版本。
您可以扩展这个想法,并在您发布的二进制文件旁边另外发布以下内容:
- Java文档 jar
- 源代码jar
- Ivy 报告 jar
- Junit 报告 jar
- 等等
在我看来,release repository 应该是你发布的不变记录,也是对源代码库的重要补充。事实上,在大型企业组织中,这种基于文件的发布记录可能比您的源代码存储库技术更长久(Clearcase -> Subversion -> Git -> ??)。
我们使用 Ivy 进行依赖管理。为了保证稳定性和可追溯性,我们在 ivy 文件中修复了所有依赖项的版本号,另外我们使用 transitive=false
来避免依赖树不受控制地增长。第二种唯一的缺点是可能需要进行一些测试才能完成 ivy 文件。
由于我们修复了版本号,因此我们不会获得关于是否存在更高版本软件包的更新。我们不希望 是在构建时获取依赖项的最新版本。 我们想要的是定期检查可用的更新,然后决定是否更新以及更新哪些包。
例如,这是截至 2016 年 1 月 14 日的 Spring 依赖关系
<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 个包)。
Ant 的 ivy:report
不会显示更新版本的可用性。在 Maven 上手动检查 101 个包很无聊。
我们还有一个本地 Artifactory 安装,我是说如果它能被证明有用的话。
有什么想法吗?我想看到的是一份包含 Ivy 文件中包的当前和最新版本号的报告
我刚找到一个 ivy 任务 checkdepsupdate 旨在解决您的问题:
<target name="resolve" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:checkdepsupdate showTransitive="false" revisionToCheck="latest.release"/>
</target>
在我下面的示例中使用 ivy 文件,它会打印以下报告详细信息,即我的第 3 方依赖项的最新版本。
[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
我想这可能就是您要找的。
杂项
冒着陈述显而易见的风险,通过设置 transitive=false,您自己承担了管理整个依赖关系树的工作。对于简单的项目,这很好,但您现在发现了这种方法的缺点。 Spring 等项目故意将其可交付成果分成多个 jar 以增加灵活性。它允许您只下载所需的内容,并避免包含一个非常大的整体 spring jar。
我会推荐一些东西来改善你的常春藤体验
- 采用 ivy 的传递依赖管理
- 使用dynamic revisions
- 发布到存储库,以创建发布记录
传递依赖和class路径管理
在我的 ivy 文件中,我通常只包含包含我正在使用的 class 的模块,让 ivy 处理其他依赖项。我还使用 ivy configurations 按功能对依赖项进行分组。我的最终目标是使用配置来填充 java class 路径,因此我的一些依赖项在编译时需要,其他在 run-time,最后经常测试需要永远不会的 jar随版本发布。
常春藤文件示例:
<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,但在运行时根据 class 中包含的 jars 决定特定的实现小路。在上面的示例中,我告诉我的构建在运行时使用 log4j 实现 jar,这将依次下载兼容版本的 log4j 及其依赖的所有内容。
最后,请注意每个配置如何扩展另一个配置?这意味着测试配置将在编译和运行时配置中包含 jar。当 运行 使用 junit 进行单元测试时,这正是我所需要的。
这是我在 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>
编译和测试 class 路径现在 auto-populated 可以用作参考:
<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>
并且解析任务已经为构建维护的每个class路径创建了一个记录。
动态修订
当您发布到 ivy 存储库时,您可以指定发布类型。这允许 ivy 自动确定特定发布类型的最新发布版本。默认支持两种版本:
- 整合
- 发布
前者对应Snapshot发布的Maven概念。在您组织内的另一个团队的控制下构建二进制文件,但尚未准备好发布。后者当然适用于完全批准和发布的二进制文件,非常适合第 3 方依赖项。
下面举例说明两者的理论用法dynamic revisions:
<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>
这样就可以实现你的愿望了。您的构建将自动注册来自 3rd 方项目的新依赖项。
发布到存储库,以创建发布记录
时间不会停滞不前,项目的依赖树也不会停滞不前。由于大量的直接依赖关系,现代 Java 程序可能会在解决依赖关系时变得非常混乱。
但是....如何重现旧版本?我们可能会标记我们的源代码,但是如何在那个时间点.
跟踪依赖关系我决定将每个版本发布到 Maven 存储库中:
- how to publish 3rdparty artifacts with ivy and nexus
这是一个片段
<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 I need to generate a Maven POM file for my module. Notice the use of the tasks deliver and makepom?第一个将创建一个临时 ivy 文件,其中包含我的每个依赖项的已解析版本号。这意味着 Maven 中生成的 POM 文件包含我用来构建代码的真实版本。
您可以扩展这个想法,并在您发布的二进制文件旁边另外发布以下内容:
- Java文档 jar
- 源代码jar
- Ivy 报告 jar
- Junit 报告 jar
- 等等
在我看来,release repository 应该是你发布的不变记录,也是对源代码库的重要补充。事实上,在大型企业组织中,这种基于文件的发布记录可能比您的源代码存储库技术更长久(Clearcase -> Subversion -> Git -> ??)。