How can I download Maven artifacts in chef?

I want to do something like this in a chef recipe:

maven_artifact "/opt/foo/my.jar" do
  source "com.foo:my:0.1:jar"
end

But I can't find a cookbook which provides this. I've written something which basically does this but it doesn't handle snapshots, which requires parsing maven-metadata.xml. Before I plunge into this, I wanted to be sure I wasn't missing something obvious since this seems like a basic usecase.


Solution 1:

Based on Apache Buildr code : http://svn.apache.org/repos/asf/buildr/trunk/lib/buildr/packaging/artifact.rb

You can do something like this:

def snapshot?
  version =~ /-SNAPSHOT$/
end

if snapshot?
    metadata_path = "#{group_path}/#{id}/#{version}/maven-metadata.xml"
    metadata_xml = StringIO.new
    URI.download repo_url + metadata_path, metadata_xml
    metadata = REXML::Document.new(metadata_xml.string).root
    timestamp = REXML::XPath.first(metadata, '//timestamp')
    build_number = REXML::XPath.first(metadata, '//buildNumber')
    snapshot_of = version[0, version.size - 9]
    classifier_snippet = (classifier != nil) ? "-#{classifier}" : ""
    repo_url + "#{group_path}/#{id}/#{version}/#{id}-#{snapshot_of}-#{timestamp.text}-#{build_number.text}#{classifier_snippet}.#{type}"
end

Solution 2:

RiotGames has something you might find useful.

Solution 3:

If you use Artifactory as your Maven repository, a more elegant solution is at hand.

Starting from version 2.6.0 a request for a non-unique artifact can return the latest available snapshot.

To utilize this feature, first make sure that the target repository is defined with a unique snapshot policy, then request the desired artifact using a non-unique snapshot version such as:

org/artifact/1.0-SNAPSHOT/artifact-1.0-SNAPSHOT.jar

And the latest unique snapshot of artifact with a base revision of 1.0 will be returned.