How to create a custom repository type

My company uses an internal build system and build artifact repository (let’s call it ABCBuild). The way the repository is organized differs greatly from what we’ve learned to expect in the Java world (group:name:version:modifier:ext). I am trying to build a custom repository class for Gradle, so Gradle uses (a fast-growing community within the company) could access artifacts in the ABCBuild repository for their projects.

After looking through the Gradle source code I figured out that I need two things: a ‘Dependency’ implementation that will hold ABCBuild-specific information about the dependency, and an ‘ArtifactRepository’ (or ‘DependencyResolver’) implementation that will be able to understand what artifact(s) are needed and get them from the ABCBuild repo.

The biggest problem I have is that if I declare

class ABCDependency implements Depenency {... }

, no repository in the project is ever asked if they have such a dependency. And if I try to extend ‘AbstractExternalDependency’, the build script won’t compile because the ‘copy()’ methods from ‘Dependency’ and ‘ExternalDependency’ interfaces clash - they have different return types.

Is there a way to tell Gradle that configured instance(s) of ‘ABCRepository’ needs to be asked to get all instances of ‘ABCDependency’? Am I missing something obvious?

Thank you !

UPD: I’m developing against Gradle 1.2, of course.

I don’t know if Gradle is currently extensible in such a way, without forking the codebase or touching lots of internals. The ‘copy’ methods of ‘Dependency’ and ‘ExternalDependency’ don’t clash. It’s a covariant return type, a feature introduced in Java 1.5.

Well, I cannot compile it with groovy-1.8.6, which comes with Gradle 1.2. My guess is that this bug [] stands in my way. It’s marked as fixed in groovy-1.8.9.

As for “touching lots of internals” (forking is really not an option right now) - I got a few questions.

  1. Is it even on the roadmap to support my use case?

  2. If I decide it’s worth it to suffer from possible incompatibility between releases and “touch lots of internals” - any pointers as to which internals I should touch? A big mystery to me so far is how a ‘DependencyDescriptor’ is being produced from a ‘Dependency’, and who and how decides that a remote repository should be asked whether it has a certain dependency or not.

Thanks a lot!

If you can’t wait for that Groovy bug to get fixed and shipped with Gradle, you can always drop down to Java (for that class).

ad 1. I expect dependency management to become more flexible and extensible over time, but I can’t say whether your use case is going to be supported. (And I don’t know much about your use case, either.)

ad 2. Unfortunately, I’m not very familiar with that part of the codebase. From what I remember, there isn’t currently a straightforward way to add new ‘Dependency’ implementations, but I may be wrong.

Thank you Peter,

From what I see after a few more hours of trying, it’s really not easy, so I’ll put it off for now.

Just for your reference, I tried to formulate my use case, it’s a valid one (at least in my company), so I hope it makes its way onto your roadmap:

As an enterprise developer, I want to be able to provide my own implementation of an external artifact repository as a Gradle plugin, enabling my coworkers to use legacy enterprise repositories with their Gradle builds. Existing legacy repositories might have their own ways of identifying artifacts, different from Maven/Ivy way (group:name:version), but they still provide the same core functionality - store and serve build artifacts and their dependencies.

Thank you!

Thanks for the suggestion. What I’ve seen in practice is that people built a proxy that allowed to access their proprietary repository as an Ivy or Maven repository.

Has anything changed about this type of extension point? Does anyone know if this use case has become any easier?