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

Remove embedded-kotlin-repo and pin Kotlin dependencies with constraints #10701

Merged
merged 14 commits into from
Sep 17, 2019
Merged
2 changes: 0 additions & 2 deletions subprojects/docs/src/docs/userguide/kotlin_dsl.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -711,8 +711,6 @@ The plugin achieves this by doing the following:

* Applies the link:https://kotlinlang.org/docs/reference/using-gradle.html#targeting-the-jvm[Kotlin Plugin], which adds support for compiling Kotlin source files.
* Adds the `kotlin-stdlib-jdk8`, `kotlin-reflect` and `gradleKotlinDsl()` dependencies to the `compileOnly` and `testImplementation` configurations, which allows you to make use of those Kotlin libraries and the Gradle API in your Kotlin code.
+
All three libraries and their dependencies are bundled with Gradle, so these dependencies will not result in any downloads.
* Configures the Kotlin compiler with the same settings that are used for Kotlin DSL scripts, ensuring consistency between your build logic and those scripts.
* Enables support for <<kotdsl:precompiled_plugins,precompiled script plugins>>.

Expand Down
16 changes: 15 additions & 1 deletion subprojects/docs/src/docs/userguide/upgrading_version_5.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,24 @@ Additionally, the following deprecated functionality now results in an error:

==== `AbstractCompile.compile()` is gone

The abstrace method `compile()` is no longer declared by `AbstractCompile`.
The abstract method `compile()` is no longer declared by `AbstractCompile`.
Tasks extending `AbstractCompile` can implement their own `@TaskAction` method with the name of their choosing.
They are also free to add a `@TaskAction` method with an `InputChanges` parameter without having to implement a parameter-less one as well.

==== Using the `embedded-kotlin` plugin now requires a repository

Just like when using the `kotlin-dsl` plugin, it is now required to declare a repository where Kotlin dependencies can be found if you apply the `embedded-kotlin` plugin.

```kotlin
plugins {
`embedded-kotlin`
}

repositories {
jcenter()
}
```

==== Kotlin DSL IDE support now requires Kotlin IntelliJ Plugin >= 1.3.50

