Skip to content

Commit

Permalink
Implement kotlin version checks and kotlin jvm plugin apply in our gr…
Browse files Browse the repository at this point in the history
…adle plugin (#252)
  • Loading branch information
chippmann authored Aug 19, 2021
1 parent 2f431c0 commit 5ffb1f9
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 28 deletions.
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ nav:
- Advanced:
- Custom src dirs: user-guide/advanced/custom-src-dirs.md
- Custom gradle wrapper path: user-guide/advanced/custom_gradle_wrapper_path.md
- Gradle plugin configuration: user-guide/advanced/gradle-plugin-configuration.md
- Commandline args: user-guide/advanced/commandline-args.md
- Kotlin singletons: user-guide/advanced/kotlin-singleton.md
- GraalVM native-image: user-guide/advanced/graal-vm-native-image.md
Expand Down
5 changes: 5 additions & 0 deletions docs/src/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ If you find bugs, please report an [issue on github](https://github.com/utopia-r
## Supported languages
The only language currently supported is Kotlin. That said it is possible to support other Jvm based languages in the future. If you want to add support for another Jvm based language, feel free to open an [issue](https://github.com/utopia-rise/godot-kotlin-jvm/issues) and we'll explain in detail what is necessary to support another language and help you getting started with development.

## Supported kotlin version
This module relies on a kotlin compiler plugin for registering your classes and members to godot. As the compiler api from kotlin is not yet stable, we can only support specific kotlin version per release for now.

The current latest release is compatible with kotlin version `1.5.21`.

## Custom engine builds
Get our pre built engine builds and export templates from the latest [github release](https://github.com/utopia-rise/godot-kotlin-jvm/releases).

Expand Down
12 changes: 12 additions & 0 deletions docs/src/doc/user-guide/advanced/gradle-plugin-configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Disable build failure on kotlin version mismatch
As we're using a kotlin compiler plugin to register your code with godot, we can only support a specific kotlin version per release. This is due to the fact that the kotlin compiler plugin api is not stable yet.

But if you are familiar with the quirks of compiler plugins and their compatibility and you need to use another kotlin version than we officially support, you can disable the version checks we have in place in our gradle plugin. To do this you have to set `godot.jvm.suppressKotlinIncompatibility` to `true` in the `gradle.properties` file:

=== "gradle.properties"
```
godot.jvm.suppressKotlinIncompatibility=true
```

!!! warning
This is an advanced feature! Only use it if you know what you're doing. We cannot guarantee that our compiler plugin is compatible with other kotlin versions than the one we build it for. Setting this property to true can lead to build and/or runtime errors.
3 changes: 2 additions & 1 deletion harness/tests/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
kotlin("jvm") version "1.5.21"
// no need to apply kotlin jvm plugin. Our plugin already applies the correct version for you
// kotlin("jvm") version "1.5.21"
id("com.utopia-rise.godot-kotlin-jvm")
}

Expand Down
4 changes: 4 additions & 0 deletions harness/tests/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
org.gradle.jvmargs=-Xmx3G

# Set this property to true to disable kotlin jvm plugin version check
# Attention: this is an advanced feature. Only use it if you know what you're doing! We cannot guarantee that our compiler plugin is compatible with other kotlin versions than the one we build it for. Setting this property to true can lead to build and/or runtime errors.
#godot.jvm.suppressKotlinIncompatibility=true
1 change: 1 addition & 0 deletions kt/buildSrc/src/main/kotlin/DependenciesVersions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ object DependenciesVersions {
const val shadowJarPluginVersion: String = "6.1.0"
const val kotlinPoetVersion: String = "1.8.0"
const val kspVersion: String = "1.5.21-1.0.0-beta05"
const val supportedKotlinVersion: String = "1.5.21"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package godot.gradle
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import com.google.devtools.ksp.gradle.KspExtension
import com.google.devtools.ksp.gradle.KspGradleSubplugin
import godot.utils.GodotBuildProperties
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.plugins.ide.idea.IdeaPlugin
import org.gradle.plugins.ide.idea.model.IdeaModel
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
import java.io.File


Expand All @@ -19,6 +21,36 @@ class GodotPlugin : Plugin<Project> {
target.pluginManager.apply(IdeaPlugin::class.java) //needed so idea can find and index the generated sources from ksp
target.pluginManager.apply(ShadowPlugin::class.java)

val kotlinPlugin = target.plugins.findPlugin(KotlinPluginWrapper::class.java)
val kotlinPluginVersion = target
.buildscript
.configurations
.firstOrNull { it.name == "classpath" }
?.dependencies
?.firstOrNull { it.name == "org.jetbrains.kotlin.jvm.gradle.plugin" }
?.version

val isSuppressingKotlinIncompatibility = (target.findProperty("godot.jvm.suppressKotlinIncompatibility") as? String)?.toBoolean() ?: false

if (!isSuppressingKotlinIncompatibility) {
target.logger.info("Kotlin plugin already applied: ${kotlinPlugin != null}; detected version: ${kotlinPluginVersion ?: "none"}")

when {
kotlinPlugin != null && kotlinPluginVersion != null && kotlinPluginVersion != GodotBuildProperties.supportedKotlinVersion -> throw IllegalArgumentException(
"Detected that a kotlin plugin with version $kotlinPluginVersion is already applied. But Godot-Kotlin is only compatible with kotlin ${GodotBuildProperties.supportedKotlinVersion}, please change the version to ${GodotBuildProperties.supportedKotlinVersion}"
)
kotlinPlugin == null && kotlinPluginVersion != null && kotlinPluginVersion != GodotBuildProperties.supportedKotlinVersion -> throw IllegalArgumentException(
"Detected that kotlin plugin version $kotlinPluginVersion is already defined. But Godot-Kotlin is only compatible with kotlin ${GodotBuildProperties.supportedKotlinVersion}, please change the version to ${GodotBuildProperties.supportedKotlinVersion}"
)
kotlinPlugin == null && kotlinPluginVersion == null || kotlinPluginVersion == GodotBuildProperties.supportedKotlinVersion -> {
target.pluginManager.apply("org.jetbrains.kotlin.jvm") // the version will be the one with which this plugin was built
}
}
} else {
// warn is not really visible enough in the log. As this is a very important print, error is used to print it more visible
target.logger.error("Found property \"godot.jvm.suppressKotlinIncompatibility\" is set to \"true\". This is an advanced feature! Only use it if you know what you're doing. We cannot guarantee that our compiler plugin is compatible with other kotlin version that ${GodotBuildProperties.supportedKotlinVersion} (found version: $kotlinPluginVersion). Setting this property to true can lead to build and/or runtime errors.")
}

val godotExtension = target.extensions.create("godot", GodotExtension::class.java)
val kotlinJvmExtension = target
.extensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class GodotModuleBuilder : ModuleBuilder(), ModuleBuilderListener {
private val groupIdKey = Key<String>("GROUP_ID")
private val artifactIdKey = Key<String>("ARTIFACT_ID")
private val versionKey = Key<String>("VERSION")
private val kotlinVersionKey = Key<String>("KOTLIN_VERSION")
private val androidEnabledKey = Key<Boolean>("ANDROID_ENABLED")
private val d8ToolPathKey = Key<String>("D8_TOOL_PATH")
private val androidCompileSdkDirKey = Key<String>("ANDROID_COMPILE_SDK_DIR")
Expand Down Expand Up @@ -59,7 +58,6 @@ class GodotModuleBuilder : ModuleBuilder(), ModuleBuilderListener {
val groupIdTextField = JTextField("com.example")
val artifactIdTextField = JTextField("game")
val versionTextField = JTextField("0.0.1-SNAPSHOT")
val kotlinVersionTextField = JTextField("1.4.32")
lateinit var androidEnabledCheckBox: JCheckBox
lateinit var d8ToolPathTextField: TextFieldWithBrowseButton
lateinit var androidCompileSdkDirTextField: TextFieldWithBrowseButton
Expand All @@ -77,13 +75,6 @@ class GodotModuleBuilder : ModuleBuilder(), ModuleBuilderListener {
versionTextField().growPolicy(GrowPolicy.MEDIUM_TEXT)
}
}
if (wizardContext.isCreatingNewProject) {
titledRow(GodotPluginBundle.message("wizard.projectSettings.dependencySettings.title")) {
row(GodotPluginBundle.message("wizard.projectSettings.dependencySettings.kotlinVersion")) {
kotlinVersionTextField().growPolicy(GrowPolicy.MEDIUM_TEXT)
}
}
}
titledRow(GodotPluginBundle.message("wizard.projectSettings.buildSettings.title")) {
row(GodotPluginBundle.message("wizard.projectSettings.buildSettings.androidEnabled")) {
checkBox("", false).apply { androidEnabledCheckBox = this.component }
Expand Down Expand Up @@ -129,7 +120,6 @@ class GodotModuleBuilder : ModuleBuilder(), ModuleBuilderListener {
context.putUserData(groupIdKey, groupIdTextField.text)
context.putUserData(artifactIdKey, artifactIdTextField.text)
context.putUserData(versionKey, versionTextField.text)
context.putUserData(kotlinVersionKey, kotlinVersionTextField.text)
context.putUserData(androidEnabledKey, androidEnabledCheckBox.isSelected)
context.putUserData(d8ToolPathKey, d8ToolPathTextField.text)
context.putUserData(androidCompileSdkDirKey, androidCompileSdkDirTextField.text)
Expand All @@ -154,7 +144,6 @@ class GodotModuleBuilder : ModuleBuilder(), ModuleBuilderListener {
outFile.writeText(
outFile
.readText()
.replace("KOTLIN_VERSION", wizardContext.getUserData(kotlinVersionKey) ?: "1.4.32")
.replace(
"GODOT_KOTLIN_JVM_VERSION",
GodotBuildProperties.godotKotlinVersion
Expand Down Expand Up @@ -206,17 +195,6 @@ class GodotModuleBuilder : ModuleBuilder(), ModuleBuilderListener {
"id(\"com.utopia-rise.godot-kotlin-jvm\") version \"${GodotBuildProperties.godotKotlinVersion}\""
)
}
if (module.parentProjectAlreadyContainsDependency(wizardContext, "kotlin-stdlib")) {
content.replace(
"KOTLIN_DEPENDENCY",
"kotlin(\"jvm\")"
)
} else {
content.replace(
"KOTLIN_DEPENDENCY",
"kotlin(\"jvm\") version \"${wizardContext.getUserData(kotlinVersionKey) ?: "1.4.32"}\""
)
}
}
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
plugins {
KOTLIN_DEPENDENCY
GODOT_KOTLIN_DEPENDENCY
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
plugins {
kotlin("jvm") version "KOTLIN_VERSION"
id("com.utopia-rise.godot-kotlin-jvm") version "GODOT_KOTLIN_JVM_VERSION"
}

Expand Down
3 changes: 2 additions & 1 deletion kt/utils/godot-build-props/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ tasks {
val processResources by getting(Copy::class) {
outputs.upToDateWhen { false }
val tokens = mapOf(
"version" to version.toString()
"version" to version.toString(),
"kotlin.version" to DependenciesVersions.supportedKotlinVersion
)
from("src/main/resources") {
include("*.properties")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ object GodotBuildProperties {
val godotKotlinVersion by lazy {
buildProperties["godot.jvm.version"] as String
}
}

val supportedKotlinVersion by lazy {
buildProperties["godot.jvm.kotlin.version"] as String
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
godot.jvm.version=@version@
godot.jvm.version=@version@
godot.jvm.kotlin.version[email protected]@

0 comments on commit 5ffb1f9

Please sign in to comment.