Kotlin-dsl-samples: Constraints result in dependencies being added instead of constraints

Created on 7 Feb 2018  Â·  8Comments  Â·  Source: gradle/kotlin-dsl-samples

When I write the following code:

dependencies {
    constraints {
        "implementation"("com.google.collections:google-collections") {
            version {
                rejectAll()
            }
            because("Google collections is superceded by Guava")
        }
    }
}

The expectation is that what is added is a _constraint_. However, it turns out to be adding a _dependency_ instead. If I use the very same file in Groovy, a constraint is added.

Expected Behavior

Extensions methods should be aware of the constraints block.

Current Behavior

Constraints are created as hard dependencies, breaking the dependency graph.

bug kotlin-dsl-api dogfood

All 8 comments

Workaround:

dependencies {
    constraints {
        add("implementation", "com.google.collections:google-collections") {
            version {
                rejectAll()
            }
            because("Google collections is superceded by Guava")
        }
    }
}

@eskatos Do you have some grand solution for this problem in general or is it just to add the API in Kotlin every time issues like this arise in the API.

@JLLeitschuh no, no grand solution atm 😄 Ad-hoc API additions is the easy way forward. But putting some thinking on this first sounds good. If something comes to you, please share.

Annotating the Gradle core API and doing code generation at DSL build time popped into my head.

Just got bitten by this. The worst bit IMO is that it works but does something really different.
Is that something planned for a future (soon) release?

I see that this issue is still open. It's a pretty serious bug, is this planned for 1.0?

A bit more details about the situation. Let's look at different usage scenario:

plugins {
    `java-library`
}

// #1 - Using the API
dependencies {
    constraints {
        add("implementation", "com.google.collections:google-collections") {
            version { rejectAll() }
            because("Google collections is superceded by Guava")
        }
    }
}

// #2 - Using existing configuration accessors
dependencies {
    constraints {
        implementation("com.google.collections:google-collections") {
            version { rejectAll() }
            because("Google collections is superceded by Guava")
        }
    }
}

// #3 - Using existing configuration accessors out of the dependencies {} block
dependencies.constraints {
    implementation("com.google.collections:google-collections") {
        version { rejectAll() }
        because("Google collections is superceded by Guava")
    }
}

// #4 - Using string invoke operator
dependencies {
    constraints {
        "implementation"("com.google.collections:google-collections") {
            version { rejectAll() }
            because("Google collections is superceded by Guava")
        }
    }
}

// #5 - Using string invoke operator out of the dependencies {} block
dependencies.constraints {
    "implementation"("com.google.collections:google-collections") {
        version { rejectAll() }
        because("Google collections is superceded by Guava")
    }
}

With Gradle 4.10.x

  • #1 works ✅
  • #2 compiles cleanly but adds a dependency instead of a constraint, thats the original reported issue
    This happens because the generated implementation extension on the outer DependencyHandler is available in constraints {} and no such equivalent extension is generated for DependencyConstraintHandler
  • #3doesn't compile because no such implementation extension is available in DependencyConstraintHandler, see #2
  • #4 is just like #2 but for the string invoke syntax
  • #5 is just like #3 but for the string invoke syntax

With #1091

There's nothing more we can do specifically for dependency constraints.

Closing in favor of https://github.com/gradle/kotlin-dsl/issues/1119 and https://github.com/gradle/kotlin-dsl/issues/1120.

Was this page helpful?
0 / 5 - 0 ratings