ivy:findrevision is not able to resolve a custom pattern in Artifactory, however ivy:retrieve does it - ivy

I have this pattern in my ivysettings file:
<artifact pattern="${artifactory_host}/${repo}/[organisation]/[module]/[revision]/[type]/[artifact]-[revision].[ext]" />
When I resolve my dependencies with ivy:retrieve it gets the dependencies without any problem from Artifactory. But when I try to do it with ivy:findrevision it always set the type and the extension of the artifact as jar.
For instance if the path of the artifact is:
my_company/my_module/0.0.123456/cookbook/my_module_coockbooks-0.0.123456.zip
ivy:findrevision looks for:
my_company/my_module/0.0.123456/jar/my_module_coockbooks-0.0.123456.jar
Previously we had a NFS ivy-repository and ivy:findrevisions worked as good as ivy:retrieve, looking for the corresponding type and extension.
As far as I know the host, in this case Artifactory, shouldn't affect any resolve feature from ant-ivy because at the very end the resolution logic and pathfinding depends exclusively on the client side, in this case ant-ivy.
UPDATE
Ok, I found a simple work around but still not a real solution, I added another patter to the resolver, hardcoding the type and the extension.
<artifact pattern="${artifactory_host}/${repo}/[organisation]/[module]/[revision]/cookboock/[artifact]-[revision].zip" />
I really need to use ivy:findrevision for build logic in my ant-build and I don't want to have a different pattern for each type of artifact.

Related

Defining the behavior of "latest.integration" in Ivy

I'm having problems understanding how latest.integration works.
I have an example that is not giving the output mentioned in:
http://ant.apache.org/ivy/history/latest-milestone/tutorial/defaultconf.html
which says, the local resolver has precedence over other resolvers, regardless of the time of publishing.
My ivysettings.xml goes like this:
<resolvers>
<chain name="download-chain" returnFirst="false" >
<url name="nexus-repo" m2compatible="true" >
<artifact pattern="${nexus}/[organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]" />
<ivy pattern="${nexus}/[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" />
</url>
<resolver ref="local" />
</chain>
</resolvers>
here I declare that I have a nexus url repository and a reference to the default local. I use this chain when I want to resolve my dependencies.
I build the designated artifact and publish it to local with status "integration" with a revision "HEAD" (something like SNAPSHOT for us), first using the local resolver:
<ivy:publish
overwrite="yes"
update="true"
artifactspattern="${project.dist.dir}/[artifact]-[revision](-[classifier]).[ext]"
resolver="local"
settingsRef="ivy.nexus"
/>
and rebuild it again and publish it to nexus repository:
<ivy:publish
overwrite="yes"
update="true"
artifactspattern="${project.dist.dir}/[artifact]-[revision](-[classifier]).[ext]"
resolver="publish-url"
forcedeliver="true"
settingsRef="ivy.nexus"
/>
I have another project that declares the previous artifact as dependency with revision "latest.integration".
I expect that the artifact should be downloaded from the local repository regardless of the order of the declared resolvers. But that's not the case. The artifact downloaded is always of the resolver mentioned first. Changing the name of the "local" resolver didn't affect anything. The order is always what matters.
I tried appending changing="true" to my dependency. It didn't help.
In this question:
Ivy: Forcing local snapshot for dependency
The Asker mentions an even different behavior, namely that the very latest is picked up (the order of resolvers doesn't even matter).
SO to wrap it up and sorry for prolongation:
How to get an artifact:
1) always the latest.integration (the most recent) regardless of location.
2) always from local even if there's a more recent integration version in other locations.
3) Am I that clueless?
I would recommend reading the following answer on publishing artifacts to Nexus
how to publish 3rdparty artifacts with ivy and nexus
Use the ibiblio resolver, it's much simpler.
A second piece of advice is to have a clear separation between an integration and a release builds, within your ANT logic. The former can use a timestamp as it's revision, whereas the latter needs to have a strategy for maintaining an incrementing revision number (that's a whole different question). Maven calls these "SNAPSHOT" or "Release" builds and implements two different types of repository to support them.
A final piece of advice is to avoid using the local repository, unless, that is where you decide to store your integration builds. Ivy maintains a local cache of downloaded artifacts, it's rarely worth the effort or maintaining a local repo.
I could manage to make the order insignificant after all.
I'm not sure how far I should've gone but:
I used the latest="latest-time" in the chain resolver as well as in the URL resolver.
This wasn't however enough and when I debugged the code, I found that each resolver judged by its own 'latest'.
So I overrode the local repository like this:
<filesystem name="local" latest="latest-time" >
<ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}"/>
<artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}"/>
</filesystem>

Mapping from one repository type to another, does it work?

