Reputation: 814
I have a Gradle build which produces the main deliverable artifact (an installer) of my product. The Gradle project which models this has a number of different dependencies in different configurations. Many of those dependencies are on the default configuration of external modules, and some of those modules have a testResults
configuration that contains the (zipped) results of the test task.
It's important that those test results for all dependencies, where they exist, be published as artifacts of the main product build (to use as evidence that testing took place and was successful). It's not an issue if they don't exist.
I tried to do this by iterating over all configurations of the product build, iterating over the dependencies in each and adding a programmatically created dependency (in a new configuration created for this purpose) on the testResults
configuration of the module.
In other words, I create dependencies like this:
def processDependencyForTests( Dependency dependency ) {
def testResultsDependency = [
'group' : dependency.group,
'name' : dependency.name,
'version' : dependency.version,
'configuration' : 'testResults'
]
project.dependencies.add 'allTestResults', testResultsDependency
This populates that configuration just fine, but of course when I try to do anything with it, it fails the first time I encounter a dependency on a module that doesn't actually have a testResults
configuration:
def resolvedConfiguration = configurations.allTestResults.resolvedConfiguration
Results in this:
Build file 'C:\myproduct\build.gradle' line: 353
* What went wrong:
Execution failed for task ':myproduct:createBuildRecord'.
> Could not resolve all dependencies for configuration ':myproduct:allTestResults'.
> Module version group:mygroup, module:myproduct, version:1.2.3.4, configuration:allTestResults declares a dependency on configuration 'testResults' which is not declared in the module descriptor for group:mygroup, module:mymodule, version:1.0
It's not really practical to instead explicitly list the dependencies in a declarative fashion, because I want them to be derived from "whatever real dependencies the product project has".
How can I ensure that such expected missing configurations don't derail my build? I thought something to do with lenient configurations might be the answer, but I haven't even got that far here (I need to get a ResolvedConfiguration
first, as far as I can tell). Alternatively, if the way I'm doing this is insane, what's a more natural Gradle idiom to achieve this?
Upvotes: 12
Views: 4652
Reputation: 4434
It seems implied that Dependency
instances passed to your processDependencyForTests
method are module dependencies in a multi-modules build.
In this case you could cast them to ProjectDependency which has a dependencyProject
property that will allow you to reach the Project
object of that dependency. From there you can use depProject.configurations.findByName
to test if the configuration exists.
Something along the lines of:
def processDependencyForTests( Dependency dependency ) {
if( dependency instanceof ProjectDependency ) {
ProjectDependency projDep = (ProjectDependency) dependency
if( projDep.dependencyProject.configurations.findByName( 'testResults' ) ) {
def testResultsDependency = [
'group' : dependency.group,
'name' : dependency.name,
'version' : dependency.version,
'configuration' : 'testResults'
]
project.dependencies.add 'allTestResults', testResultsDependency
}
}
HTH
Upvotes: 0
Reputation: 5950
You'll need to check for the existence of the configuration before referencing it. In cases like this, the gradle DSL documentation is your friend. In fact, the gradle project is one of the most well-documented open source projects I've ever worked with.
Here, you'll find that configurations
is simply a container of configuration
objects. They are instances of ConfigurationContainer and Configuration respectively. Knowing this, all you need to do is to check whether the configurations
container contains a configuration
named "testResults".
This can be achieved by the following code:
if (configurations.find { it.name == 'testResults' }) {
// do your stuff
}
Upvotes: 5