nebula-plugins / gradle-dependency-lock-plugin

A plugin to allow people using dynamic dependency versions to lock them to specific versions.
Apache License 2.0
293 stars 43 forks source link

Locked dependencies in a multiproject not recognized when specified in rootproject #126

Open islandsvinur opened 7 years ago

islandsvinur commented 7 years ago

It seems that if a dependency is specified in the rootProject, it isn't recognized by the dependency-lock-plugin.

I have created a minimal example project to illustrate: https://github.com/islandsvinur/nebula-dependency-lock-failure I'm using Mockito as an example here because it releases very frequently.

How to test

The command I run to check which version of the dependency is used is:

$ gradle dependencyInsightEnhanced --configuration compile --dependency org.mockito:mockito-core

Expected behavior

For islandsvinur/nebula-dependency-lock-failure@390896485fee3d0e7e3da8975949debd37f99d65 this produces:

:dependencyInsightEnhanced
org.mockito:mockito-core:2.9.0 (locked to 2.9.0 by global.lock)

org.mockito:mockito-core:2.+ -> 2.9.0
\--- compile

nebula.dependency-lock locked with: global.lock

BUILD SUCCESSFUL in 3s
1 actionable task: 1 executed

Actual behavior

For islandsvinur/nebula-dependency-lock-failure@420605d1a6c9572cec0a203fb81dc00b3c1ccf95 this produces:

:dependencyInsightEnhanced
org.mockito:mockito-core:2.10.0

org.mockito:mockito-core:2.+ -> 2.10.0
\--- compile

nebula.dependency-lock locked with: global.lock

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

Conclusion

The Mockito dependency in both commits is locked to 2.9.0. The only difference between those two commits is that the sub project now also specifies the org.mockito:mockito-core:2.+ dependency.

It seems that the plugin does not recognize the lock it produced if the dependency is in the rootProject.

islandsvinur commented 7 years ago

Gradle 4.2

rspieldenner commented 7 years ago

Please try applying the dependency-lock plugin to the subproject

islandsvinur commented 7 years ago

For islandsvinur/nebula-dependency-lock-failure@d4792fc970f2250afeb57b60c37f0a5161c2c56a the dependencyInsight produces:

:dependencyInsightEnhanced
org.mockito:mockito-core:2.10.0

org.mockito:mockito-core:2.+ -> 2.10.0
\--- compile

nebula.dependency-lock locked with: global.lock
:sub:dependencyInsightEnhanced
No dependencies matching given input were found in configuration ':sub:compile'

BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed

Applying the plugin to allprojects does not seem to help, but also in this case adding the dependency to the subproject does. However, it introduces a failure, see islandsvinur/nebula-dependency-lock-failure@8617477f6aea9d372ee3fdde85d5a632119df722:

:dependencyInsightEnhanced
org.mockito:mockito-core:2.9.0 (locked to 2.9.0 by global.lock)

org.mockito:mockito-core:2.+ -> 2.9.0
\--- compile

nebula.dependency-lock locked with: global.lock
:sub:dependencyInsightEnhanced
org.mockito:mockito-core:2.9.0 (locked to 2.9.0 by global.lock) FAILED

org.mockito:mockito-core:2.+ -> 2.9.0 FAILED
\--- compile

nebula.dependency-lock locked with: global.lock

BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
islandsvinur commented 7 years ago

So now we have four cases:

X Plugin applied to rootproject Plugin applied to allprojects
Dependency defined on rootproject islandsvinur/nebula-dependency-lock-failure@420605d1a6c9572cec0a203fb81dc00b3c1ccf95 islandsvinur/nebula-dependency-lock-failure@d4792fc970f2250afeb57b60c37f0a5161c2c56a
Dependency defined on subproject islandsvinur/nebula-dependency-lock-failure@390896485fee3d0e7e3da8975949debd37f99d65 islandsvinur/nebula-dependency-lock-failure@8617477f6aea9d372ee3fdde85d5a632119df722

Of those, the dependencyInsight shows only the correct versions for the Dependency defined on subproject ones. Only the one that defines the plugin on the rootproject builds, the other one fails, even though the 2.9.0 is downloaded earlier during the build:

[...]
Download https://repo1.maven.org/maven2/org/mockito/mockito-core/2.9.0/mockito-core-2.9.0.pom
Download https://repo1.maven.org/maven2/org/mockito/mockito-core/2.9.0/mockito-core-2.9.0.jar
[...]
:sub:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all files for configuration ':sub:compileClasspath'.
> Could not find org.mockito:mockito-core:2.9.0.
  Required by:
      project :sub

The problem is, I cannot declare the dependency on the subproject. In my actual project, the subproject is a library depending on interfaces (e.g. servlet-api) and the rootproject is the launcher project depending on implementations of those interfaces (e.g. jetty).

haoming-ahoy commented 6 years ago

@DanielThomas @rspieldenner I am facing same issue. The reproduce is easier compared to the above description. I have a sample root project and a sub project. In the root project I declared one dependency that is not declared in sub project. I am expecting it shows up in the global section of the global.lock file, but it does not. I have applied dependency-lock plugin using allprojects. This could be an issue when we have source code in root project as well, so it does not really take all projects into consideration when generating the global graph.

As you can see from the below example, I am expecting to see com.googlecode.objectify:objectify to show up in the global section.

Another experience I have tried is to declare guava 22 in root project, and guava 18 in sub project, I am hoping to see guava 22 in _global_section but actually saw guava 18 in global section. This could be an issue when the source code in root project depends on features in new guava 22.

root project build.gradle

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "com.netflix.nebula:gradle-dependency-lock-plugin:5.0.4"
    }
}

group 'learning'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'idea'

dependencies {
    compile "com.googlecode.objectify:objectify:5.1.5"

    compile 'com.google.guava:guava:21.0'
    compile group: 'org.apache.commons', name: 'commons-math3', version: '3.3'

    testCompile group: 'junit', name: 'junit', version: '4.12'
}

allprojects {
    apply plugin: "nebula.dependency-lock"
}

sub project build.gradle file:

apply plugin: 'java'
apply plugin: 'idea'

sourceCompatibility = 1.8

dependencies {
    compile 'com.google.guava:guava:18.0'
    compile group: 'org.apache.commons', name: 'commons-math3', version: '3.1'
}