Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support configuration-specific dependency management with Gradle's Kotlin DSL #320

Open
feelform opened this issue Apr 6, 2022 · 2 comments

Comments

@feelform
Copy link

feelform commented Apr 6, 2022

plugins {
    `java-library`
    `maven-publish`
    id("io.spring.dependency-management")
}

repositories {
    mavenLocal()
    maven {
        url = uri("https://repo.maven.apache.org/maven2/")
    }

    maven {
        url = uri("https://jcenter.bintray.com")
    }

    maven {
        url = uri("https://repository.jboss.org/nexus/content/repositories/thirdparty-releases/")
    }
}

dependencies {
    testImplementation("junit:junit:${Versions.junit}")
    testImplementation("org.hamcrest:hamcrest:2.2")
    testImplementation("org.mockito:mockito-core:2.28.2")
}

group = "com.exampleexample"
version = "1.0.0-SNAPSHOT"

publishing {
    publications.create<MavenPublication>("maven") {
        from(components["java"])
    }
}

tasks.withType<JavaCompile>() {
    options.encoding = "UTF-8"
}

dependencyManagement {
    dependencies {
        dependency("org.springframework:spring-core:${Versions.spring}") {
            exclude("commons-logging:commons-logging")
        }
        dependency("org.springframework:spring-beans:${Versions.spring}")
        dependency("org.springframework:spring-context:${Versions.spring}")
        dependency("org.springframework:spring-orm:${Versions.spring}")
    }

    testImplementation {
        dependencies {
            dependency("org.springframework:spring-test:${Versions.spring}")
        }
    }
}

java-conventions.gradle.kts

$> ./gradlew dependencyManagement --info
java-conventions.gradle.kts: (51, 5): Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
internal fun ArtifactHandler.testImplementation(artifactNotation: Any): PublishArtifact defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun ArtifactHandler.testImplementation(artifactNotation: Any, configureAction: ConfigurablePublishArtifact.() -> Unit): PublishArtifact defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyConstraintHandler.testImplementation(constraintNotation: Any): DependencyConstraint? defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyConstraintHandler.testImplementation(constraintNotation: Any, block: DependencyConstraint.() -> Unit): DependencyConstraint? defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun <T : ModuleDependency> DependencyHandler.testImplementation(dependency: TypeVariable(T), dependencyConfiguration: TypeVariable(T).() -> Unit): TypeVariable(T) defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyHandler.testImplementation(dependencyNotation: Any): Dependency? defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyHandler.testImplementation(group: String, name: String, version: String? = ..., configuration: String? = ..., classifier: String? = ..., ext: String? = ..., dependencyConfiguration: Action<ExternalModuleDependency>? = ...): ExternalModuleDependency defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyHandler.testImplementation(dependencyNotation: String, dependencyConfiguration: Action<ExternalModuleDependency>): ExternalModuleDependency defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyHandler.testImplementation(dependencyNotation: Provider<*>, dependencyConfiguration: Action<ExternalModuleDependency>): Unit defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
internal fun DependencyHandler.testImplementation(dependencyNotation: ProviderConvertible<*>, dependencyConfiguration: Action<ExternalModuleDependency>): Unit defined in gradle.kotlin.dsl.accessors._f4124090576aed771f557cac1ca7fd48
:buildSrc:compileKotlin (Thread[Execution worker for ':buildSrc',5,main]) completed. Took 0.797 secs.

https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/#working-with-managed-versions-dependency-management-task

dependencyManagement {
    dependencies {
        dependency 'org.springframework:spring-core:4.1.5.RELEASE'
    }
    testImplementation {
        dependencies {
            dependency 'org.springframework:spring-beans:4.1.5.RELEASE'
        }
    }
}

I can't build testImplementation DSL in precompiled scripts. How can I use testImplementation likes maven test scope in dependency management?

@wilkinsona
Copy link
Contributor

Unfortunately, I don't think you can at the moment. The support is built using Groovy's method missing feature which doesn't translate correctly to the Kotlin DSL. You have two options for the time being:

  1. Use Groovy for your build scripts
  2. Declare all your dependency management globally rather than trying to make some of it configuration-specific

The second option would leave your example looking like this:

dependencyManagement {
    dependencies {
        dependency("org.springframework:spring-core:${Versions.spring}") {
            exclude("commons-logging:commons-logging")
        }
        dependency("org.springframework:spring-beans:${Versions.spring}")
        dependency("org.springframework:spring-context:${Versions.spring}")
        dependency("org.springframework:spring-orm:${Versions.spring}")
        dependency("org.springframework:spring-test:${Versions.spring}")
    }
}

As a slight aside, instead of declaring dependency management for each of Spring Framework's modules individually, you may want to consider importing org.springframework:spring-framework-bom instead.

@wilkinsona wilkinsona changed the title "testImplementation {" "Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: " error in kotlin DSL precompiled scripts Configuration-specific dependency management does not work when using the Kotlin DSL Apr 6, 2022
@pbit
Copy link

pbit commented Jan 13, 2023

A workaround is to call propertyMissing on the extension (not methodMissing as mentioned above)
This method delegates to the private method handlerForConfiguration.

Define some extension functions:

fun StandardDependencyManagementExtension.withConfiguration(name: String, action: Action<DependencyManagementHandler>) {
    (propertyMissing(name) as? DependencyManagementHandler)?.let {
        action(it)
    }
}
fun StandardDependencyManagementExtension.withConfiguration(configuration: Configuration, action: Action<DependencyManagementHandler>) {
    withConfiguration(configuration.name, action)
}

This enables management of dependencies by configuration object or name:

var configOne = configurations.create("configOne") {
    isCanBeConsumed = false
    isCanBeResolved = true
}
configurations.create("configTwo") {
    isCanBeConsumed = false
    isCanBeResolved = true
}

dependencyManagement {
    withConfiguration(configOne) {
        imports {
            mavenBom("org.springframework:spring-framework-bom:6.0.4")
        }
    }
    withConfiguration("configTwo") {
        imports {
            mavenBom("org.springframework:spring-framework-bom:6.0.4")
        }
    }
}

@wilkinsona wilkinsona changed the title Configuration-specific dependency management does not work when using the Kotlin DSL Support configuration-specific dependency management with Gradle's Kotlin DSL Nov 9, 2023
@wilkinsona wilkinsona added this to the 1.2.x milestone Nov 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants