diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e5c3212..9c0eddd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,5 +18,5 @@ jobs: distribution: 'zulu' java-version: 17 - - name: Build & Tests - run: ./gradlew build :linguine-generator:test :linguine-generator:functionalTest :linguine-runtime:allTests + - name: Detekt & Build & Tests + run: ./gradlew detekt build :linguine-generator:test :linguine-generator:functionalTest :linguine-runtime:allTests diff --git a/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileWriterTest.kt b/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileWriterTest.kt index 45da9ab..c78638c 100644 --- a/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileWriterTest.kt +++ b/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileWriterTest.kt @@ -1,11 +1,11 @@ package io.github.cleverlance.linguine.linguinegenerator import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.io.TempDir import java.io.File import java.nio.file.Path import kotlin.test.BeforeTest +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir class FileWriterTest { diff --git a/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePluginFunctionalTest.kt b/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePluginFunctionalTest.kt index 8240bf3..4609f91 100644 --- a/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePluginFunctionalTest.kt +++ b/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePluginFunctionalTest.kt @@ -1,23 +1,24 @@ package io.github.cleverlance.linguine.linguinegenerator -import org.gradle.testkit.runner.GradleRunner -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.io.TempDir import java.io.File import java.nio.file.Paths import kotlin.io.path.createTempDirectory import kotlin.test.assertTrue +import org.gradle.testkit.runner.GradleRunner +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir class LinguinePluginFunctionalTest { @TempDir lateinit var testProjectDir: File - private var buildSuccessOutput: String = "BUILD SUCCESSFUL" - private var gradleBuildFileName = "build.gradle.kts" + private val generateTaskName = "generateStrings" + private val buildSuccessOutput: String = "BUILD SUCCESSFUL" + private val gradleBuildFileName = "build.gradle.kts" @Test - fun `plugin task executes successfully`() { + fun whenGenerateTaskExecutedThenCompletedSuccessfully() { File(testProjectDir, gradleBuildFileName).apply { writeText( """ @@ -49,14 +50,15 @@ class LinguinePluginFunctionalTest { val result = GradleRunner.create() .withProjectDir(testProjectDir) .withPluginClasspath() - .withArguments("generateStrings") + .withArguments(generateTaskName) .build() assert(result.output.contains(buildSuccessOutput)) } + @Suppress("LongMethod") @Test - fun `plugin generates expected Kotlin file from JSON configuration`() { + fun whenGenerateTaskExecutedThenOutputsFileContainsExpectedContent() { testProjectDir.resolve(gradleBuildFileName).apply { writeText( """ @@ -89,7 +91,7 @@ class LinguinePluginFunctionalTest { val result = GradleRunner.create() .withProjectDir(testProjectDir) - .withArguments("generateStrings") + .withArguments(generateTaskName) .withPluginClasspath() .build() @@ -136,7 +138,7 @@ class LinguinePluginFunctionalTest { } @Test - fun `plugin generates file at specified location with correct content`() { + fun whenGenerateTaskExecutedThenOutputFilePlacedInConfiguredPath() { val testProjectDir = createTempDirectory().toFile() File(testProjectDir, "settings.gradle.kts").writeText("") @@ -173,7 +175,7 @@ class LinguinePluginFunctionalTest { val result = GradleRunner.create() .withProjectDir(testProjectDir) .withPluginClasspath() - .withArguments("generateStrings") + .withArguments(generateTaskName) .forwardOutput() .build() diff --git a/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/filereader/FileReaderTest.kt b/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/filereader/FileReaderTest.kt index 9a3286e..7817b5b 100644 --- a/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/filereader/FileReaderTest.kt +++ b/linguine-generator/src/functionalTest/kotlin/io/github/cleverlance/linguine/linguinegenerator/filereader/FileReaderTest.kt @@ -1,9 +1,9 @@ package io.github.cleverlance.linguine.linguinegenerator.filereader +import java.io.File import org.gradle.internal.impldep.junit.framework.TestCase.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir -import java.io.File class FileReaderTest { diff --git a/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileContentGenerator.kt b/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileContentGenerator.kt index 6a47a4f..e4de1d2 100644 --- a/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileContentGenerator.kt +++ b/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/FileContentGenerator.kt @@ -16,26 +16,7 @@ class FileContentGenerator( private val fileContent: Map, ) { - private companion object { - const val DEFAULT_INDENT = " " - val FORMAT_SPECIFIER_REGEX = Regex("%[0-9]*\\\$[sdf]|%[sdf]") - } - - private val filePackage: String by lazy { - fun Path.isSourceDirectory(): Boolean = isDirectory() - && (name == "kotlin" || name == "java") - && parent?.parent?.name == "src" - - var sourcePath: Path? = filePath - while (sourcePath != null && !sourcePath.isSourceDirectory()) { - sourcePath = sourcePath.parent - } - - if (sourcePath == null) return@lazy "" // no package - - val relativeDirectoryPath = filePath.parent.relativeTo(sourcePath) - relativeDirectoryPath.joinToString(separator = ".") { path -> path.name } - } + private val filePackage: String by lazy { getFilePackage(filePath) } fun generateFileContent(root: Map): String { return FileSpec.builder(filePackage, "") @@ -53,6 +34,22 @@ class FileContentGenerator( .toString() } + private fun getFilePackage(filePath: Path): String { + fun Path.isSourceDirectory(): Boolean = isDirectory() && + (name == "kotlin" || name == "java") && + parent?.parent?.name == "src" + + var sourcePath: Path? = filePath + while (sourcePath != null && !sourcePath.isSourceDirectory()) { + sourcePath = sourcePath.parent + } + + if (sourcePath == null) return "" // no package + + val relativeDirectoryPath = filePath.parent.relativeTo(sourcePath) + return relativeDirectoryPath.joinToString(separator = ".") { path -> path.name } + } + private fun TypeSpec.Builder.addObjectContent(root: Map): TypeSpec.Builder { @Suppress("UNCHECKED_CAST") // presuming the structure of the map root.forEach { (key, value) -> @@ -115,4 +112,9 @@ class FileContentGenerator( else -> Any::class } } + + private companion object { + const val DEFAULT_INDENT = " " + val FORMAT_SPECIFIER_REGEX = Regex("%[0-9]*\\\$[sdf]|%[sdf]") + } } diff --git a/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePlugin.kt b/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePlugin.kt index 6dcbd24..cd83340 100644 --- a/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePlugin.kt +++ b/linguine-generator/src/main/kotlin/io/github/cleverlance/linguine/linguinegenerator/LinguinePlugin.kt @@ -1,5 +1,7 @@ package io.github.cleverlance.linguine.linguinegenerator +import io.github.cleverlance.linguine.linguinegenerator.filereader.FileType as LinguineFileType +import org.gradle.api.provider.Property as GradleProperty import io.github.cleverlance.linguine.linguine_generator.BuildConfig import io.github.cleverlance.linguine.linguinegenerator.filereader.FileReader import org.gradle.api.DefaultTask @@ -17,17 +19,10 @@ import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.getByType import org.gradle.work.Incremental import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import io.github.cleverlance.linguine.linguinegenerator.filereader.FileType as LinguineFileType -import org.gradle.api.provider.Property as GradleProperty @Suppress("unused") class LinguinePlugin : Plugin { - private companion object { - const val GENERATE_STRINGS_TASK_NAME = "generateStrings" - const val RUNTIME_DEPENDENCY = "${BuildConfig.GROUP}:linguine-runtime:${BuildConfig.VERSION}" - } - override fun apply(project: Project) { val extension = project.extensions.create("linguineConfig", LinguineConfig::class.java) @@ -73,7 +68,6 @@ class LinguinePlugin : Plugin { configureGenerateStringsTask(project, extension) } - private fun configureForJvm(project: Project, extension: LinguineConfig) { project.dependencies { add("implementation", RUNTIME_DEPENDENCY) @@ -89,6 +83,11 @@ class LinguinePlugin : Plugin { buildTasks.forEach { task -> task.dependsOn(GENERATE_STRINGS_TASK_NAME) } } } + + private companion object { + const val GENERATE_STRINGS_TASK_NAME = "generateStrings" + const val RUNTIME_DEPENDENCY = "${BuildConfig.GROUP}:linguine-runtime:${BuildConfig.VERSION}" + } } @CacheableTask diff --git a/linguine-runtime/src/commonMain/kotlin/io/github/cleverlance/linguine/linguineruntime/presentation/LocalisationProvider.kt b/linguine-runtime/src/commonMain/kotlin/io/github/cleverlance/linguine/linguineruntime/presentation/LocalisationProvider.kt index 580c1a0..79647d8 100644 --- a/linguine-runtime/src/commonMain/kotlin/io/github/cleverlance/linguine/linguineruntime/presentation/LocalisationProvider.kt +++ b/linguine-runtime/src/commonMain/kotlin/io/github/cleverlance/linguine/linguineruntime/presentation/LocalisationProvider.kt @@ -1,9 +1,9 @@ package io.github.cleverlance.linguine.linguineruntime.presentation import co.touchlab.kermit.Logger +import kotlin.native.concurrent.ThreadLocal import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json -import kotlin.native.concurrent.ThreadLocal @ThreadLocal internal object LocalisationProvider {