Java ivy:publish 如何运作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/353336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does ivy:publish work?
提问by Mauli
I'm completely at loss how the ant task ivy:publish is supposed to work.
我完全不知道 ant 任务 ivy:publish 应该如何工作。
I would expect that I do my normal build, which creates a bunch of jar files, then I would push those jars to the (local) repository.
我希望我进行正常的构建,这会创建一堆 jar 文件,然后我会将这些 jar 推送到(本地)存储库。
How can I specify from where to retrieve the built jars, and how would those end up in the repository?
我如何指定从哪里检索构建的 jars,以及它们将如何在存储库中结束?
Update:
更新:
<target name="publish-local" description="--> Publish Local">
<ivy:retrieve />
<ivy:publish resolver="local" pubrevision="${release.version}" status="release" update="true" overwrite="true">
<artifacts pattern="${dist.dir}/[organisation]-[module].[ext]" />
</ivy:publish>
</target>
this actually works, I didn't include the retrieve before.
这实际上有效,我之前没有包括检索。
But I still have some problems, suppose I want to publish 3 jars, openscada-utils.jar, openscada-utils-sources.jar and openscada-utils-javadocs.jar as openscada-utils-0.9.2.jar, openscada-utils-0.9.2-sources.jar and openscada-utils-0.9.2-javadocs.jar
但是我仍然有一些问题,假设我想发布 3 个 jar,openscada-utils.jar、openscada-utils-sources.jar 和 openscada-utils-javadocs.jar 作为 openscada-utils-0.9.2.jar、openscada-utils -0.9.2-sources.jar 和 openscada-utils-0.9.2-javadocs.jar
It isn't entirely clear to me, how the actual names are assembled, and where I can specify which names they should get. (Using the fragment above, the jars are always called only utils.jar).
我并不完全清楚,实际名称是如何组合的,以及我可以在哪里指定它们应该获得哪些名称。(使用上面的片段,罐子总是只被称为 utils.jar)。
Update 1:
更新 1:
I got it to work (a bit), but it still doesn't feel right. Somehow all tutorials focus on dependencies from 3rd party projects, but an equally important point for me is to handle project specific dependencies.
我让它工作(有点),但它仍然感觉不对。不知何故,所有教程都关注来自 3rd 方项目的依赖项,但对我来说同样重要的一点是处理项目特定的依赖项。
I have a bunch of sub projects which depend on each other in various ways. Considering ivy:publish it is not clear to me how to start.
我有一堆子项目,它们以各种方式相互依赖。考虑到 ivy:publish 我不清楚如何开始。
How do I handle the first version? I have a common version number for all sub projects to indicate that they belong together (lets say 0.9). Therefore the first revision should be 0.9.0, but so far nothing of my projects is in my repository. How do I get Ivy to assign this revision number.
In the course of developing I want to publish the built files again, without changing the revision number so far.
If I'm finished with my work I want to push it to a shared repository (and increase the revision number lets say from 0.9.0 to 0.9.1), what is the recommended approach to do so?
For an actual release, I want to make distributions with dependencies and without, somehow I guess I can use different configurations for that. How can I use that to my advantage?
我如何处理第一个版本?我有所有子项目的通用版本号,以表明它们属于一起(比方说 0.9)。因此,第一个修订版应该是 0.9.0,但到目前为止,我的存储库中没有任何项目。我如何让 Ivy 分配此修订号。
在开发过程中,我想再次发布构建的文件,目前为止不更改修订号。
如果我完成了我的工作,我想将其推送到共享存储库(并将修订号从 0.9.0 增加到 0.9.1),那么推荐的方法是什么?
对于实际发布,我想制作具有依赖关系和不具有依赖关系的发行版,不知何故我想我可以为此使用不同的配置。我怎样才能利用它来发挥我的优势?
回答by sblundy
You need to specify the "resolver". Something like:
您需要指定“解析器”。就像是:
<ivy:publish resolver="local" pubrevision="1.0"/>
It's controlled by the pattern. This pagecovers it pretty well. It looks like you want yours to be:
它由模式控制。这个页面很好地涵盖了它。看起来你想要你的:
<artifacts pattern="${dist.dir}/[organisation]-[module]-[revision]-[type].[ext]" />
And you'll need to identify the three jars as artifacts in the ivy.xml file. Something like this:
并且您需要将这三个 jar 标识为 ivy.xml 文件中的工件。像这样的东西:
<publications>
<artifact name="utils"/>
<artifact name="utils" type="source"/>
<artifact name="utils" type="javadocs"/>
</publications>
回答by Jared
It's important to realize what ivy is doing here. It is NOT simply copying your artifact jars into the ivy repository - it is also generating the relevant ".ivy.xml" files that specify all the dependents of each of your artifacts.
重要的是要意识到常春藤在这里做什么。它不是简单地将您的工件 jar 复制到 ivy 存储库中 - 它还会生成相关的“.ivy.xml”文件,这些文件指定了您的每个工件的所有依赖项。
Under the covers, the ivy:retrieve
task is actually also triggering an ivy:resolve
. When that ivy:resolve occurs, a file is written to your local ivy cache (in the .ivy
folder in user.home
) that specifies how the resolution happened (which revisions of which modules were required to complete the resolution.) When ivy:publish
is encountered, that resolution record is retrieved from cache and used to generate the ivy.xml for your artifacts.
在幕后,该ivy:retrieve
任务实际上也触发了一个ivy:resolve
. 当该 ivy:resolve 发生时,一个文件被写入您的本地 ivy 缓存(在 中的.ivy
文件夹中user.home
),该文件指定解析是如何发生的(完成解析需要哪些模块的哪些修订版。)ivy:publish
遇到时,该解析记录是从缓存中检索并用于为您的工件生成 ivy.xml。
The largest pitfall I've found in doing this is the requirement that the ivy:resolve
and ivy:publish
tasks both be loaded by the same classloader when they are executed by ant. The easiest way to make sure this happens is to use the loaderRef on your taskdef tasks. For example (note the matching loaderRef tags):
我在这样做时发现的最大缺陷是要求ivy:resolve
和ivy:publish
任务在由 ant 执行时由同一个类加载器加载。确保这种情况发生的最简单方法是在 taskdef 任务上使用 loaderRef。例如(注意匹配的 loaderRef 标签):
<taskdef name="ivy-retrieve"
classname="org.apache.ivy.ant.IvyRetrieve"
classpathref="ivy.lib"
loaderRef="ivy.loader"/>
<taskdef name="ivy-publish"
classname="org.apache.ivy.ant.IvyPublish"
classpathref="ivy.lib"
loaderRef="ivy.loader"/>
回答by Peter Lamberg
First you need an ivy.xml file.
首先,您需要一个 ivy.xml 文件。
<ivy-module version="2.0">
<info organisation="com.example.code" module="MyProject"
revision="${project.revision}"/>
<configurations>
<conf name="runtime" description="" />
... other config elements here...
</configurations>
<publications defaultconf="runtime">
<artifact name="MyProject" type="jar" ext="jar" conf="runtime" />
</publications>
<dependencies>
...
</dependencies>
</ivy-module>
The info element and publications elements in ivy.xml allow you to skip various attributes on the ivy elements in build.xml.
ivy.xml 中的 info 元素和publications 元素允许您跳过build.xml 中ivy 元素的各种属性。
Note the ${project.revision} in ivy.xml. The property is given value in build.xml, but this seems to work nicely. The revision can then easily have whatever value is required (eg. nightly builds vs. local builds).
注意ivy.xml 中的${project.revision}。该属性在 build.xml 中给出了值,但这似乎工作得很好。然后,修订版可以轻松获得所需的任何值(例如,每晚构建与本地构建)。
Here is a sample how you could set up your build.xml file
以下是如何设置 build.xml 文件的示例
<property name="project.revision" value="1.0.0"/>
...
<target name="ivy">
<ivy:resolve />
<!-- Possible ivy:report, ivy:retrieve and other
elements for managing your dependencies go here -->
<ivy:deliver conf="*(public)"/>
</target>
<target name="publish" depends="clean, ivy, jar">
<ivy:publish resolver="local">
<!-- possible artifacts elements if your artifacts
are not in standard location -->
</ivy:publish>
</target>
...
回答by David W.
You're suppose to run the <ivy:deliver/>
task first. This creates an ivy.xml file that can be used by the Ivy repository.
您应该先运行<ivy:deliver/>
任务。这将创建一个可供 Ivy 存储库使用的 ivy.xml 文件。
When you use <ivy:publish>
you specify which repository you want to publish to by specifying it in the resolver
parameter. This needs to match the resolver name in your ivy.settings.xml
file.
使用时,<ivy:publish>
您可以通过在resolver
参数中指定来指定要发布到的存储库。这需要与ivy.settings.xml
文件中的解析器名称匹配。
You don't really specify the artifacts, but a pattern where to find the artifacts to publish. You specify this via the <artifacts>
subtask on the <ivy:publish>
task. For example, if you build everything under the ${basedir}/target/archive
directory like we do, you can specify it as this:
您并没有真正指定工件,而是指定在哪里可以找到要发布的工件的模式。您可以通过<artifacts>
任务上的子任务来指定它<ivy:publish>
。例如,如果您${basedir}/target/archive
像我们一样在目录下构建所有内容,则可以将其指定为:
<ivy:publish resolver="public">
<artifacts path="target/archive/[artifact].[ext]"/>
</ivy:publish>
If you want to change the revision number of your file, you can use the pubrevisionparameter of the <ivy:publish>
task. This doesn't update the ivy.xml
, but will publish your jars/wars to the correct revision. I prefer to use the pubrevisionparameter of the <ivy:deliver>
task and let it create the correct ivy.xml
file anyway. Then, <ivy:publish>
will use the revision in my ivy.xml
file.
如果要更改文件的修订号,可以使用任务的pubrevision参数<ivy:publish>
。这不会更新ivy.xml
,但会将您的 jars/wars 发布到正确的修订版。我更喜欢使用任务的pubrevision参数,<ivy:deliver>
并让它创建正确的ivy.xml
文件。然后,<ivy:publish>
将在我的ivy.xml
文件中使用修订版。
You don't need to do <ivy:retrieve>
. After all, you're running a build to create new jars, and they should be SOMEWHERE in your build. Otherwise, if you're not creating a jar or war what are you trying to publish into your Ivy repository? And, you certainly don't want to retrieve something already in your Ivy repository just to republish it.
你不需要做<ivy:retrieve>
。毕竟,您正在运行一个构建来创建新的 jar,它们应该在您的构建中的某个地方。否则,如果您不是在创建 jar 或 war,您想将什么发布到您的 Ivy 存储库中?而且,您当然不想为了重新发布而检索 Ivy 存储库中已有的内容。
My philosophy has always been that publishing is a CM task and shouldn't be done as part of the build procedure. Thus, we don't use <ivy:deliver>
or <ivy:publish>
.
我的理念一直是发布是一项 CM 任务,不应作为构建过程的一部分来完成。因此,我们不使用<ivy:deliver>
or <ivy:publish>
。
We use Artifactory as our Ivy repository (and our Maven repository). We use Jenkinsas our continuous build server.
我们使用 Artifactory 作为我们的 Ivy 存储库(以及我们的 Maven 存储库)。我们使用Jenkins作为我们的持续构建服务器。
What I do is have the developers make a pom.xml
file out of their ivy.xml
file via the <ivy:makepom>
task. This and the build jars/wars are saved as archived artifacts in Jenkins.
我所做的是让开发人员通过任务pom.xml
从他们的ivy.xml
文件中创建一个文件<ivy:makepom>
。这和构建 jars/wars 被保存为 Jenkins 中的存档工件。
When we are happy with a particular build and want it in our public repository, I use Jenkin's Promote Build task to promote a particular jar/war with its pom.xml to our Artifactory repository. We use the mvn deploy:deploy-file
task to do that.
当我们对特定的构建感到满意并希望它在我们的公共存储库中时,我使用 Jenkin 的提升构建任务将带有 pom.xml 的特定 jar/war 提升到我们的 Artifactory 存储库。我们使用mvn deploy:deploy-file
任务来做到这一点。