Resolve "external" dependecy as project when present


(Andreas Nyberg) #1

Let’s say I have a dependency “X:Y:1.2.3” that is developed by few and usually treated as an external dependency. I bring it into my branch and want to treat it as a subproject “X:Y”, where “X” is the name of my root project. Other subprojects in my project still refer to it as an external dependency.

How can I make the external dependency resolve to my subroject when I have it in my projecty, without adding the project dependency directly and tweaking the declaration every dependency that might transitively bring in the external one?


(René Groeschke) #2

Hello, gradle does not support his out of the box. To achieve that, you have to generate the subprojects included in your multiproject dynamically within your settings.gradle file and add a new dependency type. There is an example project available at https://github.com/pniederw/elastic-deps. It creates a project dependency if the project folder exists, otherwise it creates an external dependency.

hope this helps.

cheers, René


(Michael Brand) #3

Could you use the local Maven repository cache for this? Basically, create your repository list so that you look first in the Maven cache for the jar, and then to a project-wide repository.

Then set up the dependencies as Rene suggests. Have settings.gradle include your subproject only if the folder exists. Finally, you’ll need to add a dependsOn to compileJava that publishes the X:Y jar if the project exists.

settings.gradle

if (new File("Y").with{exists() && isDirectory()}) {
   include 'Y'
}

build.gradle

if (findProject("X:Y")) {
   compileJava {
       dependsOn 'X:Y:publish'
   }
}

You’ll also probably want to do some magic with versions so that you’re using snapshot versions when using the local cache for X:Y.

I haven’t tested this, so it may not work. But that’s where I’d start.


(René Groeschke) #4

I don’t understand what you try to achieve with this block:

if (findProject("X:Y")) {
   compileJava {
       dependsOn 'X:Y:publish'
   }
}

if project X:Y exists you would just use a project dependency if not you would use a “external” dependency. In the sample project we created a method called “elastic” for that kind of declaration:

dependencies {
  compile elastic("mycompany:sub3:1.0", "sub3")
}

How the external dependencies are resolved is up to you. you can use a remote repository or the local maven repository. Normally you would use an external repository, because normally you just want to use the artifacts created and published by your ci machine instead of dealing with the whole subproject.

cheers, René


(Michael Brand) #5

Your method of using a simple if/then statement for setting up the dependency is probably cleaner than using the Maven cache. I’m looking at using the local cache for a similar situation where I need the “Y” artifact to survive a “clean” and that’s why it came to mind.

The compileJava dependency was based on the assumption that we use the local Maven cache. Without having looked it up, I believe that the “dependsOn” is required to ensure that the “Y” artifact has been pushed to the cache before attempting to compile the project code.

But it sounds like your example is the better solution.


(Matt Khan) #6

I tackled this by adding an ‘internals’ extension, described it in http://forums.gradle.org/gradle/topics/handling_projects_coupled_at_configuration_time