From 08e51e17aef14546a6176ef252d2ce89d8887f86 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Mon, 4 Nov 2024 19:11:02 +0000 Subject: [PATCH] 1.0.5: Replace underscores with camel-case names --- changes/1.0.5.md | 8 +++ gradle.properties | 2 +- .../kotlin/dev/kordex/i18n/generator/Main.kt | 16 ++++- .../i18n/generator/TranslationsClass.kt | 58 +++++++++++++++---- test/strings.properties | 4 +- 5 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 changes/1.0.5.md diff --git a/changes/1.0.5.md b/changes/1.0.5.md new file mode 100644 index 0000000..a37d8a7 --- /dev/null +++ b/changes/1.0.5.md @@ -0,0 +1,8 @@ +# i18n tools 1.0.5 + +Updated the class generator to remove common delimiters from names and camel-case them instead of replacing the delimiters with underscores. + +## Translations Class Generator + +- **API:** Add a (default on) option to remove common delimiters in names. You can disable this for compatibility with old code, but I'll remove the option in a future version. +- **CLI:** Expose the above option via the `-ncc` and `--no-camel-case` switches. I'll remove these when I remove the API option. diff --git a/gradle.properties b/gradle.properties index cf16e2f..f76197e 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.4 +projectVersion=1.0.5 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 665c220..a61f092 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 @@ -90,6 +90,16 @@ public fun main(vararg args: String) { ) } + spec.addOption("-ncc", "--no-camel-case") { + paramLabel("CAMEL CASE") + defaultValue("false") + + description( + "Replace common delimiters in names with underscores instead of camel-casing them. " + + "This option is provided for compatibility, and will be removed in the future.." + ) + } + val commandLine = CommandLine(spec) commandLine.setExecutionStrategy(::run) @@ -109,6 +119,7 @@ private fun run(result: CommandLine.ParseResult): Int { val classPackage: String = result.matchedOption("p").getValue() val encoding: String = result.matchedOptionValue("e", "UTF-8") val internal: Boolean = result.matchedOptionValue("in", false) + val noCamelCase: Boolean = result.matchedOptionValue("ncc", false) val className: String = result.matchedOptionValue("c", "Translations") val outputDir: File = result.matchedOptionValue("o", File("output")) @@ -141,11 +152,12 @@ private fun run(result: CommandLine.ParseResult): Int { println("Generating class \"$className\" for bundle \"$bundle\"...") val translationsClass = TranslationsClass( - bundle = bundle, allProps = props, + bundle = bundle, className = className, + publicVisibility = !internal, + splitToCamelCase = !noCamelCase, classPackage = classPackage, - publicVisibility = !internal ) 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 d6b7f5a..15ef3f4 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 @@ -17,6 +17,8 @@ import com.squareup.kotlinpoet.PropertySpec import java.io.File import java.util.Properties +public val DELIMITERS: Array = arrayOf("_", "-", ".") + /** * Representation of a generated translations object. * @@ -36,6 +38,8 @@ import java.util.Properties * @param publicVisibility Whether to use `public` (`true`) or `internal` (`false`) visibility modifiers in the * generated code. * Defaults to (`true`). + * + * @param splitToCamelCase Whether to replace common delimiters in generated names */ public class TranslationsClass( public val allProps: Properties, @@ -44,8 +48,26 @@ public class TranslationsClass( public val className: String = "Translations", public val publicVisibility: Boolean = true, + @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 ) { + + init { + @Suppress("DEPRECATION") + if (!splitToCamelCase) { + System.err.println("") + + System.err.println( + "WARNING: Configured to replace delimiters with underscores instead of converting names to " + + "camel-case. This option will be removed in a future version." + ) + + System.err.println("") + } + } + /** KModifier represented by [publicVisibility]. **/ public val visibility: KModifier = if (publicVisibility) { KModifier.PUBLIC @@ -127,13 +149,7 @@ public class TranslationsClass( if (v.isNotEmpty()) { // Object - val objName = k - .replace("-", " ") - .split(" ") - .map { it.capitalized() } - .joinToString("") - - types.addObject(objName) { + types.addObject(k.toClassName()) { addModifiers(visibility) addKeys(v, props, translationsClassName, keyName) } @@ -170,8 +186,28 @@ public class TranslationsClass( public fun String.capitalized(): String = replaceFirstChar { it.uppercase() } - public fun String.toVarName(): String = - replace("-", "_") - .replace(".", "_") - .replaceFirstChar { it.lowercase() } + @Suppress("DEPRECATION") + public fun String.toVarName(): String = let { + if (splitToCamelCase) { + toClassName() + .replaceFirstChar { it.lowercase() } + } else { + it.replace("-", "_") + .replace(".", "_") + .replaceFirstChar { it.lowercase() } + } + } + + @Suppress("DEPRECATION", "SpreadOperator") + public fun String.toClassName(): String = + let { + if (splitToCamelCase) { + it.split(*DELIMITERS).joinToString("") { it.capitalized() } + } else { + it.replace("-", " ") + .split(" ") + .map { it.capitalized() } + .joinToString("") + } + } } diff --git a/test/strings.properties b/test/strings.properties index 99b39f9..fdb6571 100644 --- a/test/strings.properties +++ b/test/strings.properties @@ -5,7 +5,7 @@ commands.button.name=button commands.slap.action=slaps {0} with their {1} commands.slap.args.target.description=Person you want to slap commands.slap.args.target.name=target -commands.slap.args.weapon.description=What you want to slap with -commands.slap.args.weapon.name=weapon +commands.slap.args.weapon-description=What you want to slap with +commands.slap.args.weapon_name=weapon commands.slap.description=Ask the bot to slap another user commands.slap.name=slap