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
+
1
7
plugins {
2
8
alias(libs.plugins.jetbrainsCompose) apply false
3
9
alias(libs.plugins.compose.compiler) apply false
@@ -16,6 +22,7 @@ plugins {
16
22
alias(libs.plugins.kotlinter) apply false
17
23
alias(libs.plugins.keeper) apply false
18
24
alias(libs.plugins.kotlin.atomicfu) apply false
25
+ id(" org.jetbrains.dokka" ) version " 2.0.0"
19
26
}
20
27
21
28
allprojects {
@@ -57,3 +64,41 @@ subprojects {
57
64
tasks.register<Delete >(" clean" ) {
58
65
delete(rootProject.layout.buildDirectory)
59
66
}
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