feat: propper db persistence w/ docker support
This commit is contained in:
parent
2c4995f9d7
commit
4c3d939d9a
9 changed files with 276 additions and 160 deletions
312
build.gradle.kts
312
build.gradle.kts
|
|
@ -1,159 +1,147 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import io.github.klahap.dotenv.DotEnv
|
||||
import io.github.klahap.dotenv.DotEnvBuilder
|
||||
import org.flywaydb.gradle.task.FlywayMigrateTask
|
||||
import org.gradle.api.JavaVersion.VERSION_21
|
||||
import org. gradle.api.JavaVersion.VERSION_21
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
import kotlin.io.path.Path
|
||||
|
||||
val env = DotEnvBuilder.dotEnv {
|
||||
addFile("$rootDir/.env")
|
||||
addSystemEnv()
|
||||
// ====================================================================================================
|
||||
// ENVIRONMENT CONFIGURATION
|
||||
// ====================================================================================================
|
||||
|
||||
val env = if (File("${layout.projectDirectory.asFile.absolutePath}/.env").exists()) {
|
||||
DotEnvBuilder.dotEnv {
|
||||
addFile("${layout.projectDirectory}/.env")
|
||||
addSystemEnv()
|
||||
}
|
||||
} else {
|
||||
DotEnvBuilder.dotEnv {
|
||||
addSystemEnv()
|
||||
}
|
||||
}
|
||||
|
||||
val envDbUrl: String = env["DB_URL"] ?: ""
|
||||
val envDbMigration: String = env["DB_MIGRATIONS"] ?: "src/main/resources/db/migration"
|
||||
val envDbUsername: String = env["DB_USERNAME"] ?: ""
|
||||
val envDbPassword: String = env["DB_PASSWORD"] ?: ""
|
||||
|
||||
val generatedResourcesDirectory = "${layout.buildDirectory.get()}/generated-resources"
|
||||
val generatedSourcesDirectory = "${layout.buildDirectory.get()}/generated-src"
|
||||
// ====================================================================================================
|
||||
// PLUGIN CONFIGURATION
|
||||
// ====================================================================================================
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.jvm)
|
||||
alias(libs.plugins.shadow)
|
||||
alias(libs.plugins.dotenv.plugin)
|
||||
alias(libs.plugins.jte)
|
||||
alias(libs.plugins.flyway)
|
||||
alias(libs.plugins.tasktree)
|
||||
alias(libs.plugins.jooq.codegen.gradle)
|
||||
alias(libs.plugins.taskinfo)
|
||||
alias(libs.plugins.flyway)
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// BASIC CONFIGURATION
|
||||
// ====================================================================================================
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = VERSION_21
|
||||
targetCompatibility = VERSION_21
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// GENERATED CODE DIRECTORIES
|
||||
// ====================================================================================================
|
||||
|
||||
val generatedResourcesDir = layout.buildDirectory.dir("generated-resources")
|
||||
val generatedSourcesDir = layout.buildDirectory.dir("generated-src")
|
||||
val migrationSourceDir = layout.projectDirectory.dir("src/main/resources/db/migration")
|
||||
val jtwSourceDir = layout.projectDirectory.dir("src/main/kte")
|
||||
val jteOutputDir = generatedResourcesDir.get().dir("jte")
|
||||
val jooqOutputDir = generatedSourcesDir.get().dir("jooq")
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
resources.srcDir(jteOutputDir)
|
||||
kotlin.srcDir(jooqOutputDir)
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// DEPENDENCIES
|
||||
// ====================================================================================================
|
||||
|
||||
dependencies {
|
||||
// HTTP4K
|
||||
implementation(platform(libs.http4k.bom))
|
||||
implementation(libs.bundles.http4k)
|
||||
|
||||
// Environment & Configuration
|
||||
implementation(libs.dotenv)
|
||||
|
||||
// Templating
|
||||
implementation(libs.jte.kotlin)
|
||||
|
||||
// Database
|
||||
implementation(libs.bundles.database)
|
||||
implementation(libs.flyway.core)
|
||||
implementation(libs.flyway.database.postgresql)
|
||||
|
||||
// Testing
|
||||
testImplementation(libs.bundles.testing)
|
||||
|
||||
// Jooq Codegen
|
||||
jooqCodegen(libs.jooq.meta)
|
||||
jooqCodegen(libs.jooq.meta.extensions)
|
||||
jooqCodegen(libs.jooq.postgres)
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath(libs.postgresql)
|
||||
classpath(libs.jooq.codegen)
|
||||
classpath(libs.jooq.meta)
|
||||
classpath(libs.jooq.meta.extensions)
|
||||
classpath(libs.flyway.database.postgresql)
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.main {
|
||||
resources.srcDir("$generatedResourcesDirectory/jte")
|
||||
kotlin.srcDir("$generatedSourcesDirectory/jooq")
|
||||
}
|
||||
// ====================================================================================================
|
||||
// JTE TEMPLATE GENERATION
|
||||
// ====================================================================================================
|
||||
|
||||
tasks {
|
||||
withType<KotlinJvmCompile>().configureEach {
|
||||
dependsOn("jooqCodegen")
|
||||
|
||||
compilerOptions {
|
||||
allWarningsAsErrors = false
|
||||
jvmTarget.set(JVM_21)
|
||||
freeCompilerArgs.add("-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
|
||||
withType<Test> {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
withType<FlywayMigrateTask> {
|
||||
dependsOn("initDb")
|
||||
}
|
||||
|
||||
named("precompileJte") {
|
||||
dependsOn("compileKotlin")
|
||||
}
|
||||
|
||||
named<ShadowJar>("shadowJar") {
|
||||
manifest {
|
||||
attributes("Main-Class" to "at.dokkae.homepage.HomepageKt")
|
||||
}
|
||||
|
||||
dependsOn("precompileJte")
|
||||
|
||||
mustRunAfter("flywayMigrate", "jooqCodegen")
|
||||
|
||||
from("$generatedResourcesDirectory/jte")
|
||||
|
||||
archiveFileName.set("app.jar")
|
||||
|
||||
exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
|
||||
}
|
||||
|
||||
register("buildDocker") {
|
||||
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = VERSION_21
|
||||
targetCompatibility = VERSION_21
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(platform(libs.http4k.bom))
|
||||
|
||||
implementation(libs.dotenv)
|
||||
|
||||
implementation(libs.bundles.http4k)
|
||||
implementation(libs.jte.kotlin)
|
||||
implementation(libs.bundles.database)
|
||||
|
||||
testImplementation(libs.bundles.testing)
|
||||
|
||||
jooqCodegen(libs.jooq.meta)
|
||||
jooqCodegen(libs.jooq.postgres)
|
||||
}
|
||||
|
||||
// ========== JTE Templating ==========
|
||||
jte {
|
||||
sourceDirectory.set(Path("src/main/kte"))
|
||||
targetDirectory.set(Path("$generatedResourcesDirectory/jte"))
|
||||
sourceDirectory.set(Path(jtwSourceDir.asFile.absolutePath))
|
||||
targetDirectory.set(Path(jteOutputDir.asFile.absolutePath))
|
||||
precompile()
|
||||
}
|
||||
|
||||
// ========== FlyWay ==========
|
||||
flyway {
|
||||
url = envDbUrl
|
||||
user = envDbUsername
|
||||
password = envDbPassword
|
||||
locations = arrayOf("filesystem:$envDbMigration")
|
||||
baselineOnMigrate = true
|
||||
validateMigrationNaming = true
|
||||
tasks.named("precompileJte") {
|
||||
dependsOn("compileKotlin")
|
||||
}
|
||||
|
||||
tasks.register("initDb") {
|
||||
doFirst {
|
||||
println("Database Configuration:")
|
||||
println(" Raw URL from env: $envDbUrl")
|
||||
println(" Resolved URL: $envDbUrl")
|
||||
println(" Migrations: $envDbMigration")
|
||||
println(" Credentials:")
|
||||
println(" Username: $envDbUsername")
|
||||
println(" Password: ${"*".repeat(envDbPassword.length)}")
|
||||
}
|
||||
tasks.register("genJte") {
|
||||
group = "codegen"
|
||||
description = "Precompile jte template into classes"
|
||||
|
||||
dependsOn("precompileJte")
|
||||
}
|
||||
|
||||
tasks.named("flywayMigrate") {
|
||||
finalizedBy("jooqCodegen")
|
||||
}
|
||||
// ====================================================================================================
|
||||
// JOOQ CODE GENERATION FROM SQL FILES
|
||||
// ====================================================================================================
|
||||
|
||||
// ========== Jooq ==========
|
||||
jooq {
|
||||
configuration {
|
||||
logging = org.jooq.meta.jaxb.Logging.WARN
|
||||
|
|
@ -172,7 +160,6 @@ jooq {
|
|||
name = "org.jooq.meta.postgres.PostgresDatabase"
|
||||
inputSchema = "public"
|
||||
|
||||
// SQLite specific configuration
|
||||
includes = ".*"
|
||||
excludes = """
|
||||
flyway_.*|
|
||||
|
|
@ -195,7 +182,7 @@ jooq {
|
|||
|
||||
target {
|
||||
packageName = "at.dokkae.homepage.generated.jooq"
|
||||
directory = "$generatedSourcesDirectory/jooq"
|
||||
directory = jooqOutputDir.asFile.absolutePath
|
||||
}
|
||||
|
||||
strategy {
|
||||
|
|
@ -203,4 +190,113 @@ jooq {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("genJooq") {
|
||||
group = "codegen"
|
||||
description = "Generate jooq classes from migrations"
|
||||
|
||||
dependsOn("jooqCodegen")
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// FLYWAY MIGRATE AND CODEGEN TASK
|
||||
// ====================================================================================================
|
||||
|
||||
flyway {
|
||||
url = envDbUrl
|
||||
user = envDbUsername
|
||||
password = envDbPassword
|
||||
locations = arrayOf("filesystem:${migrationSourceDir.asFile.absolutePath}")
|
||||
baselineOnMigrate = true
|
||||
validateMigrationNaming = true
|
||||
}
|
||||
|
||||
tasks.register("migrate") {
|
||||
group = "codegen"
|
||||
description = "Run Flyway migrations and generate JOOQ code (no compilation)"
|
||||
|
||||
dependsOn("flywayMigrate")
|
||||
finalizedBy("jooqCodegen")
|
||||
|
||||
doFirst {
|
||||
logger.lifecycle("╔═══════════════════════════════════════════════════════════════╗")
|
||||
logger.lifecycle("║ Running Migrations and Code Generation ║")
|
||||
logger.lifecycle("╚═══════════════════════════════════════════════════════════════╝")
|
||||
logger.lifecycle("| Database URL: $envDbUrl")
|
||||
logger.lifecycle("| Migrations: ${migrationSourceDir.asFile.absolutePath}")
|
||||
logger.lifecycle("| Username: $envDbUsername")
|
||||
logger.lifecycle("| Password: ${if (envDbUsername.isEmpty()) "not " else ""}provided")
|
||||
}
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("✓ Migration and code generation completed")
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// COMPILATION ORDER
|
||||
// ====================================================================================================
|
||||
|
||||
tasks {
|
||||
withType<KotlinJvmCompile>().configureEach {
|
||||
dependsOn("genJooq")
|
||||
|
||||
compilerOptions {
|
||||
allWarningsAsErrors = false
|
||||
jvmTarget.set(JVM_21)
|
||||
freeCompilerArgs.add("-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
|
||||
withType<Test> {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// JAR BUILDING
|
||||
// ====================================================================================================
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
manifest {
|
||||
attributes("Main-Class" to "at.dokkae.homepage.HomepageKt")
|
||||
}
|
||||
|
||||
dependsOn("genJte", "genJooq")
|
||||
|
||||
from(jteOutputDir)
|
||||
|
||||
archiveFileName.set("app.jar")
|
||||
|
||||
mergeServiceFiles()
|
||||
|
||||
exclude(
|
||||
"META-INF/*. RSA",
|
||||
"META-INF/*.SF",
|
||||
"META-INF/*.DSA"
|
||||
)
|
||||
}
|
||||
|
||||
tasks.named("build") {
|
||||
dependsOn("shadowJar")
|
||||
}
|
||||
|
||||
// ====================================================================================================
|
||||
// HELPER TASKS
|
||||
// ====================================================================================================
|
||||
|
||||
tasks.register("cleanGenerated") {
|
||||
group = "build"
|
||||
description = "Clean all generated code"
|
||||
|
||||
doLast {
|
||||
delete(generatedResourcesDir)
|
||||
delete(generatedSourcesDir)
|
||||
logger.lifecycle("✓ Cleaned generated code directories")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("clean") {
|
||||
dependsOn("cleanGenerated")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue