Build fails when root project includes subprojects of another multi-module project

Hi, To make life for developers easier, I’d like to replace artifact dependency for modules of another top-level project with project dependencies. Actually build script would decide if project is used or artifact should be fetched from repo:

def getProject1moduleOrArtifactDependency(String projectName, String version) {
    return gradle.project1Dir.exists() ? project(":${projectName}") : "com.sample:${projectName}:${version}"
}
dependencies {
    compile(getProject1moduleOrArtifactDependency('module1', '1.0'))
    // ...
}

I know that theoretically it is possible to include subprojects of one multi-module gradle project into another gradle project. It works if included subprojecs don’t rely on their root project, but fails for example if i have defined some variables in build.gradle of multi-module root project that is used by subproject that i want to include in another root project.

Here is an example structure of my projects:

project1
|- module1
|- module2

and another root-project:

project2

project2/settings.gradle:

File projectParentDir = settingsDir.getParentFile();
File project1Dir = new File((File)projectParentDir, "project1");
gradle.ext.project1Dir = project1Dir
if(project1Dir.exists()) {
    include 'project1', 'module1', 'module2'
    project(':project1').projectDir = project1Dir
    project(':module1').projectDir = new File(project1Dir, 'module1')
    project(':module2').projectDir = new File(project1Dir, 'module2')
}

When i add smth like following:

project1/build.gradle:

ext {
    versions = [
        lib1: 'X.Y.Z',
    ]
}

and try to use it from

project1/module1/build.gradle:

dependencies {
    compile 'com.samplegroup:lib1:' + versions.lib1
}

…then building project2 starts to fail (project1 builds fine if the build is not started from project2):

A problem occurred evaluating project ':module1'.
> Could not find property 'versions' on org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler_Decorated@7b1c1c5a.

I guess project2 doesn’t understand that when building project1/module1, then project1/build.gradle should also be used.

Is it possible to tell Gradle, that it should consult project1/build.gradle when using project1/module1/build.gradle from project2?

FYI, i got it working by splitting project1/build.gradle into several includeable build scripts that i included from project2/build.gradle (if project1Dir.exists()).

But I’m still not sure that it is correct or the easiest way - or maybe hack like this is discouraged because it might somehow bite me later (for example because of configurations done for one project through allprojects/subprojects could ruin the configuration for the other project that in non-dev environment in my case would be another independent “root-project”). What do You think?

The missing property issue sounds like a problem with evaluation ordering, although as far as I know, parent projects should be evaluated. You might try adding ‘evaluationDependsOn ‘:project1’’ to the ‘:project1:module1’ build script.

To better answer your initial question, there isn’t really a non-hackish way to accomplish this currently in Gradle. However, it looks like Daz has written up a design spec to address this exact use case.

https://github.com/gradle/gradle/blob/master/design-docs/dependency-substitution.md