-
Notifications
You must be signed in to change notification settings - Fork 5k
Description
Current Behavior
When Gradle resolves a dynamic selector, it attempts to find a version that matches other potential selectors.
For example, with existing versions:
1.2
,1.5
,1.8
,2.1
and with two selectors:
[1,2)
1.5
Gradle would resolve 1.5
as it is the best fit. The range alone would have resolved 1.8
.
As part of that resolution mechanism, Gradle iterates over all versions and checks their compatibility. One such check is about variants, to confirm that the selected version does have a variant that can match. But this requires downloading the metadata of the version, to resolve its variants.
Gradle also does two other checks that are local and could reject the version. But those checks are done after the check requiring the full metadata.
Expected Behavior
Move the full metadata check to be the last one done by Gradle. This can save quite a number of network requests in cases where the additional selector is not compatible with the range, like the following:
[1,2)
2.1!!
Context (optional)
There are potentially multiple layers for this fix:
- At the first level, we can change the order of the checks here:
Lines 121 to 141 in 1ec027f
RejectedByAttributesVersion maybeRejectByAttributes = tryRejectByAttributes(candidateId, metadataProvider, consumerAttributes); if (maybeRejectByAttributes != null) { result.doesNotMatchConsumerAttributes(maybeRejectByAttributes); } else if (isRejectedBySelector(candidateId, rejectedVersionSelector)) { // Mark this version as rejected result.rejectedBySelector(candidateId, rejectedVersionSelector); } else { RejectedByRuleVersion rejectedByRules = isRejectedByRule(candidateId, rules, metadataProvider); if (rejectedByRules != null) { // Mark this version as rejected result.rejectedByRule(rejectedByRules); if (requestedVersionMatcher.matchesUniqueVersion()) { // Only consider one candidate, because matchesUniqueVersion means that there's no ambiguity on the version number break; } } else { result.matches(candidateId); return; } } - At a second level, Gradle could verify if the
rejectedVersionSelector
is compatible or not with the range. And possibly, fully skip the whole fetching of versions, since none will be a match.
Note that Gradle should consider porting this fix back to 7.x as that logic has not change since then.
Self-contained Reproducer Project
N/A but will add tests with the fix
Gradle version
all
Build scan URL (optional)
No response
Your Environment (optional)
No response