From 1dc5cad9430f74beb787b8c675ca05ac88c9d723 Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 13:12:55 -0400 Subject: [PATCH 1/9] Generate translation keys as enum class overrides instead of members --- build.gradle.kts | 1 - buildSrc/src/main/kotlin/Versions.kt | 7 +- trikot-kword/kword-plugin/build.gradle.kts | 9 +- .../com.mirego.kword/KWordEnumGenerate.kt | 85 +++++++++++++++++++ .../kotlin/com.mirego.kword/KWordPlugin.kt | 19 +++++ .../kotlin/com.mirego.kword/KwordExtension.kt | 38 +++++++++ .../com/mirego/kword/KwordEnumGenerateTest.kt | 18 ++++ trikot-kword/sample/ios/Podfile.lock | 8 +- .../build.gradle.kts | 2 +- .../common/TRIKOT_FRAMEWORK_NAME.podspec | 2 +- 10 files changed, 171 insertions(+), 18 deletions(-) create mode 100644 trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt create mode 100644 trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt create mode 100644 trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt create mode 100644 trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 5657e512..488c6359 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,4 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile val samplesEnabled = !extra.has("disable_samples") diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index ef093c8c..00d1e35b 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -15,12 +15,13 @@ object Versions { const val ANDROIDX_LIFECYCLE = "2.8.2" const val OKIO = "3.9.0" const val KSP = "2.0.0-1.0.21" - const val KOTLIN_POET = "1.17.0" + const val KOTLIN_POET = "1.18.1" const val ACCOMPANIST = "0.34.0" + const val COMPILE_TESTING_KSP = "1.6.0" object Android { - const val TARGET_SDK = 34 - const val COMPILE_SDK = 34 + const val TARGET_SDK = 35 + const val COMPILE_SDK = 35 const val MIN_SDK = 21 } const val JVM_TOOLCHAIN = 17 diff --git a/trikot-kword/kword-plugin/build.gradle.kts b/trikot-kword/kword-plugin/build.gradle.kts index 59f1ba3d..4c0fe8bb 100644 --- a/trikot-kword/kword-plugin/build.gradle.kts +++ b/trikot-kword/kword-plugin/build.gradle.kts @@ -1,17 +1,10 @@ plugins { - id("groovy") + kotlin("jvm") id("mirego.publish") } -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - } -} - dependencies { implementation(gradleApi()) - implementation(localGroovy()) implementation("com.squareup:kotlinpoet:${Versions.KOTLIN_POET}") } diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt new file mode 100644 index 00000000..8f9bb049 --- /dev/null +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt @@ -0,0 +1,85 @@ +package com.mirego.kword + +import com.squareup.kotlinpoet.* +import groovy.json.JsonSlurper +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import java.io.File +import java.util.Locale + +open class KWordEnumGenerate : DefaultTask() { + @Internal + val extension: KWordExtension = project.extensions.getByType(KWordExtension::class.java) + + @TaskAction + fun generate() { + val generatedClassName = ClassName.bestGuess(getEnumClassName()) + val enumBuilder = enumBuilder(generatedClassName) + addEnumConstants(enumBuilder) + writeFile(generatedClassName, enumBuilder) + } + + private fun enumBuilder(generatedClassName: ClassName): TypeSpec.Builder { + return TypeSpec.enumBuilder(generatedClassName) + .addSuperinterface(ClassName.bestGuess("com.mirego.trikot.kword.KWordKey")) + } + + private fun addEnumConstants(enumBuilder: TypeSpec.Builder) { + parseKeys() + .map { key -> underscoreKey(key) to key } + .forEach { + enumBuilder.addEnumConstant(it.first, TypeSpec.anonymousClassBuilder() + .addProperty( + PropertySpec.builder("translationKey", String::class, KModifier.OVERRIDE) + .initializer("%S", it.second) + .build() + ) + .build()) + } + } + + private fun writeFile(generatedClassName: ClassName, enumBuilder: TypeSpec.Builder) { + FileSpec.builder(generatedClassName.packageName, generatedClassName.simpleName) + .indent(" ") + .addType(enumBuilder.build()) + .build() + .writeTo(getGeneratedDir()) + } + + private fun parseKeys(): List { + val keys = mutableSetOf() + getTranslationFiles().forEach { + val translations = JsonSlurper().parse(it) as Map + keys.addAll(translations.keys) + } + return keys.toList() + } + + companion object { + fun underscoreKey(key: String): String { + return key.replace(Regex("([A-Z])"), "_$1").replace(".", "_").uppercase(Locale.ENGLISH) + } + } + + @InputFiles + fun getTranslationFiles(): List = + extension.translationFile?.let { listOf(it) } ?: extension.translationFiles + + @Internal + fun getEnumClassName(): String { + return extension.enumClassName ?: "" + } + + @Internal + fun getGeneratedDir(): File { + return extension.generatedDir ?: File("") + } + + @OutputFile + fun getGeneratedClassFile(): File { + return File(getGeneratedDir(), getEnumClassName().replace(".", "/") + ".kt") + } +} \ No newline at end of file diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt new file mode 100644 index 00000000..7e8f5d70 --- /dev/null +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt @@ -0,0 +1,19 @@ +package com.mirego.kword + +import org.gradle.api.Plugin +import org.gradle.api.Project + +class KWordPlugin : Plugin { + companion object { + private const val TASKS_GROUP = "KWord" + } + + override fun apply(project: Project) { + val extension = project.extensions.create("kword", KWordExtension::class.java, project) + + project.tasks.create("kwordGenerateEnum", KWordEnumGenerate::class.java) { + it.group = TASKS_GROUP + it.description = "Generate keys enum based on json translation file." + } + } +} \ No newline at end of file diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt new file mode 100644 index 00000000..e471d6b1 --- /dev/null +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt @@ -0,0 +1,38 @@ +package com.mirego.kword + +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.tasks.Input +import java.io.File + +open class KWordExtension(project: Project) { + @Input + var translationFile: File? = null + + @Input + var translationFiles: List = emptyList() + + @Input + var enumClassName: String? = null + + @Input + var generatedDir: File? = null + + private val projectDirectory: Directory = project.layout.projectDirectory + + fun translationFile(translationFile: Any) { + this.translationFile = projectDirectory.files(translationFile).singleFile + } + + fun translationFiles(vararg translationFiles: Any) { + this.translationFiles = projectDirectory.files(*translationFiles).toList() + } + + fun enumClassName(enumClassName: String) { + this.enumClassName = enumClassName + } + + fun generatedDir(generatedDir: Any) { + this.generatedDir = projectDirectory.files(generatedDir).singleFile + } +} \ No newline at end of file diff --git a/trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt b/trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt new file mode 100644 index 00000000..7622757b --- /dev/null +++ b/trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt @@ -0,0 +1,18 @@ +package com.mirego.kword + +import org.gradle.internal.impldep.org.apache.ivy.plugins.repository.ResourceHelper +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder +import java.io.File + +class KwordPluginTest { + + @Rule + @JvmField + var temporaryFolder: TemporaryFolder = TemporaryFolder() + + private val kWordEnumGenerate = KWordEnumGenerate() +} \ No newline at end of file diff --git a/trikot-kword/sample/ios/Podfile.lock b/trikot-kword/sample/ios/Podfile.lock index 50917d49..a5b525e1 100644 --- a/trikot-kword/sample/ios/Podfile.lock +++ b/trikot-kword/sample/ios/Podfile.lock @@ -1,8 +1,8 @@ PODS: - SwiftLint (0.43.1) - - Trikot/kword (5.4.0-SNAPSHOT): + - Trikot/kword (5.5.0-SNAPSHOT): - TRIKOT_FRAMEWORK_NAME - - TRIKOT_FRAMEWORK_NAME (5.4.0-SNAPSHOT) + - TRIKOT_FRAMEWORK_NAME (5.5.0-SNAPSHOT) DEPENDENCIES: - SwiftLint @@ -21,8 +21,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: SwiftLint: 99f82d07b837b942dd563c668de129a03fc3fb52 - Trikot: cf1117e1fef1ec0dbd6ee26e2cc564a2e467eee9 - TRIKOT_FRAMEWORK_NAME: a1cd696ba6ac576f82a21a6f9231219df5fcd045 + Trikot: 5d5bb34fccaeeb2e469d9e73c5177dc63e939f81 + TRIKOT_FRAMEWORK_NAME: ae9595e5a2a165d60ca9876f178f4f86db253813 PODFILE CHECKSUM: cd5b1ad5ff7d13e99dec5f4c7a746099a745e482 diff --git a/trikot-viewmodels-declarative-compiler/viewmodels-declarative-compiler-flow/build.gradle.kts b/trikot-viewmodels-declarative-compiler/viewmodels-declarative-compiler-flow/build.gradle.kts index efdd2983..948bc064 100644 --- a/trikot-viewmodels-declarative-compiler/viewmodels-declarative-compiler-flow/build.gradle.kts +++ b/trikot-viewmodels-declarative-compiler/viewmodels-declarative-compiler-flow/build.gradle.kts @@ -14,7 +14,7 @@ dependencies { implementation(project(Project.TRIKOT_VIEWMODELS_DECLARATIVE_FLOW)) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.KOTLINX_COROUTINES}") - testImplementation("com.github.tschuchortdev:kotlin-compile-testing-ksp:1.6.0") + testImplementation("com.github.tschuchortdev:kotlin-compile-testing-ksp:${Versions.COMPILE_TESTING_KSP}") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") testImplementation("org.jetbrains.kotlin:kotlin-reflect:${Versions.KOTLIN}") diff --git a/trikot-viewmodels-declarative-flow/sample/common/TRIKOT_FRAMEWORK_NAME.podspec b/trikot-viewmodels-declarative-flow/sample/common/TRIKOT_FRAMEWORK_NAME.podspec index ea5484ff..b4893178 100644 --- a/trikot-viewmodels-declarative-flow/sample/common/TRIKOT_FRAMEWORK_NAME.podspec +++ b/trikot-viewmodels-declarative-flow/sample/common/TRIKOT_FRAMEWORK_NAME.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'TRIKOT_FRAMEWORK_NAME' - spec.version = '5.4.0-SNAPSHOT' + spec.version = '5.5.0-SNAPSHOT' spec.homepage = 'www.mirego.com' spec.source = { :http=> ''} spec.authors = '' From f9fd0c6e58aa8bf4389ba6b8beb368d0562dd977 Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 13:20:56 -0400 Subject: [PATCH 2/9] cleanup --- .../com/mirego/kword/KWordEnumGenerate.groovy | 88 ------------------- .../com/mirego/kword/KWordExtension.groovy | 54 ------------ .../com/mirego/kword/KWordPlugin.groovy | 17 ---- 3 files changed, 159 deletions(-) delete mode 100644 trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordEnumGenerate.groovy delete mode 100644 trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordExtension.groovy delete mode 100644 trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordPlugin.groovy diff --git a/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordEnumGenerate.groovy b/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordEnumGenerate.groovy deleted file mode 100644 index b620c904..00000000 --- a/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordEnumGenerate.groovy +++ /dev/null @@ -1,88 +0,0 @@ -package com.mirego.kword - -import com.squareup.kotlinpoet.* -import groovy.json.JsonSlurper -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -class KWordEnumGenerate extends DefaultTask { - private static final ClassName KOTLIN_STRING = ClassName.bestGuess('kotlin.String') - - @Internal - KWordExtension extension = { project.extensions.getByType(KWordExtension) }() - - @TaskAction - void generate() { - ClassName generatedClassName = ClassName.bestGuess(getEnumClassName()) - TypeSpec.Builder enumBuilder = enumBuilder(generatedClassName) - addEnumConstants(enumBuilder) - writeFile(generatedClassName, enumBuilder) - } - - private TypeSpec.Builder enumBuilder(ClassName generatedClassName) { - TypeSpec.enumBuilder(generatedClassName) - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("translationKey", KOTLIN_STRING) - .build()) - .addProperty( - PropertySpec.builder("translationKey", KOTLIN_STRING, KModifier.OVERRIDE) - .initializer("translationKey") - .build()) - .addSuperinterface(ClassName.bestGuess('com.mirego.trikot.kword.KWordKey'), CodeBlock.EMPTY) - } - - private void addEnumConstants(enumBuilder) { - parseKeys() - .collect { key -> new Tuple2(underscoreKey(key), key) } - .each { - enumBuilder.addEnumConstant(it.first, TypeSpec.anonymousClassBuilder() - .addSuperclassConstructorParameter("%S", it.second) - .build()) - } - } - - private writeFile(ClassName generatedClassName, TypeSpec.Builder enumBuilder) { - FileSpec.builder(generatedClassName.packageName, generatedClassName.simpleName) - .indent(" ") - .addType(enumBuilder.build()) - .build() - .writeTo(getGeneratedDir()) - } - - private List parseKeys() { - final Set keys = new HashSet<>() - getTranslationFiles().collect { - Map translations = new JsonSlurper().parse(it) as Map - keys.addAll(translations.keySet()) - } - keys.toList() - } - - static String underscoreKey(String key) { - key.replaceAll(/([A-Z])/, '_$1').replaceAll(/\./, '_').toUpperCase() - } - - @InputFiles - List getTranslationFiles() { - return extension.translationFile != null ? Arrays.asList(extension.translationFile) : extension.translationFiles - } - - @Internal - String getEnumClassName() { - return extension.enumClassName - } - - @Internal - File getGeneratedDir() { - return extension.generatedDir - } - - @OutputFile - File getGeneratedClassFile() { - return new File(getGeneratedDir(), getEnumClassName().replaceAll(/\./, '/') + '.kt') - } -} diff --git a/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordExtension.groovy b/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordExtension.groovy deleted file mode 100644 index 33133360..00000000 --- a/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordExtension.groovy +++ /dev/null @@ -1,54 +0,0 @@ -package com.mirego.kword - -import org.gradle.api.Project -import org.gradle.api.file.Directory -import org.gradle.api.tasks.Input - -class KWordExtension { - @Input - File translationFile - @Input - List translationFiles - @Input - String enumClassName - @Input - File generatedDir - - private Directory projectDirectory - - KWordExtension(Project project) { - projectDirectory = project.layout.projectDirectory - } - - File getTranslationFile() { - return translationFile - } - - void translationFile(Object translationFile) { - this.translationFile = projectDirectory.files(translationFile).singleFile - } - - List getTranslationFiles() { - return translationFiles - } - - void translationFiles(Object... translationFiles) { - this.translationFiles = projectDirectory.files(translationFiles).toList() - } - - String getEnumClassName() { - return enumClassName - } - - void enumClassName(String enumClassName) { - this.enumClassName = enumClassName - } - - File getGeneratedDir() { - return generatedDir - } - - void generatedDir(Object generatedDir) { - this.generatedDir = projectDirectory.files(generatedDir).singleFile - } -} diff --git a/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordPlugin.groovy b/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordPlugin.groovy deleted file mode 100644 index b6818d35..00000000 --- a/trikot-kword/kword-plugin/src/main/groovy/com/mirego/kword/KWordPlugin.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package com.mirego.kword - -import org.gradle.api.Plugin -import org.gradle.api.Project - -class KWordPlugin implements Plugin { - private static final String TASKS_GROUP = 'KWord' - - @Override - void apply(Project project) { - KWordExtension extension = project.extensions.create('kword', KWordExtension, project) - - KWordEnumGenerate generateTask = project.task('kwordGenerateEnum', type: KWordEnumGenerate, group: TASKS_GROUP, - description: 'Generate keys enum based on json translation file.') - - } -} From 680163f359ba7a748eaa6941d3c47c32b008b783 Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 14:56:43 -0400 Subject: [PATCH 3/9] WIP --- CHANGELOG.md | 16 ++++- .../kword-plugin/api/kword-plugin.api | 18 +++++ .../com.mirego.kword/KWordEnumGenerate.kt | 67 ++++++++++--------- .../kotlin/com.mirego.kword/KWordPlugin.kt | 9 ++- .../kotlin/com.mirego.kword/KwordExtension.kt | 40 +++-------- trikot-kword/sample/common/build.gradle.kts | 6 +- 6 files changed, 86 insertions(+), 70 deletions(-) create mode 100644 trikot-kword/kword-plugin/api/kword-plugin.api diff --git a/CHANGELOG.md b/CHANGELOG.md index 15740655..19ab99dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Upcoming ### Breaking Changes +- [kword] Gradle plugin DSL changed. All properties are now lazy. +Instead of +```kotlin + translationFile = file("src/commonMain/resources/translations/translation.en.json") + enumClassName = "com.mirego.sample.KWordTranslation" + generatedDir = file("src/commonMain/generated") +``` -### Updates +Do this +```kotlin + translationFile.set(file("src/commonMain/resources/translations/translation.en.json")) + enumClassName.set("com.mirego.sample.KWordTranslation") + generatedDir.set(file("src/commonMain/generated")) +``` -### Breaking Changes +### Updates ## 5.4.0 diff --git a/trikot-kword/kword-plugin/api/kword-plugin.api b/trikot-kword/kword-plugin/api/kword-plugin.api new file mode 100644 index 00000000..8837c410 --- /dev/null +++ b/trikot-kword/kword-plugin/api/kword-plugin.api @@ -0,0 +1,18 @@ +public abstract class com/mirego/kword/KWordExtension { + public fun ()V + public abstract fun getEnumClassName ()Lorg/gradle/api/provider/Property; + public abstract fun getGeneratedDir ()Lorg/gradle/api/file/DirectoryProperty; + public abstract fun getTranslationFile ()Lorg/gradle/api/file/RegularFileProperty; + public abstract fun getTranslationFiles ()Lorg/gradle/api/file/ConfigurableFileCollection; +} + +public final class com/mirego/kword/KWordPlugin : org/gradle/api/Plugin { + public static final field Companion Lcom/mirego/kword/KWordPlugin$Companion; + public fun ()V + public synthetic fun apply (Ljava/lang/Object;)V + public fun apply (Lorg/gradle/api/Project;)V +} + +public final class com/mirego/kword/KWordPlugin$Companion { +} + diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt index 8f9bb049..bfc769fb 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt @@ -3,20 +3,38 @@ package com.mirego.kword import com.squareup.kotlinpoet.* import groovy.json.JsonSlurper import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction -import java.io.File import java.util.Locale -open class KWordEnumGenerate : DefaultTask() { - @Internal - val extension: KWordExtension = project.extensions.getByType(KWordExtension::class.java) +internal abstract class KWordEnumGenerate : DefaultTask() { + + @get:InputFiles + abstract val translationFiles: ConfigurableFileCollection + + @get:Input + abstract val enumClassName: Property + + @get:InputDirectory + abstract val generatedDir: DirectoryProperty + + @get:OutputFile + val generatedClassFile: Provider get() = + generatedDir.file(enumClassName.map { it.replace(".", "/") + ".kt" }) @TaskAction fun generate() { - val generatedClassName = ClassName.bestGuess(getEnumClassName()) + logger.warn("Generating KWord enum for ${enumClassName.get()}") + logger.warn("Translation files: ${translationFiles.files}") + val generatedClassName = ClassName.bestGuess(enumClassName.get()) val enumBuilder = enumBuilder(generatedClassName) addEnumConstants(enumBuilder) writeFile(generatedClassName, enumBuilder) @@ -24,6 +42,14 @@ open class KWordEnumGenerate : DefaultTask() { private fun enumBuilder(generatedClassName: ClassName): TypeSpec.Builder { return TypeSpec.enumBuilder(generatedClassName) + .primaryConstructor( + FunSpec.constructorBuilder() + .addParameter("translationKey", String::class) + .build()) + .addProperty( + PropertySpec.builder("translationKey", String::class, KModifier.OVERRIDE) + .initializer("translationKey") + .build()) .addSuperinterface(ClassName.bestGuess("com.mirego.trikot.kword.KWordKey")) } @@ -32,11 +58,7 @@ open class KWordEnumGenerate : DefaultTask() { .map { key -> underscoreKey(key) to key } .forEach { enumBuilder.addEnumConstant(it.first, TypeSpec.anonymousClassBuilder() - .addProperty( - PropertySpec.builder("translationKey", String::class, KModifier.OVERRIDE) - .initializer("%S", it.second) - .build() - ) + .addSuperclassConstructorParameter("%S", it.second) .build()) } } @@ -46,12 +68,12 @@ open class KWordEnumGenerate : DefaultTask() { .indent(" ") .addType(enumBuilder.build()) .build() - .writeTo(getGeneratedDir()) + .writeTo(generatedDir.get().asFile) } private fun parseKeys(): List { val keys = mutableSetOf() - getTranslationFiles().forEach { + translationFiles.forEach { val translations = JsonSlurper().parse(it) as Map keys.addAll(translations.keys) } @@ -63,23 +85,4 @@ open class KWordEnumGenerate : DefaultTask() { return key.replace(Regex("([A-Z])"), "_$1").replace(".", "_").uppercase(Locale.ENGLISH) } } - - @InputFiles - fun getTranslationFiles(): List = - extension.translationFile?.let { listOf(it) } ?: extension.translationFiles - - @Internal - fun getEnumClassName(): String { - return extension.enumClassName ?: "" - } - - @Internal - fun getGeneratedDir(): File { - return extension.generatedDir ?: File("") - } - - @OutputFile - fun getGeneratedClassFile(): File { - return File(getGeneratedDir(), getEnumClassName().replace(".", "/") + ".kt") - } } \ No newline at end of file diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt index 7e8f5d70..aafb4f9e 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt @@ -4,16 +4,21 @@ import org.gradle.api.Plugin import org.gradle.api.Project class KWordPlugin : Plugin { - companion object { + private companion object { private const val TASKS_GROUP = "KWord" } override fun apply(project: Project) { - val extension = project.extensions.create("kword", KWordExtension::class.java, project) + val extension = project.extensions.create("kword", KWordExtension::class.java) project.tasks.create("kwordGenerateEnum", KWordEnumGenerate::class.java) { it.group = TASKS_GROUP it.description = "Generate keys enum based on json translation file." + it.enumClassName.set(extension.enumClassName) + it.translationFiles.setFrom( + extension.translationFiles + extension.translationFile + ) + it.generatedDir.set(extension.generatedDir) } } } \ No newline at end of file diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt index e471d6b1..c03b678f 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt @@ -1,38 +1,16 @@ package com.mirego.kword -import org.gradle.api.Project -import org.gradle.api.file.Directory -import org.gradle.api.tasks.Input -import java.io.File +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property -open class KWordExtension(project: Project) { - @Input - var translationFile: File? = null +abstract class KWordExtension { + abstract val translationFile: RegularFileProperty - @Input - var translationFiles: List = emptyList() + abstract val translationFiles: ConfigurableFileCollection - @Input - var enumClassName: String? = null + abstract val enumClassName: Property - @Input - var generatedDir: File? = null - - private val projectDirectory: Directory = project.layout.projectDirectory - - fun translationFile(translationFile: Any) { - this.translationFile = projectDirectory.files(translationFile).singleFile - } - - fun translationFiles(vararg translationFiles: Any) { - this.translationFiles = projectDirectory.files(*translationFiles).toList() - } - - fun enumClassName(enumClassName: String) { - this.enumClassName = enumClassName - } - - fun generatedDir(generatedDir: Any) { - this.generatedDir = projectDirectory.files(generatedDir).singleFile - } + abstract val generatedDir: DirectoryProperty } \ No newline at end of file diff --git a/trikot-kword/sample/common/build.gradle.kts b/trikot-kword/sample/common/build.gradle.kts index 5740c47d..d5a665f5 100644 --- a/trikot-kword/sample/common/build.gradle.kts +++ b/trikot-kword/sample/common/build.gradle.kts @@ -16,9 +16,9 @@ configurations { } kword { - translationFile = file("src/commonMain/resources/translations/translation.en.json") - enumClassName = "com.mirego.sample.KWordTranslation" - generatedDir = file("src/commonMain/generated") + translationFile.set(file("src/commonMain/resources/translations/translation.en.json")) + enumClassName.set("com.mirego.sample.KWordTranslation") + generatedDir.set(file("src/commonMain/generated")) } fun org.jetbrains.kotlin.gradle.plugin.mpp.Framework.configureFramework() { From 2b3608dcb17a81a97cbb7aa816312062da051ad8 Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 15:13:13 -0400 Subject: [PATCH 4/9] reformat --- CHANGELOG.md | 5 +++- .../com.mirego.kword/KWordEnumGenerate.kt | 24 +++++++++++++------ .../{KwordExtension.kt => KWordExtension.kt} | 2 +- .../kotlin/com.mirego.kword/KWordPlugin.kt | 2 +- .../com/mirego/kword/KwordEnumGenerateTest.kt | 18 -------------- trikot-kword/sample/common/build.gradle.kts | 3 ++- 6 files changed, 25 insertions(+), 29 deletions(-) rename trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/{KwordExtension.kt => KWordExtension.kt} (99%) delete mode 100644 trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ab99dc..b5ae0177 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Upcoming ### Breaking Changes + - [kword] Gradle plugin DSL changed. All properties are now lazy. -Instead of + Instead of + ```kotlin translationFile = file("src/commonMain/resources/translations/translation.en.json") enumClassName = "com.mirego.sample.KWordTranslation" @@ -16,6 +18,7 @@ Instead of ``` Do this + ```kotlin translationFile.set(file("src/commonMain/resources/translations/translation.en.json")) enumClassName.set("com.mirego.sample.KWordTranslation") diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt index bfc769fb..d76b01cf 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt @@ -1,6 +1,11 @@ package com.mirego.kword -import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeSpec import groovy.json.JsonSlurper import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection @@ -45,11 +50,13 @@ internal abstract class KWordEnumGenerate : DefaultTask() { .primaryConstructor( FunSpec.constructorBuilder() .addParameter("translationKey", String::class) - .build()) + .build() + ) .addProperty( PropertySpec.builder("translationKey", String::class, KModifier.OVERRIDE) .initializer("translationKey") - .build()) + .build() + ) .addSuperinterface(ClassName.bestGuess("com.mirego.trikot.kword.KWordKey")) } @@ -57,9 +64,12 @@ internal abstract class KWordEnumGenerate : DefaultTask() { parseKeys() .map { key -> underscoreKey(key) to key } .forEach { - enumBuilder.addEnumConstant(it.first, TypeSpec.anonymousClassBuilder() - .addSuperclassConstructorParameter("%S", it.second) - .build()) + enumBuilder.addEnumConstant( + it.first, + TypeSpec.anonymousClassBuilder() + .addSuperclassConstructorParameter("%S", it.second) + .build() + ) } } @@ -85,4 +95,4 @@ internal abstract class KWordEnumGenerate : DefaultTask() { return key.replace(Regex("([A-Z])"), "_$1").replace(".", "_").uppercase(Locale.ENGLISH) } } -} \ No newline at end of file +} diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordExtension.kt similarity index 99% rename from trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt rename to trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordExtension.kt index c03b678f..33b38df8 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KwordExtension.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordExtension.kt @@ -13,4 +13,4 @@ abstract class KWordExtension { abstract val enumClassName: Property abstract val generatedDir: DirectoryProperty -} \ No newline at end of file +} diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt index aafb4f9e..e25a329f 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordPlugin.kt @@ -21,4 +21,4 @@ class KWordPlugin : Plugin { it.generatedDir.set(extension.generatedDir) } } -} \ No newline at end of file +} diff --git a/trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt b/trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt deleted file mode 100644 index 7622757b..00000000 --- a/trikot-kword/kword-plugin/src/test/kotlin/com/mirego/kword/KwordEnumGenerateTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.mirego.kword - -import org.gradle.internal.impldep.org.apache.ivy.plugins.repository.ResourceHelper -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TemporaryFolder -import java.io.File - -class KwordPluginTest { - - @Rule - @JvmField - var temporaryFolder: TemporaryFolder = TemporaryFolder() - - private val kWordEnumGenerate = KWordEnumGenerate() -} \ No newline at end of file diff --git a/trikot-kword/sample/common/build.gradle.kts b/trikot-kword/sample/common/build.gradle.kts index d5a665f5..777d88d1 100644 --- a/trikot-kword/sample/common/build.gradle.kts +++ b/trikot-kword/sample/common/build.gradle.kts @@ -2,7 +2,8 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") - id("mirego.kword").version("2.0.1") + id("mirego.kword").version("5.5.0-SNAPSHOT") +// id("mirego.kword").version("5.4.0") } group = "com.mirego.sample" From 5509260211f7de1857b1c97479274c5064d364da Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 15:18:19 -0400 Subject: [PATCH 5/9] WIP --- trikot-kword/kword-plugin/api/kword-plugin.api | 18 ++++++++++++++---- .../com.mirego.kword/KWordEnumGenerate.kt | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/trikot-kword/kword-plugin/api/kword-plugin.api b/trikot-kword/kword-plugin/api/kword-plugin.api index 8837c410..15c50fc9 100644 --- a/trikot-kword/kword-plugin/api/kword-plugin.api +++ b/trikot-kword/kword-plugin/api/kword-plugin.api @@ -1,3 +1,17 @@ +public abstract class com/mirego/kword/KWordEnumGenerate : org/gradle/api/DefaultTask { + public static final field Companion Lcom/mirego/kword/KWordEnumGenerate$Companion; + public fun ()V + public final fun generate ()V + public abstract fun getEnumClassName ()Lorg/gradle/api/provider/Property; + public final fun getGeneratedClassFile ()Lorg/gradle/api/provider/Provider; + public abstract fun getGeneratedDir ()Lorg/gradle/api/file/DirectoryProperty; + public abstract fun getTranslationFiles ()Lorg/gradle/api/file/ConfigurableFileCollection; +} + +public final class com/mirego/kword/KWordEnumGenerate$Companion { + public final fun underscoreKey (Ljava/lang/String;)Ljava/lang/String; +} + public abstract class com/mirego/kword/KWordExtension { public fun ()V public abstract fun getEnumClassName ()Lorg/gradle/api/provider/Property; @@ -7,12 +21,8 @@ public abstract class com/mirego/kword/KWordExtension { } public final class com/mirego/kword/KWordPlugin : org/gradle/api/Plugin { - public static final field Companion Lcom/mirego/kword/KWordPlugin$Companion; public fun ()V public synthetic fun apply (Ljava/lang/Object;)V public fun apply (Lorg/gradle/api/Project;)V } -public final class com/mirego/kword/KWordPlugin$Companion { -} - diff --git a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt index d76b01cf..00cb624a 100644 --- a/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt +++ b/trikot-kword/kword-plugin/src/main/kotlin/com.mirego.kword/KWordEnumGenerate.kt @@ -20,7 +20,7 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import java.util.Locale -internal abstract class KWordEnumGenerate : DefaultTask() { +abstract class KWordEnumGenerate : DefaultTask() { @get:InputFiles abstract val translationFiles: ConfigurableFileCollection From bb2a5051524fcc00dc5d116e1f532143c6e45bf7 Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 15:30:09 -0400 Subject: [PATCH 6/9] Cleanup until next release --- trikot-kword/sample/common/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/trikot-kword/sample/common/build.gradle.kts b/trikot-kword/sample/common/build.gradle.kts index 777d88d1..9491f84d 100644 --- a/trikot-kword/sample/common/build.gradle.kts +++ b/trikot-kword/sample/common/build.gradle.kts @@ -2,8 +2,7 @@ plugins { id("com.android.library") kotlin("multiplatform") kotlin("native.cocoapods") - id("mirego.kword").version("5.5.0-SNAPSHOT") -// id("mirego.kword").version("5.4.0") + id("mirego.kword").version("5.4.0") } group = "com.mirego.sample" From 8e810ce91c2943981545113e69cf2aa636119b8c Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 17:07:31 -0400 Subject: [PATCH 7/9] revert sample changes temporarely until we have a published version --- trikot-kword/sample/common/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/trikot-kword/sample/common/build.gradle.kts b/trikot-kword/sample/common/build.gradle.kts index 9491f84d..8fc11718 100644 --- a/trikot-kword/sample/common/build.gradle.kts +++ b/trikot-kword/sample/common/build.gradle.kts @@ -16,9 +16,9 @@ configurations { } kword { - translationFile.set(file("src/commonMain/resources/translations/translation.en.json")) - enumClassName.set("com.mirego.sample.KWordTranslation") - generatedDir.set(file("src/commonMain/generated")) + translationFile = file("src/commonMain/resources/translations/translation.en.json") + enumClassName = "com.mirego.sample.KWordTranslation" + generatedDir = file("src/commonMain/generated") } fun org.jetbrains.kotlin.gradle.plugin.mpp.Framework.configureFramework() { From dc5f525e1b7df446df7209a96d9066a68855e67a Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Fri, 9 Aug 2024 17:32:56 -0400 Subject: [PATCH 8/9] Cleanup and fix build --- trikot-kword/sample/common/build.gradle.kts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/trikot-kword/sample/common/build.gradle.kts b/trikot-kword/sample/common/build.gradle.kts index 8fc11718..8ee8268e 100644 --- a/trikot-kword/sample/common/build.gradle.kts +++ b/trikot-kword/sample/common/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask + plugins { id("com.android.library") kotlin("multiplatform") @@ -77,10 +79,6 @@ android { } } -project.afterEvaluate { - tasks - .filter { task -> task.name.startsWith("compile") && task.name.contains("Kotlin") } - .forEach { task -> - task.dependsOn(tasks.withType()) - } +tasks.withType> { + dependsOn(tasks.withType()) } From 616fed576389b0a1cc0022140a57952a7ac3eeb1 Mon Sep 17 00:00:00 2001 From: Nicolas Presseault Date: Mon, 12 Aug 2024 09:32:24 -0400 Subject: [PATCH 9/9] Add dependency for ktlint too --- trikot-kword/sample/common/build.gradle.kts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/trikot-kword/sample/common/build.gradle.kts b/trikot-kword/sample/common/build.gradle.kts index 8ee8268e..2561ed43 100644 --- a/trikot-kword/sample/common/build.gradle.kts +++ b/trikot-kword/sample/common/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import org.jlleitschuh.gradle.ktlint.tasks.KtLintCheckTask plugins { id("com.android.library") @@ -79,6 +80,10 @@ android { } } +tasks.withType { + dependsOn(tasks.withType()) +} + tasks.withType> { dependsOn(tasks.withType()) }