ben-manes / gradle-versions-plugin

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

Question: can the built-in component selection rule be cleared? #573

Open martinda opened 2 years ago

martinda commented 2 years ago

I am getting this message for all my dependencies:

Selection of com.domain:moduleName:1.2.3-branchName rejected by component selection rule: Component status integration rejected by revision milestone

The ivy.xml of all my dependencies has this form:

<ivy-module version="2.0">
    <info organisation="com.domain" module="moduleName" revision="1.2.3-branchName" status="integration" publication="20211207123001"/>
    <configurations>
        <conf name="all" visibility="public" extends="a,b"/>
        <conf name="a" visibility="public"/>
        <conf name="b" visibility="public"/>
    </configurations>
    <publications>
        <artifact name="moduleName" type="zip" ext="zip" conf="a" m:classifier="a"/>
        <artifact name="moduleName" type="zip" ext="zip" conf="b" m:classifier="b"/>
    </publications>
    <dependencies>
        <dependency rev="5.6.7-otherBranch" org="com.domain" name="dep1" conf="a"/>
    </dependencies>
</ivy-module>

I think the addRevisionFilter method is the cause of the rejection.

Q1: Is it possible to clear the component selection rule and accept all? Q2: How can I replace the rule without editing the source, is there a DSL? Q3: How do I change the ivy.xml to make it work?

Thanks in advance.

ben-manes commented 2 years ago

Does the following work?

gradle dependencyUpdates -Drevision=integration

This plugin was written for Gradle 1.0, which was built on top of Ivy. The only option we had was to use Ivy's latest.$revision feature to query. The default was milestone to ignore maven -SNAPSHOT versions. Later on Gradle wrote its own dependency management logic, added component selection rules, and we dropped support for ancient build versions. That rule is for feature compatibility but generally isn't a great approach given the flexibility of resolution strategies. By using integration it should be disabled and you can set it in your task configuration.

martinda commented 2 years ago

It gets further but it gives a really strange error message with -Drevision=integration :

The exception that is the cause of unresolved state: org.gradle.internal.resolve.ModuleVersionResolveException: Could not resolve com.domain:dep1:+.
Required by:
    project :
Caused by: org.gradle.internal.component.model.ConfigurationNotFoundException: Project : declares a dependency from configuration 'aCopy2' to configuration 'default' which is not declared in the descriptor for com.domain:dep1:5.6.7-otherBranch.

It looks like it copied the a configuration to aCopy2. I don't know where that comes from. My memory is vague wrt the default configuration.

ben-manes commented 2 years ago

We use use Configuration.copyRecursive() to clone the configuration and manipulate the dependency's version to a dynamic + resolution. That was originally a detached configuration, but we encountered bugs in Gradle's RepositoryHandler which favored touching as little as possible. When a configuration is copied it gets a Copy and number assigned by the build tool.

I don't have experience with Ivy, but I think there is a conflict because the dependency declares the configuration it targets. When cloned and the dependency's conf doesn't match the configuration.name then the resolver detects that as a misconfiguration. That would hint towards modifying the dependency's setTargetConfiguration to match the copy when it is added.

If you'd like to debug this and provide a PR, the development iteration is pretty simple. Increment the version, make some changes, and publish to your local maven repository. In your test project you can use mavenLocal() to resolve to your new version and iterate. There might be a way to reference as a composite build, but it's not too slow of a dev loop. Alternatively you could add a test following the examples, but I don't recall finding that as easy for debugging purposes. If interested then I can help you debug through this.

martinda commented 2 years ago

Thank you @ben-manes . When I have a chance I will look into the details and see if I can come up with something.

lenntt commented 1 year ago

It looks like it copied the a configuration to aCopy2. I don't know where that comes from. My memory is vague wrt the default configuration.

I've seen this behavior too, the problem there seemed to be the gradle demon, killing it, changed my errors into different ones (#794)

ben-manes commented 1 year ago

I think this is likely your fix as well but someone would need to debug and try it out.

That would hint towards modifying the dependency's setTargetConfiguration to match the copy when it is added.