build.gradle.kts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
  2. import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
  3. import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
  4. import org.springframework.boot.gradle.tasks.bundling.BootJar
  5. import org.springframework.boot.gradle.tasks.run.BootRun
  6. plugins {
  7. val kotlinVersion: String by System.getProperties()
  8. id("kotlinx-serialization") version kotlinVersion
  9. kotlin("multiplatform") version kotlinVersion
  10. id("io.spring.dependency-management") version System.getProperty("dependencyManagementPluginVersion")
  11. id("org.springframework.boot") version System.getProperty("springBootVersion")
  12. kotlin("plugin.spring") version kotlinVersion
  13. val kvisionVersion: String by System.getProperties()
  14. id("kvision") version kvisionVersion
  15. }
  16. extra["kotlin.version"] = "1.4.10"
  17. version = "1.0-SNAPSHOT"
  18. group = "me.mementomorri"
  19. repositories {
  20. mavenCentral()
  21. jcenter()
  22. mavenLocal()
  23. }
  24. // Versions
  25. val kotlinVersion: String by System.getProperties()
  26. val kvisionVersion: String by System.getProperties()
  27. val coroutinesVersion: String by project
  28. val springDataR2dbcVersion: String by project
  29. val r2dbcPostgresqlVersion: String by project
  30. val r2dbcH2Version: String by project
  31. val kweryVersion: String by project
  32. val jwtVersion: String by project
  33. val slugifyVersion: String by project
  34. val webDir = file("src/frontendMain/web")
  35. val mainClassName = "com.example.MainKt"
  36. kotlin {
  37. jvm("backend") {
  38. withJava()
  39. compilations.all {
  40. kotlinOptions {
  41. jvmTarget = "1.8"
  42. freeCompilerArgs = listOf("-Xjsr305=strict")
  43. }
  44. }
  45. }
  46. js("frontend") {
  47. browser {
  48. runTask {
  49. outputFileName = "main.bundle.js"
  50. sourceMaps = false
  51. devServer = KotlinWebpackConfig.DevServer(
  52. open = false,
  53. port = 3000,
  54. proxy = mapOf(
  55. "/kv/*" to "http://localhost:8080",
  56. "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true)
  57. ),
  58. contentBase = listOf("$buildDir/processedResources/frontend/main")
  59. )
  60. }
  61. webpackTask {
  62. outputFileName = "main.bundle.js"
  63. }
  64. testTask {
  65. useKarma {
  66. useChromeHeadless()
  67. }
  68. }
  69. }
  70. binaries.executable()
  71. }
  72. sourceSets {
  73. val commonMain by getting {
  74. dependencies {
  75. api("io.kvision:kvision-server-spring-boot:$kvisionVersion")
  76. implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
  77. }
  78. kotlin.srcDir("build/generated-src/common")
  79. }
  80. val commonTest by getting {
  81. dependencies {
  82. implementation(kotlin("test-common"))
  83. implementation(kotlin("test-annotations-common"))
  84. }
  85. }
  86. val backendMain by getting {
  87. dependencies {
  88. implementation(kotlin("stdlib-jdk8"))
  89. implementation(kotlin("reflect"))
  90. implementation("org.springframework.boot:spring-boot-starter")
  91. implementation("org.springframework.boot:spring-boot-devtools")
  92. implementation("org.springframework.boot:spring-boot-starter-webflux")
  93. implementation("org.springframework.data:spring-data-r2dbc:$springDataR2dbcVersion")
  94. implementation("io.r2dbc:r2dbc-postgresql:$r2dbcPostgresqlVersion")
  95. implementation("io.r2dbc:r2dbc-h2:$r2dbcH2Version")
  96. implementation("com.github.andrewoma.kwery:core:$kweryVersion")
  97. implementation("com.auth0:java-jwt:$jwtVersion")
  98. implementation("com.github.slugify:slugify:$slugifyVersion")
  99. }
  100. }
  101. val backendTest by getting {
  102. dependencies {
  103. implementation(kotlin("test"))
  104. implementation(kotlin("test-junit"))
  105. implementation("org.springframework.boot:spring-boot-starter-test")
  106. }
  107. }
  108. val frontendMain by getting {
  109. resources.srcDir(webDir)
  110. dependencies {
  111. implementation(npm("marked", "^0.6.3"))
  112. implementation("io.kvision:kvision:$kvisionVersion")
  113. implementation("io.kvision:kvision-redux-kotlin:$kvisionVersion")
  114. implementation("io.kvision:kvision-pace:$kvisionVersion")
  115. }
  116. kotlin.srcDir("build/generated-src/frontend")
  117. }
  118. val frontendTest by getting {
  119. dependencies {
  120. implementation(kotlin("test-js"))
  121. implementation("io.kvision:kvision-testutils:$kvisionVersion")
  122. }
  123. }
  124. }
  125. }
  126. fun getNodeJsBinaryExecutable(): String {
  127. val nodeDir = NodeJsRootPlugin.apply(project).nodeJsSetupTaskProvider.get().destination
  128. val isWindows = System.getProperty("os.name").toLowerCase().contains("windows")
  129. val nodeBinDir = if (isWindows) nodeDir else nodeDir.resolve("bin")
  130. val command = NodeJsRootPlugin.apply(project).nodeCommand
  131. val finalCommand = if (isWindows && command == "node") "node.exe" else command
  132. return nodeBinDir.resolve(finalCommand).absolutePath
  133. }
  134. tasks {
  135. create("generatePotFile", Exec::class) {
  136. dependsOn("compileKotlinFrontend")
  137. executable = getNodeJsBinaryExecutable()
  138. args("$buildDir/js/node_modules/gettext-extract/bin/gettext-extract")
  139. inputs.files(kotlin.sourceSets["frontendMain"].kotlin.files)
  140. outputs.file("$projectDir/src/frontendMain/resources/i18n/messages.pot")
  141. }
  142. }
  143. afterEvaluate {
  144. tasks {
  145. getByName("frontendProcessResources", Copy::class) {
  146. dependsOn("compileKotlinFrontend")
  147. exclude("**/*.pot")
  148. doLast("Convert PO to JSON") {
  149. destinationDir.walkTopDown().filter {
  150. it.isFile && it.extension == "po"
  151. }.forEach {
  152. exec {
  153. executable = getNodeJsBinaryExecutable()
  154. args(
  155. "$buildDir/js/node_modules/gettext.js/bin/po2json",
  156. it.absolutePath,
  157. "${it.parent}/${it.nameWithoutExtension}.json"
  158. )
  159. println("Converted ${it.name} to ${it.nameWithoutExtension}.json")
  160. }
  161. it.delete()
  162. }
  163. }
  164. }
  165. create("frontendArchive", Jar::class).apply {
  166. dependsOn("frontendBrowserProductionWebpack")
  167. group = "package"
  168. archiveAppendix.set("frontend")
  169. val distribution =
  170. project.tasks.getByName("frontendBrowserProductionWebpack", KotlinWebpack::class).destinationDirectory!!
  171. from(distribution) {
  172. include("*.*")
  173. }
  174. from(webDir)
  175. duplicatesStrategy = DuplicatesStrategy.EXCLUDE
  176. into("/public")
  177. inputs.files(distribution, webDir)
  178. outputs.file(archiveFile)
  179. manifest {
  180. attributes(
  181. mapOf(
  182. "Implementation-Title" to rootProject.name,
  183. "Implementation-Group" to rootProject.group,
  184. "Implementation-Version" to rootProject.version,
  185. "Timestamp" to System.currentTimeMillis()
  186. )
  187. )
  188. }
  189. }
  190. getByName("backendProcessResources", Copy::class) {
  191. duplicatesStrategy = DuplicatesStrategy.EXCLUDE
  192. }
  193. getByName("bootJar", BootJar::class) {
  194. dependsOn("frontendArchive", "backendMainClasses")
  195. classpath = files(
  196. kotlin.targets["backend"].compilations["main"].output.allOutputs +
  197. project.configurations["backendRuntimeClasspath"] +
  198. (project.tasks["frontendArchive"] as Jar).archiveFile
  199. )
  200. }
  201. getByName("jar", Jar::class).apply {
  202. dependsOn("bootJar")
  203. }
  204. getByName("bootRun", BootRun::class) {
  205. dependsOn("backendMainClasses")
  206. classpath = files(
  207. kotlin.targets["backend"].compilations["main"].output.allOutputs +
  208. project.configurations["backendRuntimeClasspath"]
  209. )
  210. }
  211. create("backendRun") {
  212. dependsOn("bootRun")
  213. group = "run"
  214. }
  215. getByName("compileKotlinBackend") {
  216. dependsOn("compileKotlinMetadata")
  217. }
  218. getByName("compileKotlinFrontend") {
  219. dependsOn("compileKotlinMetadata")
  220. }
  221. }
  222. }