Skip to content

Commit c168fd9

Browse files
committed
Add Kotlin/JS
1 parent 3f51e6e commit c168fd9

File tree

22 files changed

+2071
-41
lines changed

22 files changed

+2071
-41
lines changed

.gitattributes

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
kt/gradlew linguist-generated
33
kt/gradlew.bat linguist-generated
44

5+
# generated by Kotlin/JS
6+
kt/kotlin-js-store/yarn.lock
7+
58
# generated by Poetry
69
py/poetry.lock linguist-generated
710

.github/workflows/kt.yml

+23
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ jobs:
4646
path: |
4747
kt/aoc2023-exe/build/bin/*/debugExecutable/*.kexe
4848
kt/aoc2023-exe/build/bin/*/releaseExecutable/*.kexe
49+
- uses: actions/upload-artifact@v3
50+
with:
51+
name: aoc2023-js
52+
path: kt/build/js/packages/aoc2023-aoc2023-exe/kotlin/*
4953

5054
run-jvm:
5155
needs: [ get-inputs, build ]
@@ -84,3 +88,22 @@ jobs:
8488
- run: linuxX64/releaseExecutable/aoc2023-exe.kexe
8589
env:
8690
AOC2023_DATADIR: inputs
91+
92+
run-node:
93+
needs: [ get-inputs, build ]
94+
runs-on: ubuntu-latest
95+
96+
steps:
97+
- uses: actions/download-artifact@v3
98+
with:
99+
name: inputs
100+
path: inputs
101+
- uses: actions/download-artifact@v3
102+
with:
103+
name: aoc2023-js
104+
- uses: actions/setup-node@v4
105+
with:
106+
node-version: 21.3.0
107+
- run: node aoc2023-aoc2023-exe.js
108+
env:
109+
AOC2023_DATADIR: inputs

kt/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Run [kotlinx.benchmark](https://github.com/Kotlin/kotlinx-benchmark) ([JMH](http
1818
Print solutions for the inputs provided in local data files:
1919

2020
```sh
21-
./gradlew :aoc2023-exe:jvmRun :aoc2023-exe:run{Debug,Release}Executable{LinuxX64,Macos{X64,Arm64}}
21+
./gradlew :aoc2023-exe:jvmRun :aoc2023-exe:runReleaseExecutable{LinuxX64,Macos{X64,Arm64}} :aoc2023-exe:jsNodeProductionRun
2222
```
2323

2424
Run all checks, including [Detekt](https://detekt.github.io/) static code analysis and [ktlint](https://ktlint.github.io/) formatter:

kt/aoc2023-exe/build.gradle.kts

+14-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ plugins {
99
id("com.github.ephemient.aoc2023.detekt")
1010
id("com.github.ephemient.aoc2023.kotlin.multiplatform.jvm.platform")
1111
id("com.github.ephemient.aoc2023.kotlin.multiplatform.native.platforms")
12+
id("com.github.ephemient.aoc2023.kotlin.multiplatform.js.platform")
1213
}
1314

1415
application {
@@ -20,6 +21,12 @@ kotlin {
2021
withJava()
2122
}
2223

24+
js {
25+
useCommonJs()
26+
nodejs()
27+
binaries.executable()
28+
}
29+
2330
targets.withType<KotlinJvmTarget> {
2431
mainRun {
2532
mainClass = application.mainClass
@@ -36,7 +43,6 @@ kotlin {
3643
commonMain {
3744
dependencies {
3845
implementation(projects.aoc2023Lib)
39-
implementation(libs.kotlinx.coroutines)
4046
}
4147
}
4248

@@ -51,6 +57,12 @@ kotlin {
5157
implementation(libs.okio)
5258
}
5359
}
60+
61+
jsMain {
62+
dependencies {
63+
implementation(libs.kotlin.wrappers.node)
64+
}
65+
}
5466
}
5567
}
5668

@@ -62,6 +74,7 @@ benchmark {
6274
targets {
6375
register("jvmTest")
6476
}
77+
6578
configurations {
6679
getByName("main") {
6780
warmups = 1

kt/aoc2023-exe/src/commonMain/kotlin/com/github/ephemient/aoc2023/exe/CommonMain.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package com.github.ephemient.aoc2023.exe
22

33
import com.github.ephemient.aoc2023.days
4-
import kotlinx.coroutines.Dispatchers
5-
import kotlinx.coroutines.withContext
64

7-
internal suspend fun mainImpl(vararg args: String): Unit = withContext(Dispatchers.Default) {
5+
internal fun mainImpl(args: Array<out String>) {
86
for (day in days) {
97
if (args.isNotEmpty() && day.name !in args) continue
108
println("Day ${day.name}")
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package com.github.ephemient.aoc2023.exe
22

3-
internal expect suspend fun getDayInput(day: Int): String
3+
internal expect fun getDayInput(day: Int): String

kt/aoc2023-exe/src/commonTest/kotlin/com/github/ephemient/aoc2023/exe/Day1Bench.kt

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@ import kotlinx.benchmark.Benchmark
55
import kotlinx.benchmark.Scope
66
import kotlinx.benchmark.Setup
77
import kotlinx.benchmark.State
8-
import kotlinx.coroutines.runBlocking
98

109
@State(Scope.Benchmark)
1110
class Day1Bench {
1211
private lateinit var input: String
1312

1413
@Setup
1514
fun setup() {
16-
input = runBlocking {
17-
getDayInput(1)
18-
}
15+
input = getDayInput(1)
1916
}
2017

2118
@Benchmark

kt/aoc2023-exe/src/commonTest/kotlin/com/github/ephemient/aoc2023/exe/Day2Bench.kt

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@ import kotlinx.benchmark.Benchmark
55
import kotlinx.benchmark.Scope
66
import kotlinx.benchmark.Setup
77
import kotlinx.benchmark.State
8-
import kotlinx.coroutines.runBlocking
98

109
@State(Scope.Benchmark)
1110
class Day2Bench {
1211
private lateinit var input: String
1312

1413
@Setup
1514
fun setup() {
16-
input = runBlocking {
17-
getDayInput(2)
18-
}
15+
input = getDayInput(2)
1916
}
2017

2118
@Benchmark
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.github.ephemient.aoc2023.exe
2+
3+
import node.buffer.BufferEncoding
4+
import node.fs.readFileSync
5+
import node.process.process
6+
7+
internal actual fun getDayInput(day: Int): String {
8+
val dataDir = process.env["AOC2023_DATADIR"]?.ifEmpty { null } ?: "."
9+
return readFileSync("$dataDir/day$day.txt", BufferEncoding.utf8)
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.github.ephemient.aoc2023.exe
2+
3+
import node.process.process
4+
5+
@ExperimentalJsExport
6+
@JsExport
7+
fun main() {
8+
mainImpl(with(process.argv) { copyOfRange(2, size) })
9+
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package com.github.ephemient.aoc2023.exe
22

3-
import kotlinx.coroutines.Dispatchers
4-
import kotlinx.coroutines.withContext
53
import java.io.File
64

7-
@Suppress("InjectDispatcher")
8-
internal actual suspend fun getDayInput(day: Int): String = withContext(Dispatchers.IO) {
5+
internal actual fun getDayInput(day: Int): String =
96
File(System.getenv("AOC2023_DATADIR")?.ifEmpty { null } ?: ".", "day$day.txt").readText()
10-
}

kt/aoc2023-exe/src/jvmMain/kotlin/com/github/ephemient/aoc2023/exe/JvmMain.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
package com.github.ephemient.aoc2023.exe
44

5-
suspend fun main(vararg args: String): Unit = mainImpl(*args)
5+
fun main(vararg args: String) {
6+
mainImpl(args)
7+
}

kt/aoc2023-exe/src/nativeMain/kotlin/com/github/ephemient/aoc2023/exe/IO.kt

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ package com.github.ephemient.aoc2023.exe
22

33
import kotlinx.cinterop.ExperimentalForeignApi
44
import kotlinx.cinterop.toKString
5-
import kotlinx.coroutines.Dispatchers
6-
import kotlinx.coroutines.IO
7-
import kotlinx.coroutines.withContext
85
import okio.Path.Companion.toPath
96
import okio.buffer
107
import platform.posix.getenv
118

129
@OptIn(ExperimentalForeignApi::class)
13-
internal actual suspend fun getDayInput(day: Int): String = withContext(Dispatchers.IO) {
10+
internal actual fun getDayInput(day: Int): String {
1411
val dataDir = (getenv("AOC2023_DATADIR")?.toKString()?.ifEmpty { null } ?: ".").toPath()
15-
okio.FileSystem.SYSTEM.source(dataDir / "day$day.txt").buffer().readUtf8()
12+
return okio.FileSystem.SYSTEM.source(dataDir / "day$day.txt").buffer().readUtf8()
1613
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.github.ephemient.aoc2023.exe
22

3-
import kotlinx.coroutines.runBlocking
4-
5-
fun main(vararg args: String): Unit = runBlocking {
6-
mainImpl(*args)
3+
fun main(vararg args: String) {
4+
mainImpl(args)
75
}

kt/aoc2023-lib/build.gradle.kts

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ plugins {
33
id("com.github.ephemient.aoc2023.detekt")
44
id("com.github.ephemient.aoc2023.kotlin.multiplatform.jvm.platform")
55
id("com.github.ephemient.aoc2023.kotlin.multiplatform.native.platforms")
6+
id("com.github.ephemient.aoc2023.kotlin.multiplatform.js.platform")
67
}
78

89
kotlin {
10+
js {
11+
browser()
12+
nodejs()
13+
}
14+
915
sourceSets {
1016
commonTest {
1117
dependencies {
1218
implementation(kotlin("test"))
13-
implementation(libs.kotlinx.coroutines.test)
1419
}
1520
}
1621

kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Days.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ val days = listOf(
88
data class Day(
99
val day: Int,
1010
val name: String = day.toString(),
11-
val solver: (String) -> List<suspend () -> Any?>,
11+
val solver: (String) -> List<() -> Any?>,
1212
)

kt/aoc2023-lib/src/commonTest/kotlin/com/github/ephemient/aoc2023/Day1Test.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package com.github.ephemient.aoc2023
22

3-
import kotlinx.coroutines.test.runTest
43
import kotlin.test.Test
54
import kotlin.test.assertEquals
65

76
class Day1Test {
87
@Test
9-
fun part1() = runTest {
8+
fun part1() {
109
assertEquals(142, Day1(example1).part1())
1110
}
1211

1312
@Test
14-
fun part2() = runTest {
13+
fun part2() {
1514
assertEquals(281, Day1(example2).part2())
1615
}
1716

kt/aoc2023-lib/src/commonTest/kotlin/com/github/ephemient/aoc2023/Day2Test.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package com.github.ephemient.aoc2023
22

3-
import kotlinx.coroutines.test.runTest
43
import kotlin.test.Test
54
import kotlin.test.assertEquals
65

76
class Day2Test {
87
@Test
9-
fun part1() = runTest {
8+
fun part1() {
109
assertEquals(8, Day2(example).part1())
1110
}
1211

1312
@Test
14-
fun part2() = runTest {
13+
fun part2() {
1514
assertEquals(2286, Day2(example).part2())
1615
}
1716

kt/buildSrc/build.gradle.kts

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ gradlePlugin {
1818
id = "com.github.ephemient.aoc2023.kotlin.multiplatform.native.platforms"
1919
implementationClass = "com.github.ephemient.aoc2023.buildsrc.KotlinMultiplatformNativePlatformsPlugin"
2020
}
21+
create("KotlinMultiplatformJsPlatformPlugin") {
22+
id = "com.github.ephemient.aoc2023.kotlin.multiplatform.js.platform"
23+
implementationClass = "com.github.ephemient.aoc2023.buildsrc.KotlinMultiplatformJsPlatformPlugin"
24+
}
2125
}
2226
}
2327

2428
dependencies {
25-
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
29+
implementation(kotlin("gradle-plugin", libs.versions.kotlin.asProvider().get()))
2630
implementation(libs.detekt.plugin)
2731
}

kt/buildSrc/src/main/kotlin/com/github/ephemient/aoc2023/buildsrc/KotlinMultiplatformPlugins.kt

+18
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ package com.github.ephemient.aoc2023.buildsrc
33
import org.gradle.api.Plugin
44
import org.gradle.api.Project
55
import org.gradle.kotlin.dsl.apply
6+
import org.gradle.kotlin.dsl.configure
67
import org.gradle.kotlin.dsl.getValue
78
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
9+
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
10+
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
811

912
class KotlinMultiplatformBasePlugin : Plugin<Project> {
1013
override fun apply(target: Project) {
@@ -42,3 +45,18 @@ class KotlinMultiplatformNativePlatformsPlugin : Plugin<Project> {
4245
}
4346
}
4447
}
48+
49+
class KotlinMultiplatformJsPlatformPlugin : Plugin<Project> {
50+
override fun apply(target: Project) {
51+
target.rootProject.apply<NodeJsRootPlugin>()
52+
target.rootProject.configure<NodeJsRootExtension> {
53+
nodeVersion = "21.3.0"
54+
}
55+
56+
target.apply<KotlinMultiplatformBasePlugin>()
57+
target.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") {
58+
val kotlin: KotlinMultiplatformExtension by target.extensions
59+
kotlin.js()
60+
}
61+
}
62+
}

kt/gradle/libs.versions.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ detekt = "1.23.4"
44
graal-sdk = "23.1.1"
55
junit-jupiter = "5.10.1"
66
kotlin = "1.9.21"
7+
kotlin-wrappers = "18.16.12-pre.652"
78
kotlinx-benchmark = "0.4.9"
8-
kotlinx-coroutines = "1.7.3"
99
okio = "3.6.0"
1010
native-image-plugin = "0.9.28"
1111

@@ -21,9 +21,8 @@ detekt-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", v
2121
graal-sdk = { module = "org.graalvm.sdk:graal-sdk", version.ref = "graal-sdk" }
2222
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" }
2323
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter" }
24+
kotlin-wrappers-node = { module = "org.jetbrains.kotlin-wrappers:kotlin-node", version.ref = "kotlin-wrappers" }
2425
kotlinx-benchmark = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime", version.ref = "kotlinx-benchmark" }
25-
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
26-
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
2726
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
2827

2928
[bundles]

0 commit comments

Comments
 (0)