From ac62893ddb6a7344b1bd63e8c617d59c5efb3461 Mon Sep 17 00:00:00 2001 From: JojoIV Date: Sun, 19 Jul 2026 23:31:12 +0200 Subject: [PATCH 1/4] Upgrade to Kotlin 2.4.10, upgrade dependencies and migrate to BuildKonfig --- app/build.gradle.kts | 35 +++++++++++-------- .../de/jonasbroeckmann/nav/Constants.kt | 6 ++-- .../nav/app/macros/MacroSymbolScopeBase.kt | 2 +- .../de/jonasbroeckmann/nav/update/Version.kt | 4 +-- .../nav/utils/Terminal.mingw.kt | 2 +- build.gradle.kts | 8 ++--- framework/build.gradle.kts | 16 +++++---- .../jonasbroeckmann/nav/framework/ui/Hints.kt | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 7 ++-- 10 files changed, 46 insertions(+), 38 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9e9108d..52a3fae 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,4 @@ +import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.* import com.netflix.gradle.plugins.deb.Deb import dev.detekt.gradle.Detekt import org.gradle.crypto.checksum.Checksum @@ -10,7 +11,7 @@ plugins { kotlin("multiplatform") kotlin("plugin.serialization") id("dev.detekt") - id("com.github.gmazzo.buildconfig") + id("com.codingfeline.buildkonfig") id("org.gradle.crypto.checksum") id("com.netflix.nebula.ospackage") } @@ -22,19 +23,25 @@ description = "The interactive and stylish replacement for ls & cd!" val binaryName = "nav" -buildConfig { - buildConfigField("String", "VERSION", "\"$version\"") - buildConfigField("String", "BINARY_NAME", "\"$binaryName\"") +buildkonfig { + packageName = "$group" + defaultConfigs { + buildConfigField(STRING, "VERSION", "$version") + buildConfigField(STRING, "BINARY_NAME", binaryName) + } } kotlin { compilerOptions { freeCompilerArgs.addAll( - "-Xcontext-parameters", + "-Xexplicit-context-arguments", + "-Xcollection-literals", + "-Xintrinsic-const-evaluation", + "-Xallow-returns-result-of", "-Xcontext-sensitive-resolution", - "-Xnested-type-aliases", + "-Xexpect-actual-classes", + "-Xreturn-value-checker=check", "-Xconsistent-data-class-copy-visibility", - "-Xallow-holdsin-contract", ) } @@ -55,13 +62,13 @@ kotlin { } sourceSets { - val ktorVersion = "3.3.1" + val ktorVersion = "3.5.1" commonMain.dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0") - val kotlinxIOVersion = "0.8.0" + val kotlinxIOVersion = "0.9.1" implementation("org.jetbrains.kotlinx:kotlinx-io-core:$kotlinxIOVersion") implementation("org.jetbrains.kotlinx:kotlinx-io-okio:$kotlinxIOVersion") @@ -69,9 +76,9 @@ kotlin { implementation("com.akuleshov7:ktoml-core:$ktomlVersion") implementation("com.akuleshov7:ktoml-file:$ktomlVersion") - implementation("com.charleskorn.kaml:kaml:0.97.0") + implementation("com.charleskorn.kaml:kaml:0.104.0") - implementation("com.github.ajalt.clikt:clikt:5.0.3") + implementation("com.github.ajalt.clikt:clikt:5.1.0") val mordantVersion = "3.0.2" implementation("com.github.ajalt.mordant:mordant:$mordantVersion") @@ -98,7 +105,7 @@ kotlin { } dependencies { - detektPlugins("dev.detekt:detekt-rules-ktlint-wrapper:2.0.0-alpha.0") + detektPlugins("dev.detekt:detekt-rules-ktlint-wrapper:2.0.0-alpha.5") } tasks.withType().configureEach { diff --git a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/Constants.kt b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/Constants.kt index 6461280..639f58e 100644 --- a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/Constants.kt +++ b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/Constants.kt @@ -1,10 +1,8 @@ package de.jonasbroeckmann.nav -import de.jonasbroeckmann.nav.app.BuildConfig - object Constants { - val BinaryName get() = BuildConfig.BINARY_NAME - val Version get() = BuildConfig.VERSION + val BinaryName get() = BuildKonfig.BINARY_NAME + val Version get() = BuildKonfig.VERSION val RepositoryUrl get() = "https://github.com/Jojo4GH/nav" val IssuesUrl get() = "$RepositoryUrl/issues" diff --git a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/app/macros/MacroSymbolScopeBase.kt b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/app/macros/MacroSymbolScopeBase.kt index 8c14953..9742e64 100644 --- a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/app/macros/MacroSymbolScopeBase.kt +++ b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/app/macros/MacroSymbolScopeBase.kt @@ -9,7 +9,7 @@ open class MacroSymbolScopeBase( ) : MacroSymbolScope { protected open val variables = mutableMapOf() - override operator fun get(symbol: MacroSymbol) = context(context, stateProvider) { + override operator fun get(symbol: MacroSymbol): String = context(context, stateProvider) { when (symbol) { is MacroSymbol.EnvironmentVariable -> symbol.get() is MacroSymbol.Generic -> { diff --git a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt index 0ae7367..f02a3b5 100644 --- a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt +++ b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt @@ -1,7 +1,7 @@ package de.jonasbroeckmann.nav.update import de.jonasbroeckmann.nav.Constants -import de.jonasbroeckmann.nav.app.BuildConfig +import de.jonasbroeckmann.nav.BuildKonfig import kotlin.text.get data class Version( @@ -45,7 +45,7 @@ data class Version( } val Current by lazy { - of(Constants.Version) ?: throw AssertionError("Could not parse current version '${BuildConfig.VERSION}'") + of(Constants.Version) ?: throw AssertionError("Could not parse current version '${BuildKonfig.VERSION}'") } } } diff --git a/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt b/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt index e4a6671..c92e6a7 100644 --- a/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt +++ b/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt @@ -68,7 +68,7 @@ private object TerminalInterfaceNativeWindows : StandardTerminalInterface() { } val inputEvents = allocArray(1) val eventsRead = alloc() - ReadConsoleInput!!(stdinHandle, inputEvents, 1u, eventsRead.ptr) + val _ = ReadConsoleInput!!(stdinHandle, inputEvents, 1u, eventsRead.ptr) if (eventsRead.value == 0u) { throw ConsoleException("Error reading from console input") } diff --git a/build.gradle.kts b/build.gradle.kts index 389dfbd..249b056 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,9 @@ plugins { - val kotlinVersion = "2.2.20" + val kotlinVersion = "2.4.10" kotlin("multiplatform") version kotlinVersion apply false kotlin("plugin.serialization") version kotlinVersion apply false - id("dev.detekt") version "2.0.0-alpha.0" apply false - id("com.github.gmazzo.buildconfig") version "5.6.8" apply false + id("dev.detekt") version "2.0.0-alpha.5" apply false + id("com.codingfeline.buildkonfig") version "0.22.0" apply false id("org.gradle.crypto.checksum") version "1.4.0" apply false - id("com.netflix.nebula.ospackage") version "12.1.1" apply false + id("com.netflix.nebula.ospackage") version "12.3.0" apply false } diff --git a/framework/build.gradle.kts b/framework/build.gradle.kts index fa9c732..80ed8ab 100644 --- a/framework/build.gradle.kts +++ b/framework/build.gradle.kts @@ -11,10 +11,14 @@ group = "de.jonasbroeckmann.nav" kotlin { compilerOptions { freeCompilerArgs.addAll( - "-Xcontext-parameters", + "-Xexplicit-context-arguments", + "-Xcollection-literals", + "-Xintrinsic-const-evaluation", + "-Xallow-returns-result-of", "-Xcontext-sensitive-resolution", - "-Xnested-type-aliases", - "-Xconsistent-data-class-copy-visibility" + "-Xexpect-actual-classes", + "-Xreturn-value-checker=check", + "-Xconsistent-data-class-copy-visibility", ) } @@ -27,10 +31,10 @@ kotlin { sourceSets { commonMain.dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0") - val kotlinxIOVersion = "0.8.0" + val kotlinxIOVersion = "0.9.1" implementation("org.jetbrains.kotlinx:kotlinx-io-core:$kotlinxIOVersion") implementation("org.jetbrains.kotlinx:kotlinx-io-okio:$kotlinxIOVersion") diff --git a/framework/src/commonMain/kotlin/de/jonasbroeckmann/nav/framework/ui/Hints.kt b/framework/src/commonMain/kotlin/de/jonasbroeckmann/nav/framework/ui/Hints.kt index 557aae1..c71620f 100644 --- a/framework/src/commonMain/kotlin/de/jonasbroeckmann/nav/framework/ui/Hints.kt +++ b/framework/src/commonMain/kotlin/de/jonasbroeckmann/nav/framework/ui/Hints.kt @@ -76,7 +76,7 @@ class HintsBuilder internal constructor(private val defaultStrongSpacing: String inputMode: InputMode?, weakSpacing: Boolean = false, render: context(Context) A.() -> String - ) = context(context) { + ): Unit = context(context) { if (!action.isShown(inputMode)) return add(weakSpacing) { action.render() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a441313..a351597 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index 3a37a75..4982d86 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,10 +12,9 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) } +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + // Project structure rootProject.name = "nav" +include("framework") include("app") - -enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") - -include("framework") \ No newline at end of file From cf294b9f0e64ede3f707897286fe3051bb04ba27 Mon Sep 17 00:00:00 2001 From: JojoIV Date: Sun, 19 Jul 2026 23:40:44 +0200 Subject: [PATCH 2/4] Revert Detekt version change --- app/build.gradle.kts | 2 +- build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 52a3fae..19ff926 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -105,7 +105,7 @@ kotlin { } dependencies { - detektPlugins("dev.detekt:detekt-rules-ktlint-wrapper:2.0.0-alpha.5") + detektPlugins("dev.detekt:detekt-rules-ktlint-wrapper:2.0.0-alpha.0") } tasks.withType().configureEach { diff --git a/build.gradle.kts b/build.gradle.kts index 249b056..0e5d1d3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { val kotlinVersion = "2.4.10" kotlin("multiplatform") version kotlinVersion apply false kotlin("plugin.serialization") version kotlinVersion apply false - id("dev.detekt") version "2.0.0-alpha.5" apply false + id("dev.detekt") version "2.0.0-alpha.0" apply false id("com.codingfeline.buildkonfig") version "0.22.0" apply false id("org.gradle.crypto.checksum") version "1.4.0" apply false id("com.netflix.nebula.ospackage") version "12.3.0" apply false From 273579ee9d6dc607f1df8a0be1b4837710ada3a4 Mon Sep 17 00:00:00 2001 From: JojoIV Date: Sun, 19 Jul 2026 23:46:59 +0200 Subject: [PATCH 3/4] detekt --- app/build.gradle.kts | 6 +++--- .../kotlin/de/jonasbroeckmann/nav/update/Version.kt | 2 +- .../kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 19ff926..3d2713f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -26,8 +26,8 @@ val binaryName = "nav" buildkonfig { packageName = "$group" defaultConfigs { - buildConfigField(STRING, "VERSION", "$version") - buildConfigField(STRING, "BINARY_NAME", binaryName) + buildConfigField(STRING, "VERSION", "$version", const = true) + buildConfigField(STRING, "BINARY_NAME", binaryName, const = true) } } @@ -109,7 +109,7 @@ dependencies { } tasks.withType().configureEach { - exclude("de/jonasbroeckmann/nav/app/BuildConfig.kt") + exclude("de/jonasbroeckmann/nav/BuildKonfig.kt") } tasks.register("detektAll") { diff --git a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt index f02a3b5..b39f2b3 100644 --- a/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt +++ b/app/src/commonMain/kotlin/de/jonasbroeckmann/nav/update/Version.kt @@ -1,7 +1,7 @@ package de.jonasbroeckmann.nav.update -import de.jonasbroeckmann.nav.Constants import de.jonasbroeckmann.nav.BuildKonfig +import de.jonasbroeckmann.nav.Constants import kotlin.text.get data class Version( diff --git a/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt b/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt index c92e6a7..94c66f1 100644 --- a/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt +++ b/app/src/mingwMain/kotlin/de/jonasbroeckmann/nav/utils/Terminal.mingw.kt @@ -68,7 +68,10 @@ private object TerminalInterfaceNativeWindows : StandardTerminalInterface() { } val inputEvents = allocArray(1) val eventsRead = alloc() + + @Suppress("detekt:BackingPropertyNaming") val _ = ReadConsoleInput!!(stdinHandle, inputEvents, 1u, eventsRead.ptr) + if (eventsRead.value == 0u) { throw ConsoleException("Error reading from console input") } From ff4ea774e3fff5c3f5b2430575ecb7fbf6ca5847 Mon Sep 17 00:00:00 2001 From: JojoIV Date: Mon, 20 Jul 2026 00:10:02 +0200 Subject: [PATCH 4/4] Disable native cache for Linux X64 due to persisting bug --- app/build.gradle.kts | 14 ++++++++++++++ gradle.properties | 2 -- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3d2713f..c8fde3c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,10 +2,13 @@ import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.* import com.netflix.gradle.plugins.deb.Deb import dev.detekt.gradle.Detekt import org.gradle.crypto.checksum.Checksum +import org.jetbrains.kotlin.gradle.plugin.mpp.DisableCacheInKotlinVersion +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCacheApi import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.target.Architecture +import java.net.URI plugins { kotlin("multiplatform") @@ -57,6 +60,17 @@ kotlin { executable { baseName = binaryName entryPoint = "$group.main" + + if (target.konanTarget == KonanTarget.LINUX_X64) { + @OptIn(KotlinNativeCacheApi::class) + disableNativeCache( + version = DisableCacheInKotlinVersion.`2_4_10`, + reason = "Cache bug with mordant", + issueUrl = URI( + "https://youtrack.jetbrains.com/issue/KT-75928/ld.lld-error-duplicate-symbol-when-enabling-.konan-cache" + ) + ) + } } } } diff --git a/gradle.properties b/gradle.properties index 5c87ce0..2deead4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,3 @@ org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=512M # Kotlin kotlin.code.style=official kotlin.incremental.native=true -# https://youtrack.jetbrains.com/issue/KT-75928/ld.lld-error-duplicate-symbol-when-enabling-.konan-cache -kotlin.native.cacheKind.linuxX64=none