1+ import com.sun.net.httpserver.HttpExchange
2+ import com.sun.net.httpserver.HttpServer
3+ import java.net.InetSocketAddress
4+ import java.net.URLDecoder
5+ import java.nio.file.Files
6+
17plugins {
28 alias(libs.plugins.jetbrainsCompose) apply false
39 alias(libs.plugins.compose.compiler) apply false
@@ -16,6 +22,7 @@ plugins {
1622 alias(libs.plugins.kotlinter) apply false
1723 alias(libs.plugins.keeper) apply false
1824 alias(libs.plugins.kotlin.atomicfu) apply false
25+ id(" org.jetbrains.dokka" ) version " 2.0.0"
1926}
2027
2128allprojects {
@@ -57,3 +64,41 @@ subprojects {
5764tasks.register<Delete >(" clean" ) {
5865 delete(rootProject.layout.buildDirectory)
5966}
67+
68+ tasks.register(" serveDokka" ) {
69+ dependsOn(" dokkaHtml" )
70+ doLast {
71+ val server = HttpServer .create(InetSocketAddress (0 ), 0 )
72+ val root = file(" core/build/dokka/html" )
73+
74+ val handler =
75+ com.sun.net.httpserver.HttpHandler { exchange: HttpExchange ->
76+ val rawPath = exchange.requestURI.path
77+ val cleanPath = URLDecoder .decode(rawPath.removePrefix(" /" ), " UTF-8" )
78+ val requestedFile = File (root, cleanPath)
79+
80+ val file =
81+ when {
82+ requestedFile.exists() && ! requestedFile.isDirectory -> requestedFile
83+ else -> File (root, " index.html" ) // fallback
84+ }
85+
86+ val contentType =
87+ Files .probeContentType(file.toPath()) ? : " application/octet-stream"
88+ val bytes = file.readBytes()
89+ exchange.responseHeaders.add(" Content-Type" , contentType)
90+ exchange.sendResponseHeaders(200 , bytes.size.toLong())
91+ exchange.responseBody.use { it.write(bytes) }
92+ }
93+
94+ server.createContext(" /" , handler)
95+ server.executor = null
96+ server.start()
97+
98+ println (" 📘 Serving Dokka docs at http://localhost:${server.address.port} /" )
99+ println (" Press Ctrl+C to stop." )
100+
101+ // Keep the task alive
102+ Thread .currentThread().join()
103+ }
104+ }
0 commit comments