diff --git a/build-logic/src/main/kotlin/io/casper/build/TestClass.kt b/build-logic/src/main/kotlin/io/casper/build/TestClass.kt index db077d48..6a5992dc 100644 --- a/build-logic/src/main/kotlin/io/casper/build/TestClass.kt +++ b/build-logic/src/main/kotlin/io/casper/build/TestClass.kt @@ -5,10 +5,9 @@ package io.casper.build * 이제 올바른 KDoc 주석 형식을 사용합니다. */ class TestClass { + /** - * 이 함수는 KDoc 주석 검사 테스트를 위한 용도입니다. - * - * @return 항상 Unit을 반환합니다. + * 이 함수는 빌드 로직에서 사용하는 테스트 함수입니다. */ fun testFunction() { println("이 함수는 문서화 검사를 테스트하기 위한 용도입니다.") diff --git a/build.gradle.kts b/build.gradle.kts index 6ed31064..c66d9e0d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,21 +1,16 @@ plugins { kotlin("jvm") version "1.9.23" - kotlin("plugin.spring") version "1.9.23" - id("org.springframework.boot") version "3.4.4" - id("io.spring.dependency-management") version "1.1.7" id("org.jlleitschuh.gradle.ktlint").version("12.1.1") id("io.gitlab.arturbosch.detekt") version "1.23.6" id("casper.documentation-convention") } -// 모든 프로젝트(루트 및 서브프로젝트)에 공통 설정 적용 -allprojects { +// 서브프로젝트 설정 +subprojects { + // 서브프로젝트에 공통 설정 적용 repositories { mavenCentral() } - - // 모든 프로젝트에 플러그인 적용 - apply(plugin = "casper.documentation-convention") } tasks.register("checkAll") { @@ -25,6 +20,11 @@ tasks.register("checkAll") { // 루트 프로젝트의 check 태스크에 의존 dependsOn(tasks.named("check")) + // 모든 서브프로젝트의 check 태스크에 의존 + subprojects.forEach { subproject -> + dependsOn(subproject.tasks.matching { it.name.startsWith("check") }) + } + // build-logic, convention 등 includeBuild 모듈의 check 태스크에 의존 dependsOn(gradle.includedBuilds.map { it.task(":check") }) } @@ -38,20 +38,6 @@ java { } } -dependencies { - implementation("org.springframework.boot:spring-boot-starter") - implementation("org.jetbrains.kotlin:kotlin-reflect") - testImplementation("org.springframework.boot:spring-boot-starter-test") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") -} - -kotlin { - compilerOptions { - freeCompilerArgs.addAll("-Xjsr305=strict") - } -} - tasks.withType { useJUnitPlatform() } diff --git a/casper-application-domain/build.gradle.kts b/casper-application-domain/build.gradle.kts new file mode 100644 index 00000000..3c454cce --- /dev/null +++ b/casper-application-domain/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + kotlin("jvm") + id("casper.documentation-convention") // 명시적으로 플러그인 적용 +} + +group = "hs.kr.casper.entrydsm" +version = "0.0.1-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation(kotlin("test")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} \ No newline at end of file diff --git a/casper-application-domain/src/main/kotlin/hs/kr/entrydsm/application/TestClass2.kt b/casper-application-domain/src/main/kotlin/hs/kr/entrydsm/application/TestClass2.kt new file mode 100644 index 00000000..117dfbdb --- /dev/null +++ b/casper-application-domain/src/main/kotlin/hs/kr/entrydsm/application/TestClass2.kt @@ -0,0 +1,15 @@ +package hs.kr.entrydsm.application + +/** + * 이 클래스는 KDoc 주석 검사 테스트를 위한 용도입니다. + * 이제 올바른 KDoc 주석 형식을 사용합니다. + */ +class TestClass2 { + + /** + * 이 함수는 문서화 검사를 테스트하기 위한 용도입니다. + */ + fun testFunction() { + println("이 함수는 문서화 검사를 테스트하기 위한 용도입니다.") + } +} \ No newline at end of file diff --git a/casper-application-infrastructure/build.gradle.kts b/casper-application-infrastructure/build.gradle.kts new file mode 100644 index 00000000..15da2ae5 --- /dev/null +++ b/casper-application-infrastructure/build.gradle.kts @@ -0,0 +1,41 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") + kotlin("plugin.spring") version "1.9.23" + id("org.springframework.boot") version "3.4.4" + id("io.spring.dependency-management") version "1.1.7" + id("casper.documentation-convention") +} + +group = "hs.kr.entrydsm" +version = "0.0.1-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + // impl project + implementation(project(":casper-application-domain")) + + implementation("org.springframework.boot:spring-boot-starter") + implementation("org.jetbrains.kotlin:kotlin-reflect") + + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation(kotlin("test")) +} + +tasks.withType { + kotlinOptions { + freeCompilerArgs += "-Xjsr305=strict" + } +} + +tasks.withType { + useJUnitPlatform() +} + +kotlin { + jvmToolchain(17) +} diff --git a/src/main/kotlin/hs/kr/entrydsm/application/CasperApplication.kt b/casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/CasperApplication.kt similarity index 100% rename from src/main/kotlin/hs/kr/entrydsm/application/CasperApplication.kt rename to casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/CasperApplication.kt diff --git a/casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/TestClass3.kt b/casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/TestClass3.kt new file mode 100644 index 00000000..d421121f --- /dev/null +++ b/casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/TestClass3.kt @@ -0,0 +1,8 @@ +package hs.kr.entrydsm.application + +/** + * test + */ +class TestClass3 { + +} \ No newline at end of file diff --git a/casper-application-infrastructure/src/main/resources/application.yml b/casper-application-infrastructure/src/main/resources/application.yml new file mode 100644 index 00000000..e69de29b diff --git a/src/test/kotlin/hs/kr/entrydsm/application/CasperApplicationTests.kt b/casper-application-infrastructure/src/test/kotlin/hs/kr/entrydsm/application/CasperApplicationTests.kt similarity index 91% rename from src/test/kotlin/hs/kr/entrydsm/application/CasperApplicationTests.kt rename to casper-application-infrastructure/src/test/kotlin/hs/kr/entrydsm/application/CasperApplicationTests.kt index d540c305..10aafbd2 100644 --- a/src/test/kotlin/hs/kr/entrydsm/application/CasperApplicationTests.kt +++ b/casper-application-infrastructure/src/test/kotlin/hs/kr/entrydsm/application/CasperApplicationTests.kt @@ -3,13 +3,10 @@ package hs.kr.entrydsm.application import org.junit.jupiter.api.Test import org.springframework.boot.test.context.SpringBootTest -/** - * asdf - * - */ @SpringBootTest class CasperApplicationTests { + @Test fun contextLoads() { } -} +} \ No newline at end of file diff --git a/casper-convention/src/main/kotlin/io/casper/convention/plugins/DocumentationConventionPlugin.kt b/casper-convention/src/main/kotlin/io/casper/convention/plugins/DocumentationConventionPlugin.kt index 237739be..731f96ff 100644 --- a/casper-convention/src/main/kotlin/io/casper/convention/plugins/DocumentationConventionPlugin.kt +++ b/casper-convention/src/main/kotlin/io/casper/convention/plugins/DocumentationConventionPlugin.kt @@ -11,47 +11,94 @@ import org.gradle.kotlin.dsl.register /** * Casper 프로젝트의 KDoc 문서화 규칙을 정의하는 Gradle 플러그인입니다. + * 코드 요소(클래스, 함수, 프로퍼티 등)에 KDoc 주석이 있는지 확인하는 태스크를 제공합니다. */ class DocumentationConventionPlugin : Plugin { + /** + * 플러그인을 프로젝트에 적용합니다. + * 각 코드 요소별 문서화 확인 태스크와 통합 태스크를 등록하고, 빌드 라이프사이클에 연결합니다. + * + * @param project 플러그인이 적용될 프로젝트 + */ override fun apply(project: Project) { - with(project) { - // 현재 프로젝트에 태스크 등록 - registerDocTasks(this) - - // 모든 서브프로젝트에도 태스크 등록 - subprojects { - registerDocTasks(this) - } - } + project.logger.lifecycle("문서화 규칙 플러그인을 적용합니다: ${project.name}") + val registeredTasks = registerIndividualDocCheckTasks(project) + registerAggregateTask(project, registeredTasks) + connectToCheckLifecycle(project) } + /** + * 각 코드 요소(클래스, 함수, 프로퍼티 등)별로 개별 문서화 확인 태스크를 등록합니다. + * DocCheckTaskType에 정의된 각 유형에 대해 DocCheckTask를 생성합니다. + * + * @param project 태스크가 등록될 프로젝트 + * @return 등록된 태스크 프로바이더 목록 + */ + private fun registerIndividualDocCheckTasks(project: Project): List> { + val registeredTasks = mutableListOf>() - private fun Project.registerDocTasks(project: Project) { - with(project) { - val registeredTasks = mutableListOf>() + DocCheckTaskType.values().forEach { taskType -> + val taskName = taskType.taskName - DocCheckTaskType.values().forEach { taskType -> - val task = tasks.register(taskType.taskName) { + // 이미 같은 이름의 태스크가 있는지 확인 + if (project.tasks.findByName(taskName) == null) { + val task = project.tasks.register(taskName) { group = DocConstants.DOC_GROUP description = taskType.description codeElement.set(taskType.codeElement) } registeredTasks.add(task) + project.logger.lifecycle("${project.name}에 ${taskName} 태스크를 등록했습니다.") + } else { + project.logger.lifecycle("${project.name}에 이미 ${taskName} 태스크가 있습니다.") + registeredTasks.add(project.tasks.named(taskName)) } + } + return registeredTasks + } - // 모든 문서화 검사를 한 번에 실행하는 태스크 - tasks.register("checkAllDocs") { - group = DocConstants.CHECK_GROUP - description = "모든 코드 요소의 KDoc 주석 여부를 확인합니다" + /** + * 모든 개별 문서화 확인 태스크를 한 번에 실행하는 통합 태스크를 등록합니다. + * 이 태스크는 모든 개별 태스크에 의존하므로, 하나의 명령으로 모든 확인을 실행할 수 있습니다. + * + * @param project 태스크가 등록될 프로젝트 + * @param individualTasks 의존할 개별 태스크 목록 + */ + private fun registerAggregateTask(project: Project, individualTasks: List>) { + // 모든 문서화 검사를 한 번에 실행하는 태스크 + if (project.tasks.findByName(CHECK_ALL_DOCS_TASK) == null) { + project.tasks.register(CHECK_ALL_DOCS_TASK) { + group = DocConstants.CHECK_GROUP + description = "모든 코드 요소의 KDoc 주석 여부를 확인합니다" - // 등록된 모든 검사 태스크에 의존 - dependsOn(registeredTasks) + // 등록된 모든 검사 태스크에 의존 + dependsOn(individualTasks) + } + project.logger.lifecycle("${project.name}에 ${CHECK_ALL_DOCS_TASK} 태스크를 등록했습니다.") + } + } + + /** + * 문서화 확인 태스크를 프로젝트의 기본 check 태스크에 연결합니다. + * 이를 통해 일반적인 빌드 라이프사이클에 문서화 확인이 포함됩니다. + * + * @param project 연결될 프로젝트 + */ + private fun connectToCheckLifecycle(project: Project) { + // 프로젝트 평가 후에 check 태스크가 있으면 checkAllDocs를 의존성으로 추가 + project.afterEvaluate { + project.tasks.findByName("check")?.dependsOn(CHECK_ALL_DOCS_TASK) + project.logger.lifecycle("${project.name}의 check 태스크에 ${CHECK_ALL_DOCS_TASK} 의존성을 추가했습니다.") + } } - // 빌드 검증 과정에 문서화 검사 포함 - tasks.named("check") { - dependsOn("checkAllDocs") + /** + * 플러그인 내에서 사용되는 상수 값들을 정의합니다. + */ + companion object { + /** + * 모든 문서화 확인 태스크를 실행하는 통합 태스크의 이름입니다. + */ + const val CHECK_ALL_DOCS_TASK = "checkAllDocs" } -} -} } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 998fa7c2..d3b24e25 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,3 +14,7 @@ dependencyResolutionManagement { mavenCentral() } } + +include(":casper-application-domain") + +include("casper-application-infrastructure") diff --git a/src/main/kotlin/hs/kr/entrydsm/application/example/DocumentationExampleService.kt b/src/main/kotlin/hs/kr/entrydsm/application/example/DocumentationExampleService.kt deleted file mode 100644 index ba51a97a..00000000 --- a/src/main/kotlin/hs/kr/entrydsm/application/example/DocumentationExampleService.kt +++ /dev/null @@ -1,110 +0,0 @@ -package hs.kr.entrydsm.application.example - -import org.springframework.stereotype.Service - -/** - * KDoc 주석 검사를 테스트하기 위한 예제 서비스 클래스입니다. - * 이 클래스는 다양한 함수 타입과 주석 패턴을 보여주기 위한 목적으로 작성되었습니다. - * - * @author EntryDSM - * @since 1.0.0 - */ -@Service -class DocumentationExampleService { - /** - * 매개변수 없는 공개 함수의 예제입니다. - * 간단한 문자열을 반환합니다. - * - * @return 표준 인사말 문자열 - */ - fun publicFunction(): String { - return "Hello from public function" - } - - /** - * 매개변수가 있는 공개 함수 예제입니다. - * 입력받은 이름으로 개인화된 인사말을 생성하여 반환합니다. - * - * @param name 인사할 대상의 이름 - * @return 이름을 포함한 개인화된 인사말 - * @throws IllegalArgumentException 이름이 빈 문자열인 경우 - */ - fun publicFunctionWithParam(name: String): String { - return "Hello, $name!" - } - - /** - * 문자열을 대문자로 변환하는 비공개 헬퍼 함수입니다. - * 내부적으로만 사용되며 주로 [publicFunctionWithParam]에서 호출됩니다. - * - * @param text 대문자로 변환할 문자열 - * @return 대문자로 변환된 문자열 - * @see publicFunctionWithParam - */ - private fun privateFunction(text: String): String { - return text.uppercase() - } - - /** - * 주어진 문자열을 지정된 횟수만큼 중복시키는 내부 유틸리티 함수입니다. - * 텍스트 패턴을 반복해야 할 때 사용합니다. - * - * @param text 중복할 문자열 - * @param times 중복 횟수 (음수인 경우 빈 문자열 반환) - * @return 지정된 횟수만큼 중복된 문자열 - * @sample - * duplicateText("Hello", 3) // 결과: "HelloHelloHello" - */ - private fun duplicateText( - text: String, - times: Int, - ): String { - return text.repeat(times) - } -} - -/** - * 사용자 정보를 저장하기 위한 데이터 클래스입니다. - * API 응답 및 서비스 간 데이터 전송에 사용됩니다. - * - * @property id 사용자의 고유 식별자 - * @property name 사용자의 실명 또는 닉네임 - * @property email 사용자의 이메일 주소 (통신 용도) - * @constructor 모든 필수 속성을 가진 사용자 DTO 인스턴스를 생성합니다 - */ -data class UserDto( - val id: Long, - val name: String, - val email: String, -) - -/** - * 문자열 조작을 위한 유틸리티 함수를 제공하는 오브젝트입니다. - * 애플리케이션 전반에서 사용되는 문자열 관련 공통 기능을 중앙화합니다. - * - * @since 1.0.0 - */ -object StringUtils { - /** - * 문자열이 비어 있거나 null인지 확인합니다. - * 유효성 검사에 유용하게 사용됩니다. - * - * @param text 확인할 문자열 (null 가능) - * @return 문자열이 null이거나 빈 문자열이면 true, 그렇지 않으면 false - */ - fun isEmpty(text: String?): Boolean { - return text.isNullOrEmpty() - } - - /** - * 문자열의 좌우 공백을 제거합니다. - * 사용자 입력 정제에 유용합니다. - * - * @param text 처리할 문자열 - * @return 좌우 공백이 제거된 문자열 - * @throws NullPointerException text가 null인 경우 - */ - fun trim(text: String): String { - return text.trim() - } -} diff --git a/src/main/kotlin/hs/kr/entrydsm/application/example/UndocumentedExamples.kt b/src/main/kotlin/hs/kr/entrydsm/application/example/UndocumentedExamples.kt deleted file mode 100644 index b45f499e..00000000 --- a/src/main/kotlin/hs/kr/entrydsm/application/example/UndocumentedExamples.kt +++ /dev/null @@ -1,73 +0,0 @@ -package hs.kr.entrydsm.application.example - -/** - * 문서화되지 않은 요소들을 보여주는 예제 클래스입니다. - * 이 클래스는 KDoc 주석 검사 시스템을 테스트하기 위해 사용됩니다. - */ -class UndocumentedExamples { - /** - * 이전에 문서화되지 않았던 함수의 예시입니다. - * 간단한 문자열을 반환합니다. - * - * @return "This function has no KDoc" 문자열 - */ - fun undocumentedFunction(): String { - return "This function has no KDoc" - } - - /** - * 매개변수가 있는 함수 예시입니다. - * 문자열의 길이를 반환합니다. - * - * @param param 길이를 계산할 문자열 - * @return 문자열의 길이 - */ - fun anotherUndocumentedFunction(param: String): Int { - return param.length - } - - /** - * 비공개 헬퍼 함수입니다. - * 콘솔에 메시지를 출력합니다. - */ - private fun privateUndocumentedFunction() { - println("Private function without KDoc") - } -} - -/** - * 유틸리티 기능을 제공하는 싱글톤 객체입니다. - * 이 객체는 정적 메소드와 속성을 그룹화합니다. - */ -object UndocumentedObject { - /** - * 객체의 예시 속성입니다. - */ - val someProperty = "No KDoc here" - - /** - * 객체 내의 유틸리티 함수입니다. - * 간단한 메시지를 콘솔에 출력합니다. - */ - fun objectFunction() { - println("Function in undocumented object") - } -} - -/** - * 문서화 검사 예제를 위한 인터페이스입니다. - * 이 인터페이스는 구현 클래스가 따라야 할 계약을 정의합니다. - */ -interface UndocumentedInterface { - /** - * 인터페이스에서 정의된 메소드입니다. - * 구현 클래스에서 이 메소드를 구현해야 합니다. - */ - fun interfaceMethod() - - /** - * 인터페이스에서 정의된 속성입니다. - * 구현 클래스에서 이 속성에 대한 접근자를 제공해야 합니다. - */ - val interfaceProperty: String -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 245f33c7..00000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=Casper-Application