gradle / gradle

Adaptable, fast automation for all
https://gradle.org
Apache License 2.0
16.91k stars 4.73k forks source link

Variant selection errors when variant appears multiple times in dependency tree #20540

Open ntvangoor opened 2 years ago

ntvangoor commented 2 years ago

Expected Behavior

Consider a component with two variants and a dependency tree that contains both of those variants once. If that tree resolves properly, adding one of those variants again generally should resolve too.

Current Behavior

When adding one of those variants again, Gradle errors with the following message:

Execution failed for task ':fails'.
> Could not resolve all files for configuration ':detachedConfiguration2'.
   > Could not resolve test.group:test0:1.
     Required by:
         project : > test.group:test2:1
      > Multiple incompatible variants of test.group:test0:1 were selected:
           - Variant test.group:test0:1 variant runtimeElements has attributes {org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.jvm.version=11, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}
           - Variant test.group:test0:1 variant shadowRuntimeElements has attributes {org.gradle.dependency.bundling=shadowed, org.gradle.status=release}

   > Could not resolve test.group:test0:1.
     Required by:
         project : > test.group:test4:1 > test.group:test3:1
      > Multiple incompatible variants of test.group:test0:1 were selected:
           - Variant test.group:test0:1 variant runtimeElements has attributes {org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.jvm.version=11, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}
           - Variant test.group:test0:1 variant shadowRuntimeElements has attributes {org.gradle.dependency.bundling=shadowed, org.gradle.status=release}

Context

I tried to resolve a dependency tree with a similar structure.

Steps to Reproduce

Following the template I created an example: https://github.com/ntvangoor/gradle-issue-variant-selection After publishing artifacts locally, the 'works' task resolves the case where the module appears twice. After that the 'fails' task tries to resolve the case where the module appears three times and errors. It seems that Github doesn't want to check Mac and Windows if Ubuntu fails...

Your Environment

Build scan URL: https://scans.gradle.com/s/szep2xe27kep6

vlsi commented 2 years ago

Could you please clarify why you omit attributes when resolving the dependencies? The point of attributes is to declare the kind of dependencies you want to be resolved, so resolving configuration without attributes looks strange

ntvangoor commented 2 years ago

For example, the com.github.johnrengelman.shadow plugin provides an extra variant: shadowRuntimeElements. If I have a dependency that wants to use that, I change the bundling attribute so that it is selected. Other dependencies might use the normal variant. Now in my project I want to only select the shadow variant if no other dependencies request the normal variant. My project does not specifically want only shadowed or normal jars.

vlsi commented 2 years ago

I see. It would really help if you could structure the reproducer in a similar way. For instance, if one of the projects exposes both "bundled dependencies" and "external dependencies", and you declare "both variations are fine, but bundled dependencies preferred", then the example, and the error message would be way easier to understand.

Reasoning about "1, 2, 3" is hard for many humans :-/

ntvangoor commented 2 years ago

I'm sorry for using numbers instead of readable values; I updated the reproducer

ov7a commented 1 year ago

Sorry for the late reply.

Thank you for your interest in Gradle!

This is a valid documentation issue that we will address.


The reproducer you provided uses only a single attribute "bundling" which would result in a conflict.

It's not a bug in Gradle. The documentation should be improved to clarify what plugin authors should do in similar cases.

ntvangoor commented 1 year ago

The result is inconsistent as far as I can see. Sometimes it resolves the variant conflict correctly and sometimes it doesn't. It depends on whether the conflict appears only once or more during graph resolution. To see the inconsistency look at the task named "works" and the task named "fails".

tresat commented 7 months ago

Improving this error message here should now be possible via https://github.com/gradle/gradle/pull/27858, I'll take a look soon.