Skip to content

Commit a41dab2

Browse files
Merge pull request #4 from EntryDSM/test/2-code-convaintion
Feature/2 code convention
2 parents 5947755 + c389339 commit a41dab2

22 files changed

Lines changed: 875 additions & 13 deletions

File tree

build-logic/build.gradle.kts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
plugins {
2+
`kotlin-dsl`
3+
id("casper.documentation-convention")
4+
}
5+
6+
group = "io.casper.build"
7+
version = "1.0.0"
8+
9+
repositories {
10+
mavenCentral()
11+
}

build-logic/settings.gradle.kts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
rootProject.name = "build-logic"
2+
3+
pluginManagement {
4+
repositories {
5+
gradlePluginPortal()
6+
mavenCentral()
7+
}
8+
9+
// convention 모듈 참조
10+
includeBuild("../casper-convention")
11+
}
12+
13+
dependencyResolutionManagement {
14+
repositories {
15+
mavenCentral()
16+
}
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.casper.build
2+
3+
/**
4+
* 이 클래스는 KDoc 주석 검사 테스트를 위한 용도입니다.
5+
* 이제 올바른 KDoc 주석 형식을 사용합니다.
6+
*/
7+
class TestClass {
8+
/**
9+
* 이 함수는 KDoc 주석 검사 테스트를 위한 용도입니다.
10+
*
11+
* @return 항상 Unit을 반환합니다.
12+
*/
13+
fun testFunction() {
14+
println("이 함수는 문서화 검사를 테스트하기 위한 용도입니다.")
15+
}
16+
}

build.gradle.kts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,27 @@ plugins {
88
id("casper.documentation-convention")
99
}
1010

11+
// 모든 프로젝트(루트 및 서브프로젝트)에 공통 설정 적용
12+
allprojects {
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
// 모든 프로젝트에 플러그인 적용
18+
apply(plugin = "casper.documentation-convention")
19+
}
20+
21+
tasks.register("checkAll") {
22+
group = "verification"
23+
description = "모든 모듈(includeBuild 포함)에 대해 check 태스크를 실행합니다"
24+
25+
// 루트 프로젝트의 check 태스크에 의존
26+
dependsOn(tasks.named("check"))
27+
28+
// build-logic, convention 등 includeBuild 모듈의 check 태스크에 의존
29+
dependsOn(gradle.includedBuilds.map { it.task(":check") })
30+
}
31+
1132
group = "hs.kr.entrydsm"
1233
version = "0.0.1-SNAPSHOT"
1334

@@ -17,10 +38,6 @@ java {
1738
}
1839
}
1940

