[GRADLE-2017] Tooling API: Avoid incorrect dependency scope merge Created: 28/Dec/11  Updated: 02/Apr/14  Resolved: 02/Apr/14

Status: Resolved
Project: Gradle
Affects Version/s: 1.0-milestone-6, 1.0-milestone-7
Fix Version/s: 1.12-rc-1

Type: Bug
Reporter: Denis Zhdanov Assignee: Radim Kubacki
Resolution: Fixed Votes: 6


There is a possible case that the same dependency is mapped to the following standard java dependency configurations - 'testCompile' and 'runtime'. That means that we want to achieve the following:

  • don't have the dependency at the classpath during the sources compilation
  • do have the dependency at the classpath during the test compilation;
  • do have the dependency at the classpath during executing the classes from the source set;

Gradle tooling api returns single dependency for such a situation. It's scope is 'runtime'. That is incorrect because of inability to compile test sources at the project based on that information.

I see the following solutions:

  • return two dependencies, one with the scope 'test', another one with the scope 'runtime';
  • change org.gradle.tooling.model.idea.IdeaDependency.getScope() in order to return set of scopes (basically, IDE part will do what is suggested above - create more than one dependency if it's not possible to merge the scopes);

Comment by Szczepan Faber [ 16/Jan/12 ]

Looks like a bug. I'm wondering if the *.iml also incorrectly generated if one uses vanilla idea plugin.

Comment by Vladislav Soroka [ 22/Oct/13 ]

It's blocking this IntelliJ Gradle feature: http://youtrack.jetbrains.com/issue/IDEA-79209

Comment by Radim Kubacki [ 21/Feb/14 ]

I'm going to take a look how to fix this. Just to make sure what we want to achieve:
assuming there is a Gradle project with dependencies like

dependencies {
  compile project(':api')
  testCompile project(':impl'), 'junit:junit:4.11'
  runtime project(':impl')

we want to make sure that IdeaModule.getDependencies() will return dependencies where it is possible to see that :impl is used with TEST and RUNTIME scope. If we run 'gradle idea' for this module there will be two entries:

    <orderEntry type="module" module-name="impl" exported="" scope="RUNTIME" />
    <orderEntry type="module" module-name="impl" exported="" scope="TEST" />

BTW: I don't know how to set this up from the UI but it works if I edit .iml file by hand.

Similar should be done for all types of dependencies (module-libraries too).

Comment by Radim Kubacki [ 22/Feb/14 ]

At the moment it seems to me that current computation of TEST scope is not accurate: http://www.gradle.org/docs/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html describes that

TEST -> project.configurations.testRuntime - project.configurations.runtime

while it seems to me that we would need

TEST -> project.configurations.testRuntime - project.configurations.runtime + project.configurations.testCompile - project.configurations.compile

I can try that but need to find a way how to make it compatible with current Map<String, Map<String, Collection<Configuration>>> scopes definition.

Comment by Vladislav Soroka [ 24/Feb/14 ]

for the following dependencies defined in Gradle scripts:

dependencies {
  compile project(':api')
  testCompile project(':impl'), 'junit:junit:4.11'
  runtime project(':impl')

I'm expecting the next entries in the .iml file:

    <orderEntry type="library" scope="TEST" name="Gradle: junit-4.11" level="project" />
    <orderEntry type="library" scope="TEST" name="Gradle: hamcrest-core-1.3" level="project" />
    <orderEntry type="module" module-name="api" exported="" />
    <orderEntry type="module" module-name="impl" scope="TEST" />
    <orderEntry type="module" module-name="impl" exported="" scope="RUNTIME" />

This is how it currently works in IDEA but using internal API (IdeDependenciesExtractor).
Would be cool to have it by default, thanks for looking into this Radim.

Generated at Wed Jun 30 12:10:32 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.