316 lines
12 KiB
Plaintext
316 lines
12 KiB
Plaintext
|
|
import com.github.jk1.license.render.*
|
|
import com.github.jk1.license.filter.ExcludeTransitiveDependenciesFilter
|
|
import com.github.jk1.license.filter.LicenseBundleNormalizer
|
|
import org.commonmark.parser.Parser
|
|
import org.commonmark.renderer.html.HtmlRenderer
|
|
import com.github.jk1.license.render.InventoryMarkdownReportRenderer
|
|
import org.jsoup.Jsoup
|
|
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
|
|
|
//import org.gradle.internal.impldep.org.jsoup.Jsoup
|
|
|
|
|
|
buildscript {
|
|
repositories {
|
|
mavenCentral()
|
|
}
|
|
dependencies {
|
|
classpath ("org.jsoup:jsoup:1.18.1")
|
|
// 빌드 스크립트에서 commonmark 라이브러리를 사용할 수 있도록 추가합니다.
|
|
classpath("org.commonmark:commonmark:0.18.0")
|
|
}
|
|
}
|
|
|
|
|
|
plugins {
|
|
kotlin("jvm") version "1.9.25"
|
|
kotlin("plugin.spring") version "1.9.25"
|
|
id("org.springframework.boot") version "3.3.4"
|
|
id("io.spring.dependency-management") version "1.1.6"
|
|
id("com.github.jk1.dependency-license-report") version "2.0"
|
|
|
|
}
|
|
|
|
group = "kr.lunaticbum.back"
|
|
version = "0.0.7-SNAPSHOT"
|
|
|
|
java {
|
|
toolchain {
|
|
languageVersion = JavaLanguageVersion.of(17)
|
|
}
|
|
}
|
|
|
|
configurations {
|
|
compileOnly {
|
|
extendsFrom(configurations.annotationProcessor.get())
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
|
|
maven { url = uri("https://repo.spring.io/milestone") }
|
|
|
|
}
|
|
|
|
dependencies {
|
|
// [추가] Kotlin BOM(Bill of Materials)을 사용하여 모든 코틀린 라이브러리 버전을 정렬합니다.
|
|
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.25"))
|
|
|
|
// --- 기존 의존성 (정리됨) ---
|
|
implementation ("org.slf4j:jcl-over-slf4j")
|
|
implementation ("org.springframework.boot:spring-boot-starter-quartz")
|
|
implementation ("org.apache.tomcat.embed:tomcat-embed-jasper")
|
|
implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
|
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
|
implementation("org.springframework.boot:spring-boot-starter-webflux")
|
|
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
|
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
|
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
|
|
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
|
implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6")
|
|
implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
|
|
implementation ("org.jsoup:jsoup:1.18.1")
|
|
implementation ("org.seleniumhq.selenium:selenium-java:4.10.0")
|
|
implementation ("org.commonmark:commonmark:0.18.0")
|
|
implementation ("net.coobird:thumbnailator:0.4.14")
|
|
implementation("org.sejda.imageio:webp-imageio:0.1.6")
|
|
implementation ("com.drewnoakes:metadata-extractor:2.19.0")
|
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
|
compileOnly("org.projectlombok:lombok")
|
|
implementation ("com.google.maps:google-maps-services:2.2.0")
|
|
implementation(platform("org.springframework.ai:spring-ai-bom:1.0.0-M6"))
|
|
implementation("org.springframework.ai:spring-ai-ollama-spring-boot-starter:1.0.0-M6")
|
|
implementation ("org.springframework.ai:spring-ai-qdrant-store-spring-boot-starter")
|
|
implementation ("org.slf4j:slf4j-simple:1.7.25")
|
|
implementation("io.jsonwebtoken:jjwt-api:0.11.5")
|
|
implementation("io.jsonwebtoken:jjwt-impl:0.11.5")
|
|
implementation("io.jsonwebtoken:jjwt-jackson:0.11.5")
|
|
|
|
// [수정] 버전 번호를 제거합니다. (BOM이 버전을 관리해 줍니다)
|
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
|
|
|
// [수정] Gson 라이브러리 중복 제거 (2.11.0 버전만 남김)
|
|
implementation ("com.google.code.gson:gson:2.11.0")
|
|
|
|
annotationProcessor("org.projectlombok:lombok")
|
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
|
testImplementation("io.projectreactor:reactor-test")
|
|
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
|
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
|
}
|
|
|
|
|
|
kotlin {
|
|
compilerOptions {
|
|
freeCompilerArgs.addAll("-Xjsr305=strict")
|
|
}
|
|
}
|
|
tasks.withType<org.gradle.jvm.tasks.Jar>() {
|
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
exclude("META-INF/BC1024KE.RSA", "META-INF/BC1024KE.SF", "META-INF/BC1024KE.DSA")
|
|
exclude("META-INF/BC2048KE.RSA", "META-INF/BC2048KE.SF", "META-INF/BC2048KE.DSA")
|
|
}
|
|
tasks.withType<Test> {
|
|
useJUnitPlatform()
|
|
}
|
|
|
|
|
|
tasks.jar {
|
|
archiveFileName.set("app.jar")
|
|
manifest {
|
|
attributes["Main-Class"] = "kr.lunaticbum.back.lun.LunApplicationKt"
|
|
}
|
|
configurations["compileClasspath"].forEach { file: File ->
|
|
from(zipTree(file.absoluteFile))
|
|
}
|
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
}
|
|
|
|
tasks.jar {
|
|
|
|
// Otherwise you'll get a "No main manifest attribute" error
|
|
manifest {
|
|
attributes["Main-Class"] = "kr.lunaticbum.back.lun.LunApplicationKt"
|
|
}
|
|
|
|
// To avoid the duplicate handling strategy error
|
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
|
|
// To add all of the dependencies otherwise a "NoClassDefFoundError" error
|
|
from(sourceSets.main.get().output)
|
|
|
|
dependsOn(configurations.runtimeClasspath)
|
|
from({
|
|
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
|
|
})
|
|
}
|
|
|
|
// ✅ licenseReport는 이전과 동일하게 Markdown을 생성하도록 둡니다.
|
|
|
|
licenseReport {
|
|
|
|
outputDir = "$projectDir/build/licenses"
|
|
renderers = arrayOf(InventoryMarkdownReportRenderer())
|
|
// filters = arrayOf(com.github.jk1.license.filter.LicenseBundleNormalizer(), com.github.jk1.license.filter.ExcludeTransitiveDependenciesFilter())
|
|
}
|
|
|
|
tasks.register("updateLicensePage") {
|
|
dependsOn("generateLicenseReport")
|
|
|
|
doLast {
|
|
// file("$projectDir/build/licenses").listFiles().forEach {
|
|
// println("${it.absolutePath}: ${it.name}")
|
|
// }
|
|
// ... 로그 출력 로직은 그대로 유지 ...
|
|
println("🚀 'updateLicensePage' 태스크를 시작합니다.")
|
|
|
|
val licenseMarkdownFile = file("$projectDir/build/licenses/licenses.md")
|
|
val targetHtmlFile = file("src/main/resources/templates/content/licenses.html")
|
|
|
|
println(" - 원본 마크다운 파일: ${licenseMarkdownFile.path}")
|
|
println(" - 대상 HTML 파일: ${targetHtmlFile.path}")
|
|
|
|
if (!licenseMarkdownFile.exists()) {
|
|
throw GradleException("❌ 라이선스 마크다운 파일이 생성되지 않았습니다. '${licenseMarkdownFile.path}'")
|
|
}
|
|
|
|
val licenseMarkdown = licenseMarkdownFile.readText()
|
|
println(" - 마크다운 파일을 성공적으로 읽었습니다. (내용 길이: ${licenseMarkdown.length})")
|
|
|
|
val parser = Parser.builder().build()
|
|
val renderer = HtmlRenderer.builder().build()
|
|
val licenseHtml = renderer.render(parser.parse(licenseMarkdown))
|
|
println(" - 마크다운을 HTML로 변환했습니다. (HTML 길이: ${licenseHtml.length})")
|
|
|
|
|
|
// ✅ Jsoup으로 HTML 파일을 파싱합니다.
|
|
val doc = Jsoup.parse(targetHtmlFile, "UTF-8")
|
|
|
|
// ✅ CSS 선택자를 이용해 ID가 'license-content-container'인 태그를 선택하고
|
|
// 그 내부 HTML을 생성된 라이선스 내용으로 교체합니다.
|
|
doc.selectFirst("#license-content-container")?.html(licenseHtml)
|
|
|
|
println(" - HTML 파일 내 placeholder div의 내용을 교체했습니다.")
|
|
|
|
// ✅ 변경된 HTML 내용을 파일에 다시 씁니다.
|
|
targetHtmlFile.writeText(doc.outerHtml())
|
|
|
|
println("✅ 라이선스 정보(HTML)가 '${targetHtmlFile.name}' 파일에 성공적으로 업데이트되었습니다.")
|
|
}
|
|
}
|
|
|
|
// 'build' 태스크 실행 시 이 작업이 자동으로 수행되도록 연결
|
|
// [수정 전] tasks.build { dependsOn(tasks.getByName("updateLicensePage")) }
|
|
tasks.named("build") { // [수정 후] 'build' 태스크를 더 안전하게 참조합니다.
|
|
dependsOn(tasks.named("updateLicensePage"))
|
|
}
|
|
|
|
tasks.named("bootJar") { // [수정 후] 'build' 태스크를 더 안전하게 참조합니다.
|
|
dependsOn(tasks.named("updateLicensePage"))
|
|
}
|
|
|
|
// 기본 bootJar 태스크의 설정을 가져오기 위한 참조
|
|
val bootJar by tasks.getting(BootJar::class)
|
|
//
|
|
//// 'prod' 프로필이 내장된 JAR를 빌드하는 최종 태스크 정의
|
|
//tasks.register<BootJar>("bootJarProd") {
|
|
// group = "build"
|
|
// description = "Builds a production JAR that defaults to the 'prod' profile."
|
|
// archiveClassifier.set("prod")
|
|
//
|
|
// // --- 필수 설정 복사 ---
|
|
// // 1. Main 클래스 설정 복사
|
|
// mainClass.set(bootJar.mainClass)
|
|
// // 2. Classpath 설정 복사
|
|
// classpath = bootJar.classpath
|
|
// // 3. Target Java Version 설정 복사 (이번 오류 해결)
|
|
// targetJavaVersion.set(bootJar.targetJavaVersion)
|
|
//
|
|
// manifest {
|
|
// attributes["Spring-Profiles-Active"] = "prod"
|
|
// }
|
|
//}
|
|
|
|
// "local" 프로파일용 JAR를 빌드하는 작업
|
|
tasks.register<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJarLocal") {
|
|
group = "build"
|
|
description = "로컬 환경용 JAR 파일을 빌드합니다 ('local' 프로파일 적용)."
|
|
archiveClassifier.set("local") // 파일 이름에 local 접미사 추가 (e.g., app-local.jar)
|
|
|
|
// 메인 클래스와 클래스패스는 기본 bootJar 설정을 따라갑니다.
|
|
mainClass.set(tasks.bootJar.get().mainClass)
|
|
classpath = tasks.bootJar.get().classpath
|
|
targetJavaVersion.set(bootJar.targetJavaVersion)
|
|
// 'resources' 폴더의 모든 파일을 복사하되...
|
|
from("src/main/resources") {
|
|
include("**/*")
|
|
// prod 설정 파일은 제외합니다.
|
|
exclude("application-prod.properties")
|
|
// local 설정 파일의 이름을 application.properties로 변경합니다.
|
|
rename("application-local.properties", "application.properties")
|
|
}
|
|
}
|
|
|
|
// "prod" 프로파일용 JAR를 빌드하는 작업
|
|
tasks.register<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJarProd") {
|
|
group = "build"
|
|
description = "운영 환경용 JAR 파일을 빌드합니다 ('prod' 프로파일 적용)."
|
|
archiveClassifier.set("prod") // 파일 이름에 prod 접미사 추가 (e.g., app-prod.jar)
|
|
|
|
// 메인 클래스와 클래스패스는 기본 bootJar 설정을 따라갑니다.
|
|
mainClass.set(tasks.bootJar.get().mainClass)
|
|
classpath = tasks.bootJar.get().classpath
|
|
targetJavaVersion.set(bootJar.targetJavaVersion)
|
|
// 'resources' 폴더의 모든 파일을 복사하되...
|
|
from("src/main/resources") {
|
|
include("**/*")
|
|
// local 설정 파일은 제외합니다.
|
|
exclude("application-local.properties")
|
|
// prod 설정 파일의 이름을 application.properties로 변경합니다.
|
|
rename("application-prod.properties", "application.properties")
|
|
}
|
|
}
|
|
|
|
|
|
// 🚀 1. 명령어를 실행할 새로운 Exec 태스크 정의
|
|
tasks.register<Exec>("runCommandAfterProdJar") {
|
|
group = "build"
|
|
description = "prod JAR 빌드 후 실행할 명령어를 정의합니다."
|
|
|
|
// 이 태스크는 bootJarProd가 성공해야만 의미가 있으므로, 의존성을 명시해주는 것이 좋습니다.
|
|
dependsOn(tasks.named("bootJarProd"))
|
|
|
|
// 실행할 OS 명령어와 인자를 설정합니다.
|
|
// 예시 1: Docker 이미지 빌드
|
|
commandLine("docker", "buildx","buildx","--platform","linux/amd64", "-t", "lunaticbum/testjar:0.025", ".")
|
|
|
|
// 예시 2: 빌드된 JAR 파일을 특정 서버로 복사
|
|
// commandLine("scp", "build/libs/your-app-name-prod.jar", "user@server:/path/to/deploy")
|
|
|
|
// 예시 3: 간단한 셸 스크립트 실행
|
|
// commandLine("./deploy.sh")
|
|
|
|
// 필요하다면 작업 디렉토리를 설정할 수 있습니다.
|
|
// workingDir = rootDir
|
|
// doLast {
|
|
// println("prod JAR 빌드가 완료되었습니다. 추가 명령어를 실행합니다.")
|
|
// exec {
|
|
// commandLine("docker", "push", "lunaticbum/testjar:0.025")
|
|
// // commandLine("echo", "Hello from doLast!")
|
|
// }
|
|
// }
|
|
}
|
|
|
|
// 🚀 2. bootJarProd 태스크가 끝나면 위에서 정의한 태스크를 실행하도록 연결
|
|
//tasks.named("bootJarProd") {
|
|
// finalizedBy(tasks.named("runCommandAfterProdJar"))
|
|
//}
|
|
|
|
//
|
|
//// 'build' 태스크 실행 시 이 작업이 자동으로 수행되도록 연결
|
|
//tasks.build {
|
|
// dependsOn(tasks.getByName("updateLicensePage"))
|
|
//} |