@Dumitru, the use case you have (use a project dependency if the project is checked out, otherwise use an external dependency) is something we want to add to Gradle. However, we probably wouldn’t implement it how you’ve described.
Conceptually, there are a few steps involved in going from a dependency declaration to some actual files to compile against:
- Convert the dependency notation to a Dependency implementation, at configuration time. This is what the notation parser does. 2. Convert the Dependency to a module selector, at resolve time. 3. Apply the module selector to each repositories, and choose the best match.
I would do the substitution in step 2, rather than step 1. There are a couple of reasons for this. Firstly, we don’t necessarily know which projects are involved at configuration time, and secondly, it means that the original declaration is retained. This is important for later generating the meta-data descriptor when the project is published.
Another thing I would do differently is to avoid mixing both the project and module identifiers in the dependency declaration. Instead, I would separate the declaration of the dependency from the substitution. So, you would do this:
compile project: 'other'
And have some other mechanism to tell Gradle: when you resolve a dependency on project ‘other’, replace it with a dependency on group: ‘org.myorg’, module: ‘other’, version: ‘1.2’.
Implementation-wise, I would generalise the force stuff on ResolutionStrategy (as forcing is a special case of substitution), perhaps with a callback that, given a dependency, can add/change/remove the dependency.