diff --git a/changes/1.0.6.md b/changes/1.0.6.md new file mode 100644 index 0000000..904f16d --- /dev/null +++ b/changes/1.0.6.md @@ -0,0 +1,9 @@ +# i18n tools 1.0.6 + +Updated the class generator to add a couple of features. + +## Translations Class Generator + +- **API:** Add a `messageFormatVersion` option to specify the ICU message format version specified in the `Bundle` object. Defaults to `1`, but you can use `2` for the experimental new format. +- **API/CLI:** Sort keys and objects alphabetically, making it easier to browse generated code. +- **CLI:** Expose the above option via the `-mfv` and `--message-format-version` switches. diff --git a/gradle.properties b/gradle.properties index f76197e..d8b2396 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ kotlin.incremental=true org.gradle.jvmargs=-XX:MaxMetaspaceSize=1024m org.gradle.parallel=true -projectVersion=1.0.5 +projectVersion=1.0.6 diff --git a/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/Main.kt b/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/Main.kt index a61f092..d697ea1 100644 --- a/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/Main.kt +++ b/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/Main.kt @@ -11,7 +11,7 @@ import picocli.CommandLine.Model.OptionSpec import java.io.File import java.nio.charset.Charset import java.nio.file.Files -import java.util.Properties +import java.util.* import kotlin.system.exitProcess public fun main(vararg args: String) { @@ -62,6 +62,13 @@ public fun main(vararg args: String) { description("Generated class name. Defaults to \"Translations\".") } + spec.addOption("-mfv", "--message-format-version") { + paramLabel("VERSION") + defaultValue("1") + + description("ICU Message Format version. Defaults to version 1, but you may specify version 2 if needed.") + } + spec.addOption("-e", "--encoding") { paramLabel("ENCODING") defaultValue("UTF-8") @@ -120,10 +127,18 @@ private fun run(result: CommandLine.ParseResult): Int { val encoding: String = result.matchedOptionValue("e", "UTF-8") val internal: Boolean = result.matchedOptionValue("in", false) val noCamelCase: Boolean = result.matchedOptionValue("ncc", false) + val messageFormatVersion: Int = result.matchedOptionValue("mfv", 1) val className: String = result.matchedOptionValue("c", "Translations") val outputDir: File = result.matchedOptionValue("o", File("output")) + if (messageFormatVersion !in MESSAGE_FORMAT_VERSIONS) { + exitError( + "Invalid message format version $messageFormatVersion - " + + "must be one of ${MESSAGE_FORMAT_VERSIONS.joinToString()}" + ) + } + if ("." !in bundle) { bundle = "$bundle.strings" } @@ -158,6 +173,7 @@ private fun run(result: CommandLine.ParseResult): Int { publicVisibility = !internal, splitToCamelCase = !noCamelCase, classPackage = classPackage, + messageFormatVersion = messageFormatVersion, ) translationsClass.writeTo(outputDir) diff --git a/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/TranslationsClass.kt b/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/TranslationsClass.kt index 15ef3f4..358313a 100644 --- a/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/TranslationsClass.kt +++ b/i18n-generator/src/main/kotlin/dev/kordex/i18n/generator/TranslationsClass.kt @@ -4,6 +4,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +@file:Suppress("StringLiteralDuplication") + package dev.kordex.i18n.generator import com.hanggrian.kotlinpoet.TypeSpecBuilder @@ -15,9 +17,10 @@ import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.PropertySpec import java.io.File -import java.util.Properties +import java.util.* public val DELIMITERS: Array = arrayOf("_", "-", ".") +public val MESSAGE_FORMAT_VERSIONS: Array = arrayOf(1, 2) /** * Representation of a generated translations object. @@ -51,9 +54,9 @@ public class TranslationsClass( @Deprecated("This option is provided for compatibility with old code, and will be removed in a future version.") public val splitToCamelCase: Boolean = true, - public val classPackage: String + public val classPackage: String, + public val messageFormatVersion: Int = 1, ) { - init { @Suppress("DEPRECATION") if (!splitToCamelCase) { @@ -66,6 +69,13 @@ public class TranslationsClass( System.err.println("") } + + if (messageFormatVersion !in MESSAGE_FORMAT_VERSIONS) { + error( + "Invalid message format version $messageFormatVersion - " + + "must be one of ${MESSAGE_FORMAT_VERSIONS.joinToString()}" + ) + } } /** KModifier represented by [publicVisibility]. **/ @@ -84,6 +94,10 @@ public class TranslationsClass( * The [TranslationsClass] fills this automatically, and it is complete as soon as you've created one. */ public val spec: FileSpec = buildFileSpec(classPackage, className) { + if (messageFormatVersion != 1) { + this.addImport("dev.kordex.core.i18n.types", "MessageFormatVersion") + } + types.addObject(className) { addModifiers(visibility) bundle() @@ -132,9 +146,9 @@ public class TranslationsClass( translationsClassName: String, parent: String? = null, ) { - val paritioned = keys.partition() + val partitioned = keys.sorted().partition() - paritioned.forEach { (k, v) -> + partitioned.forEach { (k, v) -> val keyName = if (parent != null) { "$parent.$k" } else { @@ -161,7 +175,12 @@ public class TranslationsClass( properties.add( buildPropertySpec("bundle", ClassName("dev.kordex.core.i18n.types", "Bundle")) { addModifiers(visibility) - setInitializer("Bundle(%S)", bundle) + + if (messageFormatVersion != 1) { + setInitializer("Bundle(%S, %L)", bundle, messageFormatVersion.toMessageFormatEnum()) + } else { + setInitializer("Bundle(%S)", bundle) + } } ) } @@ -206,8 +225,17 @@ public class TranslationsClass( } else { it.replace("-", " ") .split(" ") - .map { it.capitalized() } - .joinToString("") + .joinToString("") { it.capitalized() } } } + + public fun Int.toMessageFormatEnum(): String = when (this) { + 1 -> "MessageFormatVersion.ONE" + 2 -> "MessageFormatVersion.TWO" + + else -> error( + "Invalid message format version $this - " + + "must be one of ${MESSAGE_FORMAT_VERSIONS.joinToString()}" + ) + } }