Gradle cannot resolve configuration if another configuration points to a missing project

I recently found this regression in v2.5 up to v2.8. I believe it worked in v2.3.

The basic issue is that the getResolvedConfiguration method will fail if an extraneous configuration is not correctly defined. This happens in my multi-project build in cases where only a subset of projects are available. In some cases a user may only have a subset of the multi-project build due to partitioning of our code features.

Here is a code sample that demonstrates the issue:

apply plugin:'java'
repositories { mavenCentral() }
configurations { ignoreThis }

dependencies {
   compile 'commons-lang:commons-lang:2.4'
   ignoreThis project( path:':doesNotExist', configuration:'none')
}

task resolve << {
   configurations.compile.resolvedConfiguration
      .resolvedArtifacts*.moduleVersion.id
      .flatten()
      .each() { println it }
}

With settings.gradle set to:

include 'doesNotExist'

Running the build returns:

$ gradle resolve
:resolve FAILED

FAILURE: Build failed with an exception.

* Where:
Build file '/home/pcm/temp/gradleresolve/build.gradle' line: 13

* What went wrong:
Execution failed for task ':resolve'.
> Could not resolve all dependencies for configuration ':compile'.
   > Configuration with name 'none' not found.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.314 secs

The resolve task should ignore the doesNotExist since it is not referenced in the compile configuration.

Interesting. As of Gradle 2.5, we changed the way we create a LocalComponentMetadata for a project: previously we were doing this via an Ivy ModuleDescriptor and now we are building it directly. I guess we started being more strict about valid configurations at the same time.

I’d like to know more about your use case: perhaps there’s a better way to support it than having an invalid configuration defined in your project.

Daz, thanks for clearing that up. It was a nice feature before since with a large code base a developer could work with a partial set of gradle projects and run the build. Now this use case does not always work and is pretty common practice with an SCM tool like Perforce.

I put in a workaround for the instances were a sub-project might not exist in the local file system. Maybe this will help anyone else out.

def findExistingProjects = { Collection projects ->
    projects.findAll { file(it.dependencyProject.projectDir).exists() }
}

dependencies {
    findExistingProjects([project( path:':doesNotExist', configuration:'none'),]).each { ignoreThis it }
}