I've been going through all the scenarios, digging around the web, and have yet to find an answer to this. Is it possible for Artifactory to map from one repository layout to another? This is my attempt so far...
In our business we currently have an IVY repository for which we deploy built artifacts. One such artifact is stored at the following path, with the following IVY file:
http://someserver:8080/com.abc.common_library/common_library_to/4.0.0.4-1/jar/common_library_to.jar
http://someserver:8080/com.abc.common_library/common_library_to/4.0.0.4-1/ivy/ivy.xml
For the IVY layouts I've configured the following:
[orgPath]/[module]/baseRev/[type]/([orgPath].)module(-[classifier]).[ext]
[orgPath]/[module]/baseRev/[type]/ivy(-[fileItegRev])(-[classifier]).xml
Now we want to expose this within Artifactory for our maven2 projects to consume. So I configure a new repository, setting the url, etc, and under advanced settings, I set the 'Repository Layout' to be maven-2-default and 'Remote Layout Mapping' to be the modified ivy-default. On making these changes I see the following message appear:
Not all tokens can be mapped between the source and the target layout, which may cause path translation not to work as expected.
I test and save the new repository and all appears happy. I can browse the newly configured repository and view its contents, including the above mentioned artifact. I then generate the maven settings from the home screen, ensure that the correct repositories are selected that include the newly configured one, and apply this to Eclipse.
Having done all of this, I now open the pom file within my Eclipse project and create a new dependency. I specify the following configuration:
Group Id: com.abc.common_library
Artifact Id: common_library_to
Version: 4.0.0.4-1
Type: jar
Scope: compile
Eclipse now attempts to resolve the dependency but gives the following error:
Missing artifact com.abc.common_library:common_library_to:jar:4.0.0.4-1:compile
Am I missing something here? This is quite an important step for us to be able to do. Any feedback will be most appreciated.
See Yoav's response here:
http://forums.jfrog.org/Mapping-from-one-repository-type-to-another-does-it-work-td6807726.html

Apache Ivy Config Standard

I'm trying to set up my first Ivy-powered build and am running into implementation problems, and I feel like I don't fully understand Ivy terminologies & best practices, even though I've spent a great deal of time reading the official docs and countless articles.
I have a SVN server that I want to use as the central repository for all of my projects. I do not want to use any public repositories! When I need a JAR, I'll pull it down from one of those public repos, run a checksum for security, and then push it to my SVN server (wherebyit will be deemed to be a "certified" version of the JAR; by certified, I really mean "safe").
(1) I want all of my projects to share the same ivy-settings.xml file. Do I put this in my SVN root, or somewhere inside SVN that makes sense? Here was my tentative thinking:
svn://MyRepoRoot/
ivy/
ivy-settings.xml
artifacts/
Project1/
trunk/
ivy.xml
...
branches/
tags/
Project2/
...
...
The ivy/ directory would contain a master copy of my ivy-settings.xml file. It would also contain an artifacts subdirectory where all of my "certified" JARs/WARs would go (as well as any publications my projects produce for downstream modules). Can I request for commentary?
(2) Also, something that I'm just not getting, is if each of my projects (modules) have their own ivy.xml file, and I want that file to reference the "global ivy-settings.xml file, which should by all means fall under its own, non-module-related versioning scheme, how do I pull down, say, Project1's trunk as my working copy, but configure it with the settings file which is not even a part of the same SVN project?!?
Thanks to anyone who can help give me a little practical advice and better clarity!
The ivysettings.xml is not referenced in the ivy.xml. You need the ivysettings.xml in your ant tasks to find the defined resolver, which resolve the artifacts defined in the ivy.xml.
ivy.xml defines the dependencies and ivysettings.xml the (local) runtime environment for ivy. You can change the ivysettings.xml anytime without need to edit the ivy.xml files.
The ivysettings.xml needs to be referenced in yout (ant) build.xml in ivys <settings /> task.
As for the layout. I use the same approach and it works fine for me.
I wrote my antfiles, so that I need to have the ivy folder checked out parallel to my project(s).
Another approach could be svns externals. But I never tried that.
If your svn has access over http you could also use the url parameter of the task to access ivysettings.xml.

Get full name of an artifact in Maven

I need to know the complete filename of a specific artifact in Maven. I looked at versions-maven-plugin but it seems to change the pom itself. Is there another way to reach my goal? I want to store the complete artifact name in a property so I can pick it up in Java code.
Normally you have your dependencies and let maven do all the work of retrieving the files from the repository for you.
But you want to use it in your Java code - what Java code?
Are you writing your own mojo that will be doing something during the install phase of your lifecycle?
Then you should be able to access the artifacts that are currently being processed, from there it's not a problem to get the filename.
But maybe you've got just the groupId, artifactId, version and type of an already existing artifact.
With these informations it should be no problem to navigate to your local maven repository, open the directory: groupId/artifactId/version and look what files you've got there. Usually there should be your .pom a .jar, maybe a md5-hashsum and some maven-metadata. If you're not sure which file's the interesting one: take that one with the biggest filesize.

Maven repository configurations

I've asked a similar question in which part of this was addressed, but I'd like to expand in more detail.
When configuring maven to look at internal repositories, is it best to put that information in the project pom or in a user's settings.xml? An explanation on why would be really helpful here.
thanks,
Jeff
You should always try to make the maven project so that it compiles from a clean checkout from source control in your local environment; without a settings.xml. In my opinion this means that you place any overrides to sensible default values in the user's settings.xml file. But the pom should contain sensible values that will work for everyone.
I encourage you to put the repository definition in the POM, this way any developer just grab a copy of the code and run Maven to get it compiled, without having to change things in his settings file.
I find the setting.xml file useful just for hacking Maven's behaviour in special situations, for example when one repository is not accessible due to a firewall and you need to use a mirror. But that's my personal opinion. Maven documentation gives you more freedom:
The settings element in the
settings.xml file contains elements
used to define values which configure
Maven execution in various ways, like
the pom.xml, but should not be bundled
to any specific project, or
distributed to an audience. These
include values such as the local
repository location, alternate remote
repository servers, and authentication
information.
If you have a local repository which is used in every single project you may add that at the settings.xml, just be sure that configuration is well documented, in my current project it's not and new developers struggle at the beginning when they try to compile something.
We use the user's settings.xml and include info in the README about what possible other repos may be needed.
In theory a given group-artifact-version is the same no matter which repo it comes from. It works pretty well for us. If you find yourself with two different assets that have the same group-artifact-version identifier, then that indicates you're doing something really bad.