ben-manes / gradle-versions-plugin

Gradle plugin to discover dependency updates
Apache License 2.0
3.85k stars 199 forks source link

Cannot find new versions for dependencies in `allprojects` #321

Open boris-petrov opened 5 years ago

boris-petrov commented 5 years ago

Not sure if the title is right. I have the following in my main build.gradle file:

plugins {
    id 'checkstyle'
}

allprojects {
    apply plugin: 'checkstyle'

    dependencies {
        checkstyle 'com.puppycrawl.tools:checkstyle:8.23'
    }
}

Running gradle dependencyUpdates leads to:

Failed to determine the latest version for the following dependencies (use --info for details):
 - com.puppycrawl.tools:checkstyle
     8.23

Not sure why. Any ideas?

ben-manes commented 5 years ago

Try adding mavenCentral as a repository. Gradle handles tools in magical ways, as you usually use toolVersion to set the implicit dependency. There might be other dependency apis we should be reporting on, like default dependencies, but not sure of these things.

boris-petrov commented 5 years ago

@ben-manes - thanks for the answer! Here is a complete reproduction:

In build.gradle:

plugins {
    id 'checkstyle'
    id 'com.github.ben-manes.versions' version '0.22.0'
}

repositories {
    mavenCentral()
    jcenter()
}

allprojects {
    apply plugin: 'checkstyle'

    dependencies {
        checkstyle 'com.puppycrawl.tools:checkstyle:8.23'
    }
}

I've added repositories as you requested - the same thing happens without it.

In settings.gradle:

include 'sub'

This is the important part. If you remove this file/comment-out that line - the versions plugin works fine:

The following dependencies are using the latest milestone version:
 - com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.22.0
 - com.puppycrawl.tools:checkstyle:8.23

With that line included (without even a sub directory actually being there) - the output is:

The following dependencies are using the latest milestone version:
 - com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.22.0

Failed to determine the latest version for the following dependencies (use --info for details):
 - com.puppycrawl.tools:checkstyle
     8.23
ben-manes commented 5 years ago

What is the exception in the —info log? Ideally someday the Gradle team takes this feature over as we get exposed to weird internal hacks sometimes...

boris-petrov commented 5 years ago

@ben-manes - the error, I think, is The exception that is the cause of unresolved state: Cannot resolve external dependency com.puppycrawl.tools:checkstyle:+ because no repositories are defined..

ben-manes commented 5 years ago

Good, just wanted to be sure. You need to specify repositories in the all projects block, too.

boris-petrov commented 5 years ago

@ben-manes - thanks! That did the trick. Is this a gradle-versions-plugin "bug" or a Gradle one or it's not a bug at all? I'll leave you to close the issue if this is normal behavior. Thanks again!

ben-manes commented 5 years ago

Gradle has "hidden" dependencies via tools. They expect you to use,

checkstyles {
  toolVersion = '8.23'
}

That has an implicit dependencies and repository, hidden from the normal APIs. In your version, you are adding a declared dependency that we can discover in their APIs, but the repository is implicit. We use the Configuration#copy() method to clone and rewrite the version, and somehow this implicit repository is lost. It is all very magical and I don't know if we can do anything intelligent. It really should be a Gradle engineer deciding on that code, since we might have to rely on internal assumptions only they can be sure about.

I have been of the opinion, since originally writing this plugin around ~1.x, that the Gradle team should own this feature. It really is basic dependency management and uses their APIs to do the work, anyway. That doesn't answer your question, except to keep prodding them to take ownership someday. 😄

boris-petrov commented 5 years ago

@ben-manes - well, until the Gradle guys become supportive enough and implement that, we'll have to do with your great plugin here. :)

I tried the following:

plugins {
    id 'checkstyle'
    id 'com.github.ben-manes.versions' version '0.22.0'
}

allprojects {
    apply plugin: 'checkstyle'

    checkstyle {
        toolVersion = '8.23'
    }
}

But it still doesn't work:

The following dependencies are using the latest milestone version:
 - com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.22.0

Failed to determine the latest version for the following dependencies (use --info for details):
 - com.puppycrawl.tools:checkstyle
The exception that is the cause of unresolved state: Cannot resolve external dependency com.puppycrawl.tools:checkstyle:8.23 because no repositories are defined.

Am I misusing toolVersion somehow or do I need to put repositories in allprojects after all?

ben-manes commented 5 years ago

No, any Gradle tool is hidden from us in weird ways. Their repository is not visible to the normal Gradle APIs.

You would always have to specify the repository in your projects. The tool's repository is lost in the configuration.copyRecursive(), I suppose. We copy, then modify the dependencies to use +, we then call copy.resolvedConfiguration.lenientConfiguration.getFirstLevelModuleDependencies(). We don't touch the configuration's repositories, which are set by Gradle. In the copy, the hidden repository from the tool is dropped. Therefore it fails because Gradle has nothing to look up into.

The Gradle bug is that the copy() method doesn't carry over this tool repository. Since tools are handled uniquely by Gradle, I honestly have no clue what their expectations are.

ben-manes commented 5 years ago

If you look at Resolver.groovy, you'll see it is a bit messy but not doing anything super intelligent. It just calls are few Gradle APIs, gets the results, and hands that off to be reported on.

Tools do weird things, like have dependencies not in the original listings but show up in the resolved set. Its a pre-1.0 feature, actually. The easiest is just to include all repositories in your projects.

boris-petrov commented 5 years ago

This is a bit too deep for me, I don't know Gradle that good. :)

I don't want to take up much of your time so - is this a known bug/issue/feature-request for Gradle? If not, would you like me to open something there or you're going to do it? Or is it something you've discussed with them and they just don't want to/can't listen? :)

ben-manes commented 5 years ago

I’m a bit inactive on this project, so other than a little cheap talk here I haven’t driven anything with the Gradle team lately. I’ve asked them to take ownership someday and they agreed, as long as it’s never today.

If someone wants to add proper tool version support later on, they may figure the answer to this oddity. Otherwise I think it would stay in the backlog of both projects as the workaround is trivial.

boris-petrov commented 5 years ago

OK, fair enough. Thank you for the great support! I'll leave you to decide whether to close the issue or leave it as a reference. Thanks again!