With the great changes for dependency substitution, I noticed the example code for conditionally replacing projects with specified modules when the project does not exist. This is a great feature, but I think that it could be supported natively to avoid having copy/pasted code across every project that wants to support such a feature.
configurations.main.resolutionStrategy.dependencySubstitution {
// Substitute one project with a module _if_ the project does not exist
substituteAbsentProject ':core' with module('com.mycompany:core:19.0.0')
}
Relatedly, I think it also makes sense to automate the more advanced catch-all example as well:
configurations.main.resolutionStrategy.dependencySubstitution {
// Substitute any project using the project's group name and version number
substituteAbsentProjects usingProjectDetails
// Substitute any project using any group name and version number
substituteAbsentProjects withGroup project.group version project.version
// Substitute any project using the transformation given the project name
substituteAbsentProjects withTransform {
// this could get more creative, such as using maps for the version number
project.group + it + ':' project.version
}
}
Conceptually, all of these are very simple to apply. However, the implementation is not obvious to me because I do not know how to get ahold of a Project
within the DependencySubstitutions
code (it’s trivial in the examples because the Closure
s get to capture it, which is incredibly useful). If someone can point out how to get the Project
object, then I can submit a PR with these changes this weekend.
Perhaps of interest, I could also see a different approach appearing where something like OptionalComponentSelector
gets created to represent the process. Then it could exist more generically, but I expect it pushes a lot of complexity downstream for modules:
configurations.main.resolutionStrategy.dependencySubstitution {
// first ComponentSelector gets wrapped with OptionalComponentSelector
substituteIfAbsent project(':core') with module('com.mycompany:core:19.0.0')
substituteIfAbsent module('com.mycompany:xyz:19.0.0') with project(':xyz')
}
The only valid reason that I can imagine a module not existing is because it has not been published yet (e.g., a specific version that the subproject represented as a fork with a needed fix). I wanted to avoid that kind of complexity with my first example format, but I do recognize that this is even more flexible; I do think it’s more flexibility than needed though.