diff --git a/README.md b/README.md index e1cfe44..3b91bef 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ # portal -Webportal for everything and stuff \ No newline at end of file +Webportal for everything and stuff + +## Usage + +The server can be started directly via: +```bash +./gradlew run +``` + +Or create a shadow jar: +```bash +./gradlew jar +java -jar build/libs/portal.jar +``` diff --git a/build.gradle b/build.gradle index 067aa8b..38578cd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + buildscript { repositories { jcenter() @@ -12,6 +14,7 @@ plugins { id 'kotlin-multiplatform' version '1.3.20' id 'kotlinx-serialization' version '1.3.20' id "org.kravemir.gradle.sass" version "1.2.2" + id "com.github.johnrengelman.shadow" version "4.0.4" } group "de.kif" @@ -91,7 +94,7 @@ kotlin { } } -sass{ +sass { main { srcDir = file("$projectDir/src/jsMain/resources/style") outDir = file("$buildDir/processedResources/js/main/style") @@ -119,15 +122,40 @@ task populateWebFolder(dependsOn: [jsMainClasses, sass]) { jsJar.dependsOn(populateWebFolder) +def mainClassName = 'de.kif.backend.Main' + task run(type: JavaExec, dependsOn: [jvmMainClasses, jsJar]) { - main = "de.kif.backend.MainKt" - classpath { [ - kotlin.targets.jvm.compilations.main.output.allOutputs.files, - configurations.jvmRuntimeClasspath, - ] } + main = mainClassName + classpath { + [ + kotlin.targets.jvm.compilations.main.output.allOutputs.files, + configurations.jvmRuntimeClasspath, + ] + } args = [] } clean.doFirst { delete webFolder } + +task jar(type: ShadowJar, dependsOn: [jvmMainClasses, jsMainClasses, sass]) { + from kotlin.targets.jvm.compilations.main.output + + from (kotlin.targets.js.compilations.main.output) { + into "web" + } + from (kotlin.sourceSets.jsMain.resources.srcDirs) { + into "web" + } + + configurations = [kotlin.targets.jvm.compilations.main.compileDependencyFiles] + + baseName = rootProject.name + classifier = null + version = null + + manifest { + attributes 'Main-Class': mainClassName + } +} diff --git a/src/jvmMain/kotlin/de/kif/backend/Main.kt b/src/jvmMain/kotlin/de/kif/backend/Main.kt new file mode 100644 index 0000000..6d2491f --- /dev/null +++ b/src/jvmMain/kotlin/de/kif/backend/Main.kt @@ -0,0 +1,97 @@ +package de.kif.backend + +import io.ktor.application.call +import io.ktor.html.respondHtml +import io.ktor.http.content.files +import io.ktor.http.content.static +import io.ktor.routing.get +import io.ktor.routing.routing +import io.ktor.server.engine.embeddedServer +import io.ktor.server.netty.Netty +import kotlinx.html.* +import java.io.File +import java.nio.file.FileSystem +import java.nio.file.FileSystems +import java.nio.file.Files +import java.nio.file.Paths + +object Main { + private fun extractWebFolder(): File { + val destination = Files.createTempDirectory("web"); + + val classPath = "web" + val uri = this::class.java.classLoader.getResource(classPath).toURI() + val fileSystem: FileSystem? + val src = if (uri.scheme == "jar") { + fileSystem = FileSystems.newFileSystem(uri, mutableMapOf()) + fileSystem.getPath(classPath) + } else { + Paths.get(uri) + } + + Files.walk(src).forEach { + val name = it.toAbsolutePath().toString().let { + it.drop(classPath.length + it.indexOf(classPath, ignoreCase = true)).dropWhile { + it == '/' || it == '\\' + } + } + if (Files.isDirectory(it)) { + Files.createDirectories(destination.resolve(name)) + } else { + Files.copy(it, destination.resolve(name)) + } + } + + return destination.toFile() + } + + private fun getWebFolder(): File { + val currentDir = File(".").absoluteFile.canonicalFile + + return listOf( + "web", + "../web" + ).map { + File(currentDir, it) + }.firstOrNull { it.isDirectory }?.absoluteFile?.canonicalFile ?: extractWebFolder() + } + + @JvmStatic + fun main(args: Array) { + embeddedServer(Netty, port = 8080, host = "127.0.0.1") { + val webDir = getWebFolder() + + environment.log.info("Web directory: $webDir") + + val modules = webDir.list().toList().filter { + it.endsWith(".js") && + !it.endsWith(".meta.js") && + !it.endsWith("-test.js") && + it != "require.min.js" + }.joinToString(", ") { "'${it.take(it.length - 3)}'" } + + routing { + get("/") { + call.respondHtml { + head { + title("KIF Portal") + + link(href = "/static/style/style.css", type = "text/css", rel = "stylesheet") + + script(src = "/static/require.min.js") {} + + script { + +"require.config({baseUrl: '/static'});\n" + +("require([$modules]);\n") + } + } + body {} + } + } + static("/static") { + files(webDir) + } + } + }.start(wait = true) + } +} \ No newline at end of file diff --git a/src/jvmMain/kotlin/de/kif/backend/main.kt b/src/jvmMain/kotlin/de/kif/backend/main.kt deleted file mode 100644 index 7d1b8c4..0000000 --- a/src/jvmMain/kotlin/de/kif/backend/main.kt +++ /dev/null @@ -1,58 +0,0 @@ -package de.kif.backend - -import io.ktor.application.call -import io.ktor.html.respondHtml -import io.ktor.http.content.files -import io.ktor.http.content.static -import io.ktor.routing.get -import io.ktor.routing.routing -import io.ktor.server.engine.embeddedServer -import io.ktor.server.netty.Netty -import kotlinx.html.* -import java.io.File - - -fun main() { - embeddedServer(Netty, port = 8080, host = "127.0.0.1") { - val currentDir = File(".").absoluteFile.canonicalFile - - val webDir = listOf( - "web", - "../web" - ).map { - File(currentDir, it).canonicalFile - }.firstOrNull { it.isDirectory }?.absoluteFile ?: error("Can't find 'web' folder!") - - val modules = webDir.list().toList().filter { - it.endsWith(".js") && - !it.endsWith(".meta.js") && - !it.endsWith("-test.js") && - it != "require.min.js" - }.joinToString(", ") { "'${it.take(it.length - 3)}'" } - - environment.log.info("Web directory: $webDir") - - routing { - get("/") { - call.respondHtml { - head { - title("KIF Portal") - - link(href = "/static/style/style.css", type = "text/css", rel = "stylesheet") - - script(src = "/static/require.min.js") {} - - script { - +"require.config({baseUrl: '/static'});\n" - +("require([$modules]);\n") - } - } - body {} - } - } - static("/static") { - files(webDir) - } - } - }.start(wait = true) -}