diff --git a/build.gradle.kts b/build.gradle.kts index 66a3eee..4c8a76d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,8 +3,6 @@ import net.kyori.indra.IndraPlugin import net.kyori.indra.IndraPublishingPlugin import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jlleitschuh.gradle.ktlint.KtlintBasePlugin -import org.jlleitschuh.gradle.ktlint.KtlintIdeaPlugin @Suppress("DSL_SCOPE_VIOLATION") // https://youtrack.jetbrains.com/issue/KTIJ-19369 plugins { @@ -15,7 +13,7 @@ plugins { alias(libs.plugins.ktlint) } -tasks.withType() { +tasks.withType { onlyIf { false } } @@ -28,17 +26,21 @@ subprojects { apply() apply() apply() - apply() - apply() - - repositories { - mavenCentral() - } + apply(plugin = "org.jlleitschuh.gradle.ktlint") dependencies { compileOnly(rootProject.project.libs.kotlin.stdlib) } + kotlin { + jvmToolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } + + jvmToolchain(17) + explicitApi() + } + tasks { indra { mitLicense() @@ -61,21 +63,11 @@ subprojects { } } - java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - } - } - - kotlin { - explicitApi() - } - ktlint { - version.set("0.45.1") + version.set("1.0.1") } - withType() { + withType { kotlinOptions { freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/MiniPhrase.kt b/core/src/main/kotlin/dev/kezz/miniphrase/MiniPhrase.kt index b444ebc..afb460a 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/MiniPhrase.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/MiniPhrase.kt @@ -33,37 +33,79 @@ import java.util.Locale /** The main entry-point for the MiniPhrase library. */ public class MiniPhrase private constructor( /** The MiniMessage instance. */ - public val miniMessage: MiniMessage, + public var miniMessage: MiniMessage, /** The translation registry. */ public val translationRegistry: TranslationRegistry, /** The default locale for translations. */ public val defaultLocale: Locale, /** If the phrase tag should be included by default. */ - public val includePhraseTag: Boolean + public val includePhraseTag: Boolean, ) : MiniPhraseContext { - public companion object { /** Creates a simple MiniPhrase instance from a given translation registry. */ public fun fromTranslationRegistry(translationRegistry: TranslationRegistry): MiniPhrase = configureAndBuild { translationRegistry(translationRegistry) } /** Configures and builds a MiniPhrase instance using the provided [builder]. */ - public fun configureAndBuild(builder: Builder.() -> Unit): MiniPhrase = - Builder().apply(builder).build() + public fun configureAndBuild(builder: Builder.() -> Unit): MiniPhrase = Builder().apply(builder).build() + } + + init { + translationRegistry.reload() } /** This MiniPhrase instance. */ override val miniPhrase: MiniPhrase = this + /** Formats a string and applies styles and tags. */ + public fun format( + text: String, + locale: Locale? = defaultLocale, + tags: (TagResolverBuilder.() -> Unit)? = null, + ): Component { + val resolver = + TagResolverBuilder.configureAndBuild(this) { + if (includePhraseTag) withPhraseTag(locale) + if (tags != null) tags() + } + return miniMessage.deserialize(text, resolver) + } + /** Translates a key with a given locale, or the default locale. */ - public fun translate(key: String, locale: Locale? = null, tags: (TagResolverBuilder.() -> Unit)? = null): Component { + public fun translateOrNull( + key: String, + locale: Locale? = null, + tags: (TagResolverBuilder.() -> Unit)? = null, + ): Component? { val targetLocale = locale ?: defaultLocale - val translationString = translationRegistry[key, targetLocale] ?: key - val resolver = TagResolverBuilder.configureAndBuild(this) { - if (includePhraseTag) withPhraseTag(locale) - if (tags != null) tags() - } - return miniMessage.deserialize(translationString, resolver) + val translationString = translationRegistry[key, targetLocale] ?: translationRegistry[key, defaultLocale] + + return translationString?.let { format(it, locale ?: defaultLocale, tags) } + } + + /** Translates a key with a given locale, or the default locale. */ + public fun translate( + key: String, + locale: Locale? = null, + tags: (TagResolverBuilder.() -> Unit)? = null, + ): Component { + val targetLocale = locale ?: defaultLocale + val translationString = translationRegistry[key, targetLocale] ?: translationRegistry[key, defaultLocale] ?: key + + return format(translationString, locale ?: defaultLocale, tags) + } + + /** Translates a key with a given locale, or the default locale into multiple lines. */ + public fun translateList( + key: String, + locale: Locale? = null, + tags: (TagResolverBuilder.() -> Unit)? = null, + ): List { + val targetLocale = locale ?: defaultLocale + val lines = + translationRegistry.getList(key, targetLocale) ?: translationRegistry.getList(key, defaultLocale) ?: listOf(key) + + return lines.map { format(it, locale ?: defaultLocale, tags) } } /** Builder class for MiniPhrase instances. */ @@ -104,7 +146,6 @@ public class MiniPhrase private constructor( } /** Creates a MiniPhrase instance from this builder. */ - public fun build(): MiniPhrase = - MiniPhrase(miniMessage, translationRegistry, defaultLocale, includePhraseTag) + public fun build(): MiniPhrase = MiniPhrase(miniMessage, translationRegistry, defaultLocale, includePhraseTag) } } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/audience/ArrayExt.kt b/core/src/main/kotlin/dev/kezz/miniphrase/audience/ArrayExt.kt index d872ec9..6e54104 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/audience/ArrayExt.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/audience/ArrayExt.kt @@ -26,28 +26,23 @@ package dev.kezz.miniphrase.audience import dev.kezz.miniphrase.MiniPhraseContext import dev.kezz.miniphrase.tag.TagResolverBuilder import net.kyori.adventure.audience.Audience -import net.kyori.adventure.audience.MessageType -import net.kyori.adventure.identity.Identity import java.util.Locale /** Shorthand for [Audience.audience]. */ -public fun Array.asAudience(): Audience = - Audience.audience(*this) +public fun Array.asAudience(): Audience = Audience.audience(*this) /** @see [Audience.sendTranslated]. */ context(MiniPhraseContext) public fun Array.sendTranslated( key: String, - type: MessageType = MessageType.CHAT, - identity: Identity = Identity.nil(), locale: Locale? = null, - tags: (TagResolverBuilder.() -> Unit)? = null + tags: (TagResolverBuilder.() -> Unit)? = null, ) { if (locale != null) { // If we've got an override locale, we can save rendering by wrapping this in an audience. - asAudience().sendTranslated(key, type, identity, locale, tags) + asAudience().sendTranslated(key, locale, tags) } else { // Otherwise, we need to pull it from each audience member, so just delegate. - forEach { audience -> audience.sendTranslated(key, type, identity, locale, tags) } + forEach { audience -> audience.sendTranslated(key, locale, tags) } } } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/audience/AudienceExt.kt b/core/src/main/kotlin/dev/kezz/miniphrase/audience/AudienceExt.kt index 8553261..9007e28 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/audience/AudienceExt.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/audience/AudienceExt.kt @@ -27,7 +27,6 @@ import dev.kezz.miniphrase.MiniPhraseContext import dev.kezz.miniphrase.tag.TagResolverBuilder import net.kyori.adventure.audience.Audience import net.kyori.adventure.audience.ForwardingAudience -import net.kyori.adventure.audience.MessageType import net.kyori.adventure.identity.Identity import java.util.Locale @@ -48,14 +47,10 @@ context(MiniPhraseContext) public fun Audience.sendTranslated( /** The key of the message. */ key: String, - /** The type of the message. */ - type: MessageType = MessageType.CHAT, - /** The identity of the message sender. */ - identity: Identity = Identity.nil(), /** The locale to translate the message in, if not the default for the audience. */ locale: Locale? = null, - /* A builder of additional tags to use in the deserialization process. */ - tags: (TagResolverBuilder.() -> Unit)? = null + // A builder of additional tags to use in the deserialization process. + tags: (TagResolverBuilder.() -> Unit)? = null, ) { when { this == Audience.empty() -> { @@ -64,15 +59,40 @@ public fun Audience.sendTranslated( locale == null && this is ForwardingAudience -> { // We only run through each child if the locale is null (i.e. we're pulling it from the audience itself). - forEachAudience { child -> - child.sendTranslated(key, type, identity, locale, tags) - } + forEachAudience { child -> child.sendTranslated(key, locale, tags) } } else -> { // Try and get the locale from the audience, otherwise default, then translate and send! val targetLocale = locale ?: get(Identity.LOCALE).orElseGet(miniPhrase::defaultLocale) - sendMessage(identity, miniPhrase.translate(key, targetLocale, tags), type) + sendMessage(miniPhrase.translate(key, targetLocale, tags)) + } + } +} + +context(MiniPhraseContext) +public fun Audience.sendTranslatedIfPresent( + /** The key of the message. */ + key: String, + /** The locale to translate the message in, if not the default for the audience. */ + locale: Locale? = null, + // A builder of additional tags to use in the deserialization process. + tags: (TagResolverBuilder.() -> Unit)? = null, +) { + when { + this == Audience.empty() -> { + // Do nothing if this audience is the empty audience. + } + + locale == null && this is ForwardingAudience -> { + // We only run through each child if the locale is null (i.e. we're pulling it from the audience itself). + forEachAudience { child -> child.sendTranslated(key, locale, tags) } + } + + else -> { + // Try and get the locale from the audience, otherwise default, then translate and send! + val targetLocale = locale ?: get(Identity.LOCALE).orElseGet(miniPhrase::defaultLocale) + miniPhrase.translateOrNull(key, targetLocale, tags)?.let { sendMessage(it) } } } } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/audience/IterableExt.kt b/core/src/main/kotlin/dev/kezz/miniphrase/audience/IterableExt.kt index 3a838ca..cede84c 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/audience/IterableExt.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/audience/IterableExt.kt @@ -26,28 +26,23 @@ package dev.kezz.miniphrase.audience import dev.kezz.miniphrase.MiniPhraseContext import dev.kezz.miniphrase.tag.TagResolverBuilder import net.kyori.adventure.audience.Audience -import net.kyori.adventure.audience.MessageType -import net.kyori.adventure.identity.Identity import java.util.Locale /** Shorthand for [Audience.audience]. */ -public fun Iterable.asAudience(): Audience = - Audience.audience(this) +public fun Iterable.asAudience(): Audience = Audience.audience(this) /** @see [Audience.sendTranslated] */ context(MiniPhraseContext) public fun Iterable.sendTranslated( key: String, - type: MessageType = MessageType.CHAT, - identity: Identity = Identity.nil(), locale: Locale? = null, - tags: (TagResolverBuilder.() -> Unit)? = null + tags: (TagResolverBuilder.() -> Unit)? = null, ) { if (locale != null) { // If we've got an override locale, we can save rendering by wrapping this in an audience. - asAudience().sendTranslated(key, type, identity, locale, tags) + asAudience().sendTranslated(key, locale, tags) } else { // Otherwise, we need to pull it from each audience member, so just delegate. - forEach { audience -> audience.sendTranslated(key, type, identity, locale, tags) } + forEach { audience -> audience.sendTranslated(key, locale, tags) } } } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/EmptyTranslationRegistry.kt b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/EmptyTranslationRegistry.kt index 95a75cb..9d2c4ea 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/EmptyTranslationRegistry.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/EmptyTranslationRegistry.kt @@ -27,6 +27,17 @@ import java.util.Locale /** An empty translation registry. */ public object EmptyTranslationRegistry : TranslationRegistry { - override suspend fun reload() { } - override fun get(key: String, locale: Locale): String? = null + override fun reload() { } + + override fun get( + key: String, + locale: Locale, + ): String? = null + + override fun getList( + key: String, + locale: Locale, + ): List = listOf() + + override fun getLocales(): Set = setOf() } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/MapBasedTranslationRegistry.kt b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/MapBasedTranslationRegistry.kt index 9aec454..397a787 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/MapBasedTranslationRegistry.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/MapBasedTranslationRegistry.kt @@ -26,16 +26,20 @@ package dev.kezz.miniphrase.i18n import java.util.Locale /** A translation registry that is backed by a map populated by a supplier. */ -public class MapBasedTranslationRegistry( +public open class MapBasedTranslationRegistry( /** The supplier of content for the map, used in reloads. */ - private val supplier: suspend () -> Map> + private val supplier: () -> Map>, ) : TranslationRegistry { private var map: Map> = mapOf() - override suspend fun reload() { + override fun reload() { map = supplier() } - override fun get(key: String, locale: Locale): String? = - map[locale]?.get(key) + override fun get( + key: String, + locale: Locale, + ): String? = map[locale]?.get(key) + + override fun getLocales(): Set = map.keys } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/PropertiesFileTranslationRegistry.kt b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/PropertiesFileTranslationRegistry.kt new file mode 100644 index 0000000..2cbd26c --- /dev/null +++ b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/PropertiesFileTranslationRegistry.kt @@ -0,0 +1,78 @@ +/* + * MIT License + * + * Copyright (c) 2022 Kezz + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package dev.kezz.miniphrase.i18n + +import java.io.File +import java.io.FileInputStream +import java.io.InputStreamReader +import java.nio.charset.Charset +import java.nio.file.Files +import java.nio.file.StandardCopyOption +import java.util.Locale +import java.util.Properties + +/** + * A translation registry that is populated by looking for property files in [path]. + * If [fetchFromResources], it will look for any language files in the resources directory. + * + * Format: en_us.properties + */ +public class PropertiesFileTranslationRegistry( + private val path: File, + private val resourcesPrefix: String = "", + private val fetchFromResources: Boolean = true, +) : MapBasedTranslationRegistry({ + buildMap { + val exists = path.exists() + + if (exists && !path.isDirectory) return@buildMap + if (!exists) path.mkdirs() + + Locale.getAvailableLocales().forEach { language -> + val languageKey = language.toLanguageTag().lowercase().replace("-", "_") + val translationsFile = File(path, "$languageKey.properties") + + // If the file doesn't exist we check for the file in the resources and copy it + // if the file exists there. + if (!translationsFile.exists() && fetchFromResources) { + val resourceStream = javaClass.getResourceAsStream("/$resourcesPrefix$languageKey.properties") ?: return@forEach + + translationsFile.createNewFile() + Files.copy(resourceStream, translationsFile.getAbsoluteFile().toPath(), StandardCopyOption.REPLACE_EXISTING) + } + + // If there is a file we read its contents and save it into the map. + if (translationsFile.exists()) { + val inputStream = FileInputStream(translationsFile) + + val properties = Properties() + + properties.load(InputStreamReader(inputStream, Charset.forName("UTF-8"))) + inputStream.close() + + put(language, properties.stringPropertyNames().associateWith { key -> properties.getProperty(key) }) + } + } + } + }) diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/TranslationRegistry.kt b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/TranslationRegistry.kt index 10cd019..a0f5438 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/i18n/TranslationRegistry.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/i18n/TranslationRegistry.kt @@ -27,10 +27,24 @@ import java.util.Locale /** A registry of translations. */ public interface TranslationRegistry { - /** Loads or reloads all translations. */ - public suspend fun reload() + public fun reload() /** Returns a translation for a given [key] in a [locale]. */ - public operator fun get(key: String, locale: Locale): String? + public operator fun get( + key: String, + locale: Locale, + ): String? + + /** + * Returns a translation list for a given [key] in a [locale]. + * List members are split with "\n" inside a translation. + */ + public fun getList( + key: String, + locale: Locale, + ): List? = get(key, locale)?.split("\n") + + /** Returns the list of registered locales. */ + public fun getLocales(): Set } diff --git a/core/src/main/kotlin/dev/kezz/miniphrase/tag/TagResolverBuilder.kt b/core/src/main/kotlin/dev/kezz/miniphrase/tag/TagResolverBuilder.kt index a6d2a59..0e48dce 100644 --- a/core/src/main/kotlin/dev/kezz/miniphrase/tag/TagResolverBuilder.kt +++ b/core/src/main/kotlin/dev/kezz/miniphrase/tag/TagResolverBuilder.kt @@ -23,8 +23,8 @@ */ package dev.kezz.miniphrase.tag -import dev.kezz.miniphrase.MiniPhraseContext import dev.kezz.miniphrase.MiniPhrase +import dev.kezz.miniphrase.MiniPhraseContext import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.Context import net.kyori.adventure.text.minimessage.tag.Tag @@ -37,71 +37,102 @@ import java.util.Locale * helper functions for MiniPhrase-specific elements. */ public class TagResolverBuilder private constructor( - override val miniPhrase: MiniPhrase + override val miniPhrase: MiniPhrase, ) : MiniPhraseContext { - public companion object { private const val PHRASE_TAG_NAME: String = "phrase" /** Configures and builds a tag resolver using the provided builder and MiniPhrase instance. */ - public fun configureAndBuild(miniPhrase: MiniPhrase, builder: TagResolverBuilder.() -> Unit): TagResolver = - TagResolverBuilder(miniPhrase).apply(builder).build() + public fun configureAndBuild( + miniPhrase: MiniPhrase, + builder: TagResolverBuilder.() -> Unit, + ): TagResolver = TagResolverBuilder(miniPhrase).apply(builder).build() } private val builder: TagResolver.Builder = TagResolver.builder() /** Adds a parsed placeholder to this builder. */ - public fun parsed(key: String, value: Any?) { + public fun parsed( + key: String, + value: Any?, + ) { parsed(key, value.toString()) } /** Adds a parsed placeholder to this builder. */ - public fun parsed(key: String, value: String) { + public fun parsed( + key: String, + value: String, + ) { tag(key, Tag.preProcessParsed(value)) } /** Adds a parsed placeholder to this builder. The value is lazily computed. */ - public fun parsed(key: String, value: () -> String) { + public fun parsed( + key: String, + value: () -> String, + ) { tag(key) { _, _ -> Tag.preProcessParsed(value()) } } /** Adds an unparsed placeholder to this builder. */ - public fun unparsed(key: String, value: Any?) { + public fun unparsed( + key: String, + value: Any?, + ) { unparsed(key, value.toString()) } /** Adds an unparsed placeholder to this builder. */ - public fun unparsed(key: String, value: String) { + public fun unparsed( + key: String, + value: String, + ) { tag(key, Tag.inserting(Component.text(value))) } /** Adds an unparsed placeholder to this builder. The value is lazily computed. */ @JvmName("unparsedAny") - public fun unparsed(key: String, value: () -> Any?) { + public fun unparsed( + key: String, + value: () -> Any?, + ) { unparsed(key) { value().toString() } } /** Adds an unparsed placeholder to this builder. The value is lazily computed. */ - public fun unparsed(key: String, value: () -> String) { + public fun unparsed( + key: String, + value: () -> String, + ) { tag(key) { _, _ -> Tag.inserting(Component.text(value())) } } /** Adds a tag that inserts a component. */ - public fun inserting(key: String, value: Component) { + public fun inserting( + key: String, + value: Component, + ) { tag(key, Tag.inserting(value)) } /** Adds a tag to this builder. */ - public fun tag(key: String, tag: Tag) { + public fun tag( + key: String, + tag: Tag, + ) { builder.tag(key, tag) } /** Constructs a tag and adds it to this builder. */ - public fun tag(key: String, tag: (arguments: ArgumentQueue, ctx: Context) -> Tag) { + public fun tag( + key: String, + tag: (arguments: ArgumentQueue, ctx: Context) -> Tag, + ) { builder.tag(key, tag) } @@ -114,11 +145,12 @@ public class TagResolverBuilder private constructor( public fun withPhraseTag(locale: Locale? = null) { tag(PHRASE_TAG_NAME) { arguments, ctx -> val key = arguments.popOr("No key provided.").lowerValue() - val targetLocale = arguments.peek()?.let { arg -> - runCatching { Locale.forLanguageTag(arg.lowerValue()) }.getOrElse { exception -> - throw ctx.newException("Invalid language tag $arg.", exception, arguments) - } - } ?: locale ?: miniPhrase.defaultLocale + val targetLocale = + arguments.peek()?.let { arg -> + runCatching { Locale.forLanguageTag(arg.lowerValue()) }.getOrElse { exception -> + throw ctx.newException("Invalid language tag $arg.", exception, arguments) + } + } ?: locale ?: miniPhrase.defaultLocale val result = miniPhrase.translationRegistry[key, targetLocale] @@ -131,6 +163,5 @@ public class TagResolverBuilder private constructor( } /** Creates a tag resolver from this builder. */ - public fun build(): TagResolver = - builder.build() + public fun build(): TagResolver = builder.build() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cca3783..8f357ec 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,9 @@ [versions] -indra = "2.1.1" -kotlin = "1.6.21" +indra = "3.1.3" +kotlin = "1.9.21" [libraries] -adventure-minimessage = { group = "net.kyori", name = "adventure-text-minimessage", version = "4.10.1" } +adventure-minimessage = { group = "net.kyori", name = "adventure-text-minimessage", version = "4.17.0" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } [plugins] @@ -11,4 +11,4 @@ indra = { id = "net.kyori.indra", version.ref = "indra" } indra-license = { id = "net.kyori.indra.license-header", version.ref = "indra" } indra-sonatype = { id = "net.kyori.indra.publishing.sonatype", version.ref = "indra" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -ktlint = { id = "org.jlleitschuh.gradle.ktlint", version = "10.3.0" } +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version = "12.0.3" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fc..a595206 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 68bee5b..0b13ecd 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,7 +8,7 @@ dependencyResolutionManagement { rootProject.name = "miniphrase-parent" sequenceOf( - "core" + "core", ).forEach { projectName -> include("miniphrase-$projectName") project(":miniphrase-$projectName").projectDir = file(projectName)