Gradle: How do I include ivy artifacts by pattern?
Asked Answered
H

2

10

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?

Hulking answered 11/6, 2015 at 17:48 Comment(4)
Does it handle local or remote files?Faulk
The Ivy repository is remote. I'd prefer to avoid downloading extra files by Gradle and filtering them locallyHulking
Could you please provide an example of such library?Faulk
For example, builds of Kotlin language compiler have artifacts with build numbers in their names. See this ivy descriptor I would like to match something like <include name="kotlin-compiler-(.*)" ext="zip" matcher="exactOrRegexp"/>Hulking
H
4

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)

Hulking answered 29/7, 2015 at 11:8 Comment(0)
E
2

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.

Eunuchize answered 30/6, 2015 at 14:25 Comment(1)
I do understand how to use Ivy repositories, as well as I am familiar with includes when filtering local artifacts. Yet, Ivy have a notion of filtering remote dependency and that is what I would like to achieve in Gradle.Hulking

© 2022 - 2024 — McMap. All rights reserved.