20-
repositories {
21-
mavenCentral()
22-
}
23-
2441
dependencies {
2542
implementation("org.springframework.boot:spring-boot-starter")
2643
implementation("org.jetbrains.kotlin:kotlin-reflect")

casper-convention/build.gradle.kts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
group = "io.casper.convention"
6+
version = "1.0.0"
7+
8+
repositories {
9+
mavenCentral()
10+
}
11+
12+
13+
// 중복 파일 처리 전략 설정
14+
tasks.withType<ProcessResources> {
15+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
16+
}
17+
18+
// 빌드 클린업 태스크
19+
tasks.register("cleanBuildDirs") {
20+
doLast {
21+
delete("build/pluginDescriptors")
22+
delete("build/resources/main/META-INF/gradle-plugins")
23+
}
24+
}
25+
26+
// processResources 태스크 전에 클린업 실행
27+
tasks.processResources {
28+
dependsOn("cleanBuildDirs")
29+
}
30+
31+
gradlePlugin {
32+
plugins {
33+
// 문서화 컨벤션 플러그인
34+
register("documentationConvention") {
35+
id = "casper.documentation-convention"
36+
implementationClass = "io.casper.convention.plugins.DocumentationConventionPlugin"
37+
}
38+
}
39+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.casper.convention.exception
2+
3+
import io.casper.convention.model.CodeElement
4+
import org.gradle.api.GradleException
5+
6+
7+
/**
8+
* 문서화 관련 예외를 처리하기 위한 예외 클래스
9+
* KDoc 문서화 검사 실패 시 발생
10+
* gradle 플러그인 모듈은 global Exception을 만들기 어려워서 따로 클래스로 만듦
11+
*
12+
* @param element 검사 대상 코드 요소
13+
* @param message 예외 메시지
14+
*/
15+
class DocumentationException(
16+
val element: CodeElement,
17+
message: String
18+
) : GradleException(message) {
19+
companion object {
20+
/**
21+
* 문서화 부재 예외를 생성
22+
*
23+
* @param element 문서화가 부재한 코드 요소
24+
* @return 생성된 DocumentationException 인스턴스
25+
*/
26+
fun missingDocumentation(element: CodeElement): DocumentationException {
27+
return DocumentationException(
28+
element = element,
29+
message = "일부 ${element.friendlyName}에 KDoc 주석이 없습니다. 자세한 내용은 로그를 확인하세요."
30+
)
31+
}
32+
}
33+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package io.casper.convention.model
2+
3+
/**
4+
* 코드 요소 종류를 정의하는 열거형 클래스입니다.
5+
* 각 코드 요소는 KDoc 검사 대상이 됩니다.
6+
*/
7+
enum class CodeElement(
8+
val friendlyName: String,
9+
val difficulty: Int,
10+
val helpMessage: String
11+
) {
12+
/**
13+
* Kotlin 클래스 정의
14+
*/
15+
CLASS(
16+
"클래스",
17+
3,
18+
"클래스 '%s'에 KDoc 주석이 없습니다."
19+
),
20+
21+
/**
22+
* Kotlin 객체 정의
23+
*/
24+
OBJECT(
25+
"객체",
26+
3,
27+
"객체 '%s'에 KDoc 주석이 없습니다."
28+
),
29+
30+
/**
31+
* Kotlin 인터페이스 정의
32+
*/
33+
INTERFACE(
34+
"인터페이스",
35+
3,
36+
"인터페이스 '%s'에 KDoc 주석이 없습니다."
37+
),
38+
39+
/**
40+
* Kotlin 함수 정의
41+
*/
42+
FUNCTION(
43+
"함수",
44+
4,
45+
"함수 '%s'에 KDoc 주석이 없습니다."
46+
),
47+
48+
/**
49+
* Kotlin 속성 정의
50+
*/
51+
PROPERTY(
52+
"속성",
53+
5,
54+
"속성 '%s'에 KDoc 주석이 없습니다."
55+
);
56+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.casper.convention.model
2+
3+
import org.gradle.internal.impldep.org.yaml.snakeyaml.TypeDescription
4+
5+
enum class DocCheckTaskType(
6+
7+
val taskName : String,
8+
val description: String,
9+
val codeElement: CodeElement
10+
) {
11+
12+
CLASS_DOC(
13+
taskName = "checkClassDocs",
14+
description = "클래스에 KDoc 주석이 있는지 확인합니다",
15+
codeElement = CodeElement.CLASS
16+
),
17+
OBJECT_DOC(
18+
taskName = "checkObjectDocs",
19+
description = "객체에 KDoc 주석이 있는지 확인합니다",
20+
codeElement = CodeElement.OBJECT
21+
),
22+
INTERFACE_DOC(
23+
taskName = "checkInterfaceDocs",
24+
description = "인터페이스에 KDoc 주석이 있는지 확인합니다",
25+
codeElement = CodeElement.INTERFACE
26+
),
27+
FUNCTION_DOC(
28+
taskName = "checkFunctionDocs",
29+
description = "함수에 KDoc 주석이 있는지 확인합니다",
30+
codeElement = CodeElement.FUNCTION
31+
),
32+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.casper.convention.model
2+
3+
/**
4+
* 문서화 문제를 나타내는 데이터 클래스입니다.
5+
* 코드 베이스에서 KDoc 주석이 누락된 요소에 대한 정보를 저장합니다.
6+
*/
7+
data class DocumentationProblem(
8+
/**
9+
* 문제가 발견된 코드 요소 유형
10+
*/
11+
val element: CodeElement,
12+
13+
/**
14+
* 요소의 이름 (클래스명, 함수명 등)
15+
*/
16+
val elementName: String,
17+
18+
/**
19+
* 파일의 전체 경로
20+
*/
21+
val filePath: String,
22+
23+
/**
24+
* 파일의 이름 (경로 제외)
25+
*/
26+
val fileName: String,
27+
28+
/**
29+
* 코드 요소가 선언된 줄 번호
30+
*/
31+
val lineNumber: Int
32+
) {
33+
/**
34+
* 사용자 친화적인 오류 메시지를 생성합니다.
35+
*
36+
* @return 파일명과 줄 번호가 포함된 형식화된 오류 메시지
37+
*/
38+
fun toUserFriendlyMessage(): String {
39+
val message = element.helpMessage.format(elementName)
40+
return "[$fileName:$lineNumber] $message"
41+
}
42+
43+
/**
44+
* 개발자를 위한 상세 오류 메시지를 생성합니다.
45+
*
46+
* @return 파일 경로와 줄 번호가 포함된 상세 오류 메시지
47+
*/
48+
fun toDetailedMessage(): String {
49+
return "${element.friendlyName} '$elementName'에 KDoc 주석이 없습니다. (파일: $filePath, 라인: $lineNumber)"
50+
}
51+
52+
/**
53+
* 로그 출력용 짧은 메시지를 생성합니다.
54+
*
55+
* @return 간결한 형식의 로그 메시지
56+
*/
57+
fun toLogMessage(): String {
58+
return "문서화 필요: ${element.friendlyName} '$elementName' ($fileName:$lineNumber)"
59+
}
60+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.casper.convention.plugins
2+
3+
import io.casper.convention.tasks.DocCheckTask
4+
import io.casper.convention.model.DocCheckTaskType
5+
import io.casper.convention.util.DocConstants
6+
import org.gradle.api.Plugin
7+
import org.gradle.api.Project
8+
import org.gradle.api.Task
9+
import org.gradle.api.tasks.TaskProvider
10+
import org.gradle.kotlin.dsl.register
11+
12+
/**
13+
* Casper 프로젝트의 KDoc 문서화 규칙을 정의하는 Gradle 플러그인입니다.
14+
*/
15+
class DocumentationConventionPlugin : Plugin<Project> {
16+
override fun apply(project: Project) {
17+
with(project) {
18+
// 현재 프로젝트에 태스크 등록
19+
registerDocTasks(this)
20+
21+
// 모든 서브프로젝트에도 태스크 등록
22+
subprojects {
23+
registerDocTasks(this)
24+
}
25+
}
26+
}
27+
28+
29+
private fun Project.registerDocTasks(project: Project) {
30+
with(project) {
31+
val registeredTasks = mutableListOf<TaskProvider<out Task>>()
32+
33+
DocCheckTaskType.values().forEach { taskType ->
34+
val task = tasks.register<DocCheckTask>(taskType.taskName) {
35+
group = DocConstants.DOC_GROUP
36+
description = taskType.description
37+
codeElement.set(taskType.codeElement)
38+
}
39+
registeredTasks.add(task)
40+
}
41+
42+
// 모든 문서화 검사를 한 번에 실행하는 태스크
43+
tasks.register("checkAllDocs") {
44+
group = DocConstants.CHECK_GROUP
45+
description = "모든 코드 요소의 KDoc 주석 여부를 확인합니다"
46+
47+
// 등록된 모든 검사 태스크에 의존
48+
dependsOn(registeredTasks)
49+
}
50+
51+
// 빌드 검증 과정에 문서화 검사 포함
52+
tasks.named("check") {
53+
dependsOn("checkAllDocs")
54+
}
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)