Gradle: How do I include ivy artifacts by pattern?

5.8k views Asked by At

In Ivy I can have dependency declared like this:

<dependency org="org" name="module_name" rev="12" conf="conf_name->*">
  <include name="foo(.*)-bar" ext="zip" matcher="exactOrRegexp"/>
</dependency>

which will download all matching files.

How can I define similar (regex-based) dependency in Gradle?

2

There are 2 answers

0
Nikita Skvortsov On BEST ANSWER

After some more trial-and-error, I was able to extend Gradle to resolve dependencies with following syntax:

dependencies {
    compile "org:module_name:12" {
        artifact {
            name "foo.*-bar"
            type "zip"
        }
    }
}

For this, one will need project evaluation listener, that will post-process the dependencies. Resolve ivy descriptor for each dependency, parse it, match the artifact names, update the dependency's artifacts descriptors (remove the one with pattern in name and insert matched artifacts with names).

Pros:

  • Properly uses Gradle's artifacts cache.
  • Avoids transfer of exra (not matched) artifacts.
  • Dependencies resolution mechanics is applied.

Pitfalls found during implementation:

  • Copy a configuration before resolving ivy descriptors. Resolved configuration (with dependencies) is considered immutable and wont be resolved again, so matched artifacts will not be downloaded

  • Matching different entities. After an Ivy descriptor is "resolved" and downloaded, it is somewhat tricky to match it with unresolved dependency (to update artifact descriptors), as resolved entity has different type. So far, matching on "group-artifact-version" coordinates works, but it is fragile solution.

A sample code for dependency processor can be found on GitHub (disclamer: provided "as is", no gurantees and responsibilities. But if it blows your project's working copy, please let me know)

1
Veaceslav Gaidarji On

You can check the Gradle documentation related to the Dependency Management -> Defining custom patterns for an Ivy repository

repositories {
    ivy {
        url "http://repo.mycompany.com/repo"
        layout "pattern", {
            artifact "3rd-party-artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
            artifact "company-artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
            ivy "ivy-files/[organisation]/[module]/[revision]/ivy.xml"
        }
    }
}

Regex is used to filter local files or to compile different project libraries:

compile fileTree (dir: "libs", includes: ['*.jar'])

Regex isn't allowed in depenedency declaration.

At least, you can use variables compile "foo:foo:$libVersion", but not regex.

Also, might be helpful this article Java Build Tools: How Dependency Management Works with Maven, Gradle and Ant + Ivy.