From da3e1a72d74e64cc77a9b66bfe2eea30f50a0f9a Mon Sep 17 00:00:00 2001 From: Sam Hill Date: Wed, 2 Sep 2026 11:50:55 -0400 Subject: [PATCH 1/5] Re-enable Windows and Linux native tests on matching hosts --- .github/workflows/build.yml | 2 +- sqliter-driver/build.gradle.kts | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 47049b6..1ceeee0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ jobs: with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain libsqlite + install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-sqlite3 - name: Setup Gradle uses: gradle/actions/setup-gradle@v6 diff --git a/sqliter-driver/build.gradle.kts b/sqliter-driver/build.gradle.kts index 0f9ec9a..a892ff7 100644 --- a/sqliter-driver/build.gradle.kts +++ b/sqliter-driver/build.gradle.kts @@ -83,11 +83,14 @@ mavenPublishing { publishToMavenCentral(automaticRelease = true) } -listOf( - "linuxX64Test", - "linuxArm64Test", - "linkDebugTestLinuxX64", - "linkDebugTestLinuxArm64", - "mingwX64Test", - "linkDebugTestMingwX64", -).forEach { tasks.findByName(it)?.enabled = false } +val disabledTestLinks = mutableListOf("linkDebugTestLinuxArm64") + +if (!HostManager.hostIsLinux) { + disabledTestLinks += "linkDebugTestLinuxX64" +} + +if (!HostManager.hostIsMingw) { + disabledTestLinks += "linkDebugTestMingwX64" +} + +disabledTestLinks.forEach { tasks.findByName(it)?.enabled = false } From 2deb2d63277ced43183b22fc75fe760318313afa Mon Sep 17 00:00:00 2001 From: Sam Hill Date: Wed, 2 Sep 2026 13:49:36 -0400 Subject: [PATCH 2/5] Point setup-msys2 at the runner's preinstalled MSYS2 so sqlite3 is findable --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ceeee0..cafeccb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,7 @@ jobs: msystem: MINGW64 update: true install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-sqlite3 + release: false - name: Setup Gradle uses: gradle/actions/setup-gradle@v6 From e7d3e90b496ba7c812b62ba7974a10f8d3cbc422 Mon Sep 17 00:00:00 2001 From: Sam Hill Date: Wed, 2 Sep 2026 14:53:50 -0400 Subject: [PATCH 3/5] Don't install extra toolchain --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cafeccb..a769d6a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ jobs: with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-sqlite3 + install: mingw-w64-x86_64-sqlite3 release: false - name: Setup Gradle From 16113fc15d048c546dc0693da833dd8325be0c46 Mon Sep 17 00:00:00 2001 From: Sam Hill Date: Wed, 2 Sep 2026 15:56:14 -0400 Subject: [PATCH 4/5] Normalize forward slashes in the Windows File path handling The three databasePathRemoves* tests fail on mingwX64. They were added in f59c6b1 along with a mechanical port of the file:// handling to all three File.kt copies, but the mingw tests have never run, so the port was never checked against a Windows host. mingw's File sets separatorChar to a back slash, and both fixSlashes and join compared against it directly. Forward slashes were therefore not separators: "//tmp//" collapsed to nothing, and join saw no trailing separator and inserted one, so File("//tmp//", "testdb") produced "//tmp//\testdb". Windows accepts either slash direction, so treat both as separators and normalize to separatorChar. Paths built from USERPROFILE are unaffected as they already use back slashes; only inputs that previously produced mixed garbage change. fixSlashes also reused the original string whenever the length was unchanged. That held when the only edits were collapsing and truncating, but rewriting slashes in place keeps the length, so drop the shortcut and always rebuild. The tests asserted POSIX separators. Derive the expected separator from Platform.osFamily so they assert the same normalization on every host. --- .../co/touchlab/sqliter/internal/File.kt | 18 +++++++++++------- .../sqliter/DatabaseConfigurationTest.kt | 11 ++++++++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/sqliter-driver/src/mingwMain/kotlin/co/touchlab/sqliter/internal/File.kt b/sqliter-driver/src/mingwMain/kotlin/co/touchlab/sqliter/internal/File.kt index 59b9141..af4d3c1 100644 --- a/sqliter-driver/src/mingwMain/kotlin/co/touchlab/sqliter/internal/File.kt +++ b/sqliter-driver/src/mingwMain/kotlin/co/touchlab/sqliter/internal/File.kt @@ -71,7 +71,8 @@ internal actual class File(dirPath:String? = null, name:String) { */ constructor(dir: File, name: String) : this(dir.path, name) - // Removes duplicate adjacent back slashes and any trailing back slashes. + // Removes duplicate adjacent separators and any trailing separator. Windows accepts either + // slash direction, so both count as separators and are normalized to [separatorChar]. private fun fixSlashes(origPath: String): String { // Remove duplicate adjacent slashes. var lastWasSlash = false @@ -81,7 +82,7 @@ internal actual class File(dirPath:String? = null, name:String) { val initialIndex = if (origPath.startsWith("file://", true)) 7 else 0 for (i in initialIndex until length) { val ch = newPath[i] - if (ch == separatorChar) { + if (isSeparator(ch)) { if (!lastWasSlash) { newPath[newLength++] = separatorChar lastWasSlash = true @@ -97,21 +98,24 @@ internal actual class File(dirPath:String? = null, name:String) { newLength-- } - // Reuse the original string if possible. - return if (newLength != length) buildString(newLength) { + // Always rebuild. An unchanged length doesn't mean an unchanged string here, as forward + // slashes are rewritten in place without shortening the path. + return buildString(newLength) { append(newPath) setLength(newLength) - } else origPath + } } + private fun isSeparator(ch: Char): Boolean = ch == '/' || ch == '\\' + /** * Returns the combination of the prefix and suffix with a back slash added if necessary. */ private fun join(prefix: String, suffix: String): String { val prefixLength = prefix.length - var haveSlash = prefixLength > 0 && prefix[prefixLength - 1] == separatorChar + var haveSlash = prefixLength > 0 && isSeparator(prefix[prefixLength - 1]) if (!haveSlash) { - haveSlash = suffix.isNotEmpty() && suffix[0] == separatorChar + haveSlash = suffix.isNotEmpty() && isSeparator(suffix[0]) } return if (haveSlash) prefix + suffix else prefix + separatorChar + suffix } diff --git a/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt b/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt index c98594a..8e4af3a 100644 --- a/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt +++ b/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt @@ -16,10 +16,15 @@ package co.touchlab.sqliter +import kotlin.native.OsFamily +import kotlin.native.Platform import kotlin.test.* class DatabaseConfigurationTest : BaseDatabaseTest(){ + // Paths are normalized to the host's separator, which is a back slash on Windows. + private val sep = if (Platform.osFamily == OsFamily.WINDOWS) "\\" else "/" + @Test fun pathTest(){ val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, null) @@ -29,19 +34,19 @@ class DatabaseConfigurationTest : BaseDatabaseTest(){ @Test fun databasePathRemovesExtraSlashes() { val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "//tmp//") - assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + assertEquals("${sep}tmp$sep$TEST_DB_NAME", dbPathString) } @Test fun databasePathRemovesFileUrlPrefix() { val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "file:///tmp/") - assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + assertEquals("${sep}tmp$sep$TEST_DB_NAME", dbPathString) } @Test fun databasePathRemovesFileUrlPrefixInCaps() { val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "FILE:///tmp/") - assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + assertEquals("${sep}tmp$sep$TEST_DB_NAME", dbPathString) } @Test From 1c91a8649c76dd0be81dddbe94b2b7e015429ce7 Mon Sep 17 00:00:00 2001 From: Sam Hill Date: Wed, 2 Sep 2026 16:10:00 -0400 Subject: [PATCH 5/5] Focus on windows for now --- .github/workflows/build.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a769d6a..6d97cd8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ macOS-latest, windows-latest, ubuntu-latest ] + os: [ windows-latest ] runs-on: ${{matrix.os}} steps: - name: Checkout the repo @@ -35,14 +35,6 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v6 - - name: Cache konan - uses: actions/cache@v4 - with: - path: ~/.konan - key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Update Environment Variables if: matrix.os == 'windows-latest' shell: bash