Skip to content

Commit

Permalink
Merge pull request #10701 from gradle/eskatos/kotlin-dsl/no-embedded-…
Browse files Browse the repository at this point in the history
…kotlin-repo

Remove embedded-kotlin-repo and pin Kotlin dependencies with constraints
  • Loading branch information
eskatos committed Sep 17, 2019
2 parents 809b6b0 + bad68ed commit a2b7c7d
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 226 deletions.
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}"
}
}
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

0 comments on commit a2b7c7d

Please sign in to comment.