From 608ccae160e6e7898a12e5b44bb7d1a44e91c797 Mon Sep 17 00:00:00 2001 From: Stefan Koppier Date: Thu, 2 Jan 2025 10:34:57 +0100 Subject: [PATCH] Automatically apply the mappie dependency via the Gradle plugin (#149) --- README.md | 2 +- .../objects/NoVisibleConstructorTest.kt | 2 + gradle-plugin/.gitignore | 2 +- gradle-plugin/build.gradle.kts | 8 +- .../kotlin/tech/mappie/MappieGradlePlugin.kt | 18 ++-- .../kotlin/tech/mappie/MappieProperties.kt | 12 +++ .../kotlin/tech/mappie/testing/TestBase.kt | 84 ++++++++++++++----- .../gradle/Gradle812CompatibilityTest.kt | 13 +++ .../MultiplatformCompatibilityTest.kt | 54 ++++++++++++ gradle.properties | 2 +- website/src/changelog.md | 4 + .../getting-started/posts/installation.md | 3 +- 12 files changed, 165 insertions(+), 39 deletions(-) create mode 100644 gradle-plugin/src/main/kotlin/tech/mappie/MappieProperties.kt create mode 100644 gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/gradle/Gradle812CompatibilityTest.kt create mode 100644 gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/multiplatform/MultiplatformCompatibilityTest.kt diff --git a/README.md b/README.md index bdd55d72..10b19739 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ plugins { id("tech.mappie.plugin") version "x.y.z" } ``` -The `mappie-api` dependency must be added to the `build.gradle.kts` file for the programming interface +When using the plugin before version `1.0.0`, the `mappie-api` dependency must be added to the `build.gradle.kts` file for the programming interface ```kotlin dependencies { implementation("tech.mappie:mappie-api:x.y.z") diff --git a/compiler-plugin/src/test/kotlin/tech/mappie/testing/objects/NoVisibleConstructorTest.kt b/compiler-plugin/src/test/kotlin/tech/mappie/testing/objects/NoVisibleConstructorTest.kt index eae32f9d..358d2d6a 100644 --- a/compiler-plugin/src/test/kotlin/tech/mappie/testing/objects/NoVisibleConstructorTest.kt +++ b/compiler-plugin/src/test/kotlin/tech/mappie/testing/objects/NoVisibleConstructorTest.kt @@ -8,6 +8,8 @@ import java.io.File class NoVisibleConstructorTest { data class Input(val name: String) + + @ConsistentCopyVisibility data class Output private constructor(val name: String) @TempDir diff --git a/gradle-plugin/.gitignore b/gradle-plugin/.gitignore index c049a048..be76dcb9 100644 --- a/gradle-plugin/.gitignore +++ b/gradle-plugin/.gitignore @@ -1 +1 @@ -src/main/resources/version.properties \ No newline at end of file +src/main/resources/mappie.properties \ No newline at end of file diff --git a/gradle-plugin/build.gradle.kts b/gradle-plugin/build.gradle.kts index afb84c48..a17279ec 100644 --- a/gradle-plugin/build.gradle.kts +++ b/gradle-plugin/build.gradle.kts @@ -24,17 +24,17 @@ gradlePlugin { } } -tasks.register("updateCompilerPluginVersion") { +tasks.register("updateMappieProperties") { group = "build" - description = "Update version.properties file for Gradle plugin." + description = "Update mappie.properties file for Gradle plugin." doLast { val directory = project.mkdir("src/main/resources") - File(directory, "version.properties").writeText("version=${project.version}") + File(directory, "mappie.properties").writeText("VERSION=${project.version}") } } tasks.compileKotlin { - dependsOn("updateCompilerPluginVersion") + dependsOn("updateMappieProperties") } tasks.test { diff --git a/gradle-plugin/src/main/kotlin/tech/mappie/MappieGradlePlugin.kt b/gradle-plugin/src/main/kotlin/tech/mappie/MappieGradlePlugin.kt index a819865d..7b9f6724 100644 --- a/gradle-plugin/src/main/kotlin/tech/mappie/MappieGradlePlugin.kt +++ b/gradle-plugin/src/main/kotlin/tech/mappie/MappieGradlePlugin.kt @@ -3,8 +3,8 @@ package tech.mappie import org.gradle.api.Project import org.gradle.api.provider.Provider import org.jetbrains.kotlin.gradle.plugin.* -import java.util.* +@Suppress("unused") class MappieGradlePlugin : KotlinCompilerPluginSupportPlugin { override fun apply(target: Project) { @@ -16,6 +16,10 @@ class MappieGradlePlugin : KotlinCompilerPluginSupportPlugin { with (kotlinCompilation.project) { logger.info("Mappie plugin ${getPluginArtifact().version} applied") + kotlinCompilation.dependencies { + implementation(dependencies.create("tech.mappie:mappie-api:${getPluginArtifact().version}")) + } + val extension = extensions.getByType(MappieExtension::class.java) return provider { buildList { @@ -42,18 +46,10 @@ class MappieGradlePlugin : KotlinCompilerPluginSupportPlugin { SubpluginArtifact( groupId = "tech.mappie", artifactId = "mappie-compiler-plugin", - version = javaClass.classLoader.getResourceAsStream("version.properties").use { - Properties().apply { load(it) }.getProperty("version") - }, + version = MappieProperties.version, ) - override fun isApplicable(kotlinCompilation: KotlinCompilation<*>) = - kotlinCompilation.target.project.run { - hasMappiePlugin() - } - - private fun Project.hasMappiePlugin() = - plugins.hasPlugin(MappieGradlePlugin::class.java) + override fun isApplicable(kotlinCompilation: KotlinCompilation<*>) = true private fun Project.checkCompatibility() { val version = getKotlinPluginVersion() diff --git a/gradle-plugin/src/main/kotlin/tech/mappie/MappieProperties.kt b/gradle-plugin/src/main/kotlin/tech/mappie/MappieProperties.kt new file mode 100644 index 00000000..f2e7df6b --- /dev/null +++ b/gradle-plugin/src/main/kotlin/tech/mappie/MappieProperties.kt @@ -0,0 +1,12 @@ +package tech.mappie + +import java.util.Properties + +object MappieProperties { + + private val properties = javaClass.classLoader.getResourceAsStream("mappie.properties").use { + Properties().apply { load(it) } + } + + val version = properties["VERSION"] as String +} \ No newline at end of file diff --git a/gradle-plugin/src/test/kotlin/tech/mappie/testing/TestBase.kt b/gradle-plugin/src/test/kotlin/tech/mappie/testing/TestBase.kt index 5f4ad402..7046ac55 100644 --- a/gradle-plugin/src/test/kotlin/tech/mappie/testing/TestBase.kt +++ b/gradle-plugin/src/test/kotlin/tech/mappie/testing/TestBase.kt @@ -8,6 +8,8 @@ import org.junit.jupiter.api.io.TempDir import java.io.File import java.util.* +enum class KotlinPlatform { JVM, MULTIPLATFORM } + abstract class TestBase { @TempDir @@ -15,6 +17,8 @@ abstract class TestBase { protected lateinit var runner: GradleRunner + protected open val platform: KotlinPlatform = KotlinPlatform.JVM + protected open val gradleVersion: String? = null protected open val kotlinVersion = "2.1.0" @@ -27,10 +31,6 @@ abstract class TestBase { gradleVersion?.let { withGradleVersion(gradleVersion) } } - directory.resolve("src/main/kotlin").mkdirs() - directory.resolve("src/main/java").mkdirs() - directory.resolve("src/test/kotlin").mkdirs() - gradleVersion?.let { println("Using Gradle version $it") } println("Using Kotlin version $kotlinVersion") @@ -45,22 +45,44 @@ abstract class TestBase { """.trimIndent() ) + when (platform) { + KotlinPlatform.JVM -> jvm() + KotlinPlatform.MULTIPLATFORM -> multiplatform() + } + } + + protected fun kotlin(file: String, @Language("kotlin") code: String) { + directory.resolve(file).apply { + appendText(code) + } + } + + protected fun java(file: String, @Language("java") code: String) { + directory.resolve(file).apply { + appendText(code) + } + } + + private fun jvm() { + directory.resolve("src/main/kotlin").mkdirs() + directory.resolve("src/main/java").mkdirs() + directory.resolve("src/test/kotlin").mkdirs() + kotlin("build.gradle.kts", """ plugins { id("org.jetbrains.kotlin.jvm") version "$kotlinVersion" id("tech.mappie.plugin") version "$version" } + repositories { + mavenLocal() + mavenCentral() + } dependencies { - implementation("tech.mappie:mappie-api:$version") testImplementation(kotlin("test")) } - repositories { - mavenLocal() - mavenCentral() - } tasks.test { useJUnitPlatform() @@ -73,21 +95,43 @@ abstract class TestBase { ) } - protected fun kotlin(file: String, @Language("kotlin") code: String) { - directory.resolve(file).apply { - appendText(code) - } - } + private fun multiplatform() { + directory.resolve("src/commonMain/kotlin").mkdirs() + directory.resolve("src/commonTest/kotlin").mkdirs() + directory.resolve("src/jvmMain/kotlin").mkdirs() - protected fun java(file: String, @Language("java") code: String) { - directory.resolve(file).apply { - appendText(code) - } + kotlin("build.gradle.kts", + """ + plugins { + id("org.jetbrains.kotlin.multiplatform") version "$kotlinVersion" + id("tech.mappie.plugin") version "$version" + } + + repositories { + mavenLocal() + mavenCentral() + } + + kotlin { + applyDefaultHierarchyTemplate() + + sourceSets { + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + } + } + } + + jvm() + } + """.trimIndent() + ) } companion object { - private val version = javaClass.classLoader.getResourceAsStream("version.properties").use { - Properties().apply { load(it) }.getProperty("version") + private val version = javaClass.classLoader.getResourceAsStream("mappie.properties").use { + Properties().apply { load(it) }.getProperty("VERSION") } @BeforeAll diff --git a/gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/gradle/Gradle812CompatibilityTest.kt b/gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/gradle/Gradle812CompatibilityTest.kt new file mode 100644 index 00000000..ea515b33 --- /dev/null +++ b/gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/gradle/Gradle812CompatibilityTest.kt @@ -0,0 +1,13 @@ +package tech.mappie.testing.compatibility.gradle + +import org.junit.jupiter.api.Test + +class Gradle812CompatibilityTest : GradleCompatibilityTestBase() { + + override val gradleVersion = "8.12" + + @Test + fun `test compatibility with gradle 8_12`() { + runner.withArguments("build").build() + } +} \ No newline at end of file diff --git a/gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/multiplatform/MultiplatformCompatibilityTest.kt b/gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/multiplatform/MultiplatformCompatibilityTest.kt new file mode 100644 index 00000000..7a7691a6 --- /dev/null +++ b/gradle-plugin/src/test/kotlin/tech/mappie/testing/compatibility/multiplatform/MultiplatformCompatibilityTest.kt @@ -0,0 +1,54 @@ +package tech.mappie.testing.compatibility.multiplatform + +import org.junit.jupiter.api.Test +import tech.mappie.testing.KotlinPlatform +import tech.mappie.testing.TestBase + +class MultiplatformCompatibilityTest : TestBase() { + + override val platform = KotlinPlatform.MULTIPLATFORM + + @Test + fun `test compatibility with multiplatform`() { + kotlin("src/commonMain/kotlin/CommonMapper.kt", + """ + import tech.mappie.api.ObjectMappie + + data class CommonInput(val string: String) + data class CommonOutput(val string: String) + + object CommonMapper : ObjectMappie() + """.trimIndent() + ) + + kotlin("src/commonTest/kotlin/CommonMapperTest.kt", + """ + import kotlin.test.* + + class CommonMapperTest { + + @Test + fun `map CommonInput to CommonOutput`() { + assertEquals( + CommonOutput("value"), + CommonMapper.map(CommonInput("value")), + ) + } + } + """.trimIndent() + ) + + kotlin("src/jvmMain/kotlin/JvmMapper.kt", + """ + import tech.mappie.api.ObjectMappie + + data class JvmInput(val string: String, val int: Int) + data class JvmOutput(val string: String, val int: Int) + + object JvmMapper : ObjectMappie() + """.trimIndent() + ) + + runner.withArguments("build").build() + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 717b5c46..17d8cab9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=0.10.0 \ No newline at end of file +version=0.11.0-SNAPSHOT \ No newline at end of file diff --git a/website/src/changelog.md b/website/src/changelog.md index 286439b4..6bfd1908 100644 --- a/website/src/changelog.md +++ b/website/src/changelog.md @@ -2,6 +2,10 @@ title: "Changelog" layout: "layouts/changelog.html" changelog: + - date: "tbd" + title: "v1.0.0" + items: + - "[#148](https://github.com/Mr-Mappie/mappie/issues/148) the `mappie-api` dependency is now applied automatically." - date: "2024-12-15" title: "v0.10.0" items: diff --git a/website/src/posts/getting-started/posts/installation.md b/website/src/posts/getting-started/posts/installation.md index 1a3aa223..d640da2d 100644 --- a/website/src/posts/getting-started/posts/installation.md +++ b/website/src/posts/getting-started/posts/installation.md @@ -30,7 +30,8 @@ plugin. We can apply Mappie by adding the following plugin to the Gradle build f {% endraw %} -The `mappie-api` dependency must be added to the Gradle build file file for the programming interface +When using mappie version below `1.0.0` or when you want to add the `mappie-api` dependency manually, +the `mappie-api` dependency can be added as follows {% raw %}