With Kotlin IntelliJ plugin versions prior to 1.3.50, Kotlin DSL scripts will be wrongly highlighted when the _Gradle JVM_ is set to a version different from the one in _Project SDK_.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ class GradleKotlinDslIntegrationTest : AbstractPluginIntegrationTest() {
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript {
repositories {
jcenter()
}
$repositoriesBlock
dependencies {
classpath(kotlin("gradle-plugin", version = "$differentKotlinVersion"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.gradle.integtests.fixtures.RepoScriptBlockUtil.jcenterRepository
import org.gradle.kotlin.dsl.fixtures.FoldersDsl
import org.gradle.kotlin.dsl.fixtures.FoldersDslExpression
import org.gradle.kotlin.dsl.fixtures.containsMultiLineString
import org.gradle.plugin.management.internal.autoapply.AutoAppliedBuildScanPlugin
import org.gradle.test.fixtures.dsl.GradleDsl

import org.gradle.test.fixtures.file.LeaksFileHandles
Expand All @@ -29,7 +30,6 @@ import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.not
import org.hamcrest.MatcherAssert.assertThat

import org.junit.Ignore
import org.junit.Test

import java.io.File
Expand Down Expand Up @@ -712,7 +712,6 @@ class ProjectSchemaAccessorsIntegrationTest : AbstractPluginIntegrationTest() {
}

@Test
@Ignore("TODO: change this test not to be dependent on an old version of the build-scan plugin")
fun `given extension with inaccessible type, its accessor is typed Any`() {

withFile("init.gradle", """
Expand All @@ -721,7 +720,7 @@ class ProjectSchemaAccessorsIntegrationTest : AbstractPluginIntegrationTest() {
gradlePluginPortal()
}
dependencies {
classpath "com.gradle:build-scan-plugin:1.16"
classpath "com.gradle:build-scan-plugin:${AutoAppliedBuildScanPlugin.VERSION}"
eskatos marked this conversation as resolved.
Show resolved Hide resolved
}
}
rootProject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ plugins {
description = "Kotlin DSL Gradle Plugins deployed to the Plugin Portal"

group = "org.gradle.kotlin"
version = "1.2.12"
version = "1.3.2"

base.archivesBaseName = "plugins"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class EmbeddedKotlinPluginTest : AbstractPluginTest() {
`embedded-kotlin`
}
$repositoriesBlock
""")

val result = build("assemble")
Expand All @@ -61,6 +63,8 @@ class EmbeddedKotlinPluginTest : AbstractPluginTest() {
configurations {
create("compileOnlyClasspath") { extendsFrom(configurations["compileOnly"]) }
}
$repositoriesBlock
tasks {
register("assertions") {
Expand All @@ -81,36 +85,36 @@ class EmbeddedKotlinPluginTest : AbstractPluginTest() {
}

@Test
fun `all embedded kotlin dependencies are resolvable without any added repository`() {
fun `all embedded kotlin dependencies are resolvable`() {

withBuildScript("""
plugins {
`embedded-kotlin`
}
$repositoriesBlock
dependencies {
${dependencyDeclarationsFor(
"implementation",
listOf("compiler-embeddable", "scripting-compiler-embeddable", "scripting-compiler-impl-embeddable")
)}
}
println(repositories.map { it.name })
configurations["compileClasspath"].files.map { println(it) }
""")

val result = build("dependencies")

assertThat(result.output, containsString("Embedded Kotlin Repository"))
listOf("stdlib", "reflect", "compiler-embeddable", "scripting-compiler-embeddable", "scripting-compiler-impl-embeddable").forEach {
assertThat(result.output, containsString("kotlin-$it-$embeddedKotlinVersion.jar"))
}
}

@Test
fun `sources and javadoc of all embedded kotlin dependencies are resolvable with an added repository`() {
fun `sources and javadoc of all embedded kotlin dependencies are resolvable`() {

withBuildScript("""
Expand Down Expand Up @@ -175,6 +179,8 @@ class EmbeddedKotlinPluginTest : AbstractPluginTest() {
`embedded-kotlin`
}
$repositoriesBlock
val customConfiguration by configurations.creating
customConfiguration.extendsFrom(configurations["embeddedKotlin"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import javax.inject.Inject
* The `embedded-kotlin` plugin.
*
* Applies the `org.jetbrains.kotlin.jvm` plugin,
* adds compile only dependencies on `kotlin-stdlib` and `kotlin-reflect`,
* configures an embedded repository that contains all embedded Kotlin libraries.
* adds compile only and test implementation dependencies on `kotlin-stdlib` and `kotlin-reflect`.
*/
class EmbeddedKotlinPlugin @Inject internal constructor(
private val embeddedKotlin: EmbeddedKotlinProvider
Expand All @@ -49,8 +48,6 @@ class EmbeddedKotlinPlugin @Inject internal constructor(

logger.warnOnDifferentKotlinVersion(getKotlinPluginVersion())

embeddedKotlin.addRepositoryTo(repositories)

val embeddedKotlinConfiguration = configurations.create("embeddedKotlin")
embeddedKotlin.addDependenciesTo(
dependencies,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class PrecompiledScriptPluginModelCrossVersionSpec extends AbstractKotlinScriptM
}
}
$repositoriesBlock
dependencies {
implementation(files("${implementationDependency.name}"))
}
Expand Down Expand Up @@ -108,6 +110,8 @@ class PrecompiledScriptPluginModelCrossVersionSpec extends AbstractKotlinScriptM
plugins {
`kotlin-dsl`
}
$repositoriesBlock
""")

and:
Expand Down Expand Up @@ -135,6 +139,8 @@ class PrecompiledScriptPluginModelCrossVersionSpec extends AbstractKotlinScriptM
`kotlin-dsl`
}
$repositoriesBlock
dependencies {
implementation(files("${jar.name}"))
}
Expand Down
39 changes: 38 additions & 1 deletion subprojects/kotlin-dsl/kotlin-dsl.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import build.futureKotlin
import build.kotlin
import build.kotlinVersion
import codegen.GenerateKotlinDependencyExtensions
import org.gradle.build.ReproduciblePropertiesWriter

plugins {
`kotlin-dsl-module`
Expand Down Expand Up @@ -110,7 +111,7 @@ dependencies {
// --- Enable automatic generation of API extensions -------------------
val apiExtensionsOutputDir = layout.buildDirectory.dir("generated-sources/kotlin")

val publishedKotlinDslPluginVersion = "1.2.11" // TODO:kotlin-dsl
val publishedKotlinDslPluginVersion = "1.3.1" // TODO:kotlin-dsl

tasks {

Expand Down Expand Up @@ -143,3 +144,39 @@ tasks {
from(writeVersionsManifest)
}
}


// -- Embedded Kotlin dependencies -------------------------------------

val embeddedKotlinBaseDependencies by configurations.creating

dependencies {
embeddedKotlinBaseDependencies(futureKotlin("stdlib-jdk8"))
embeddedKotlinBaseDependencies(futureKotlin("reflect"))
}

val writeEmbeddedKotlinDependencies by tasks.registering {
val outputFile = layout.buildDirectory.file("embeddedKotlinDependencies/gradle-kotlin-dsl-embedded-kotlin.properties")
inputs.files(embeddedKotlinBaseDependencies)
outputs.file(outputFile)
doLast {

val skippedModules = setOf(project.name, "distributionsDependencies", "kotlinCompilerEmbeddable")

val modules = embeddedKotlinBaseDependencies.incoming.resolutionResult.allComponents
.asSequence()
.mapNotNull { it.moduleVersion }
.filter { it.name !in skippedModules }
.associate { "${it.group}:${it.name}" to it.version }

ReproduciblePropertiesWriter.store(
modules,
outputFile.get().asFile.apply { parentFile.mkdirs() },
null
)
}
}

tasks.processResources {
from(writeEmbeddedKotlinDependencies)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.gradle.kotlin.dsl.embeddedKotlinVersion
import org.gradle.kotlin.dsl.fixtures.AbstractKotlinIntegrationTest

import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.not
import org.hamcrest.MatcherAssert.assertThat

import org.junit.Test
Expand All @@ -21,57 +22,79 @@ class EmbeddedKotlinProviderTest : AbstractKotlinIntegrationTest() {
}

@Test
fun `buildscript dependencies to embedded kotlin are resolved without an extra repository`() {
fun `embedded kotlin dependencies are pinned to the embedded version`() {

withBuildScript("""
buildscript {
$repositoriesBlock
dependencies {
classpath("org.jetbrains.kotlin:kotlin-stdlib:$embeddedKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-reflect:$embeddedKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-compiler-embeddable:$embeddedKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-script-runtime:$embeddedKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin:$embeddedKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-stdlib:1.0")
classpath("org.jetbrains.kotlin:kotlin-reflect:1.0")
}
}
""")

val result = build("buildEnvironment")

listOf("stdlib", "reflect", "compiler-embeddable", "script-runtime", "sam-with-receiver-compiler-plugin").forEach { module ->
assertThat(result.output, containsString("org.jetbrains.kotlin:kotlin-$module:$embeddedKotlinVersion"))
listOf("stdlib", "reflect").forEach { module ->
assertThat(result.output, containsString("org.jetbrains.kotlin:kotlin-$module:1.0 -> $embeddedKotlinVersion"))
}
}

@Test
fun `stdlib and reflect are pinned to the embedded kotlin version`() {
fun `stdlib and reflect are pinned to the embedded kotlin version for requested plugins`() {
withBuildScript("""
buildscript {
dependencies {
classpath("org.jetbrains.kotlin:kotlin-stdlib:1.0")
classpath("org.jetbrains.kotlin:kotlin-reflect:1.0")
}
plugins {
kotlin("jvm") version "1.3.31"
}
""")

val result = build("buildEnvironment")

listOf("stdlib", "reflect").forEach { module ->
assertThat(result.output, containsString("org.jetbrains.kotlin:kotlin-$module:1.0 -> $embeddedKotlinVersion"))
assertThat(result.output, containsString("org.jetbrains.kotlin:kotlin-$module:1.3.31 -> $embeddedKotlinVersion"))
}
}

@Test
fun `compiler-embeddable is not pinned`() {
withBuildScript("""
buildscript {
$repositoriesBlock
dependencies {
classpath("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.31")
}
}
""")

val result = build("buildEnvironment")

assertThat(result.output, containsString("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.31"))
assertThat(result.output, not(containsString("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.31 ->")))
}

@Test
fun `fails with a reasonable message on conflict with embedded kotlin`() {
withBuildScript("""
buildscript {
$repositoriesBlock
dependencies {
classpath("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.0")
classpath("org.jetbrains.kotlin:kotlin-stdlib") {
version { strictly("1.3.31") }
}
}
}
""")

val result = buildAndFail("buildEnvironment")

assertThat(result.error, containsString("Could not find org.jetbrains.kotlin:kotlin-compiler-embeddable:1.0"))
assertThat(
result.error,
containsString("Cannot find a version of 'org.jetbrains.kotlin:kotlin-stdlib' that satisfies the version constraints")
)
assertThat(
result.error,
containsString("because of the following reason: Pinned to the embedded Kotlin")
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ sealed class ResidualProgram {
sealed class Instruction {

/**
* Causes the configuration of the embedded Kotlin repository and embedded Kotlin libraries
* Causes the configuration of the embedded Kotlin libraries
* on the host's ScriptHandler.
*/
object SetupEmbeddedKotlin : Instruction()
Expand Down