Skip to content

Comments

build-logic 추가#39

Merged
chanho0908 merged 12 commits intomainfrom
feature/38-build-logic
Jan 20, 2026
Merged

build-logic 추가#39
chanho0908 merged 12 commits intomainfrom
feature/38-build-logic

Conversation

@chanho0908
Copy link
Owner

@chanho0908 chanho0908 commented Jan 20, 2026

이슈 번호

#38

작업내용

  • build-logic 모듈 추가 및 settings.gradle.ktsincludeBuild("build-logic") 연결
  • KMP/Android/iOS/Compose/Feature 컨벤션 플러그인 구성 및 등록
  • 버전 카탈로그 확장 함수 추가로 Java/JVM 타겟 설정 일원화
  • Compose 관련 플러그인 정의 정리 및 debugImplementation 가드 추가
  • gradle.properties 빌드 성능/메모리 옵션 정비
  • gradle/libs.versions.toml에 droidmorning 플러그인 ID 등록

chanho0908 and others added 6 commits January 20, 2026 01:18
feature 모듈 분리를 위한 Gradle Convention Plugin 구조를 구축했습니다.
- KMP, Android, Compose 설정을 중앙화하여 일관된 빌드 환경 제공
- 향후 feature 모듈 생성 시 반복적인 설정 작업 최소화

🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
DroidKnights 프로젝트 구조를 참조하여 build-logic을 개선했습니다.
- primitive 패키지로 세분화된 플러그인 구조 구현
- Extension 유틸리티 함수로 깔끔한 코드 작성
- Feature 모듈용 통합 플러그인(droidmorning.feature) 추가
- Compose 의존성을 함수로 분리하여 재사용성 향상

🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
libs.versions.toml의 Gradle 플러그인 설정을 수정했습니다.
- compose-gradle-plugin을 정확한 artifact로 변경
  (org.jetbrains.compose:compose-gradle-plugin)
- compose-compiler-gradle-plugin 별도 추가
- freeCompilerArgs를 compilerOptions DSL로 마이그레이션

🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
composeDependencies.uiTooling과 composeDependencies.preview가
deprecated되어 직접 모듈 참조로 변경했습니다.
- org.jetbrains.compose.ui:ui-tooling 직접 사용
- preview는 ui-tooling에 포함되어 제거

🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
기존 프로젝트 모듈들을 분석하여 Feature 플러그인을 개선했습니다.

**주요 변경사항:**
- JVM 타겟을 17에서 11로 변경 (프로젝트 표준)
- compileSdk 35 → 36, minSdk 26 → 24 통일
- kotlin-serialization 플러그인 추가
- Koin 의존성을 bundle로 변경 (core, compose, compose-viewmodel)
- Kotlinx 핵심 라이브러리 추가 (coroutines, serialization, datetime)
- lifecycle-viewmodel-compose 추가
- commonTest 의존성 설정 추가 (kotlin-test, koin-test, coroutines-test)

🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
- Convention Plugin 패키지 구조 평탄화 (app/ 디렉토리 제거)
- Extension 함수들을 extentions 패키지로 분리
- VersionCatalogExtensions 추가하여 타입 안전성 개선
- ComposeExtensions를 ProjectExtensions에 통합
- README 문서 업데이트 (모듈화 가이드 개선)
- Gradle 메모리 설정 최적화

🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

build-logic 모듈이 새로 추가되어 Gradle Convention Plugin을 중앙화합니다. build-logic/convention/build.gradle.kts에서 Java/Kotlin 타겟을 정렬하고 compileOnly 종속성을 추가한 뒤, gradlePlugin 블록으로 7개의 공개 플러그인(droidmorning.kmp, droidmorning.kmp.android, droidmorning.kmp.ios, droidmorning.android.library, droidmorning.kotlin.multiplatform, droidmorning.compose.multiplatform, droidmorning.feature)을 등록합니다. 다수의 Kotlin 기반 Convention Plugin 클래스(KotlinMultiPlatformPlugin, KotlinMultiPlatformAndroidPlugin, KotlinMultiPlatformiOSPlugin, AndroidLibraryConventionPlugin, ComposeMultiplatformConventionPlugin, DroidMorningFeaturePlugin)와 유틸 확장(ProjectExtensions, VersionCatalogExtensions)이 추가되었습니다. settings.gradle.kts에 includeBuild("build-logic")가 추가되고 build-logic/settings.gradle.kts 및 gradle/libs.versions.toml이 갱신되며 gradle.properties의 JVM 옵션과 병렬 빌드 설정이 변경되었습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


📋 상세 리뷰

긍정적 요약

  • Convention Plugin 패턴을 일관되게 적용해 빌드 설정을 중앙화했습니다.
  • 재사용 가능한 확장(ProjectExtensions, VersionCatalogExtensions)으로 중복을 줄였습니다.
  • includeBuild("build-logic") 및 build-logic/settings 설정으로 플러그인 노출 방식이 명확해졌습니다.

개선할 점 (왜 문제가 되는지 → 어떻게 개선할지)

  1. 플러그인 적용 순서와 전제조건 불명확
  • 왜 문제인가: DroidMorningFeaturePlugin 등에서 특정 확장이나 플러그인이 존재한다고 가정하면 적용 시점에 오류가 발생할 수 있습니다.
  • 어떻게 개선할지: apply 내부에서 전제 플러그인 존재 여부를 검증하거나(pluginManager.hasPlugin/require), 필요한 플러그인을 명시적으로 pluginManager.apply("id")로 적용하세요. 에러 메시지를 명확히 하면 원인 파악이 쉬워집니다.
  1. VersionCatalog 확장 함수의 예외 메시지 부족
  • 왜 문제인가: findVersion(name).get() 등은 항목이 없을 때 NoSuchElementException을 던져 디버깅이 어렵습니다.
  • 어떻게 개선할지: orElseThrow로 친절한 메시지를 제공하거나 찾지 못했을 때 대체값/로그를 남기세요. 예:
    internal fun VersionCatalog.version(name: String): String =
    findVersion(name).orElseThrow { NoSuchElementException("libs.versions.toml에 '$name' 버전이 없습니다") }.requiredVersion
  1. KotlinMultiPlatformAndroidPlugin의 소스셋/리소스 재정의 복잡성
  • 왜 문제인가: AGP 기본 동작과 충돌하거나 유지보수가 어려울 수 있습니다.
  • 어떻게 개선할지: 변경 목적을 주석으로 명시하거나 공통 함수로 추출해 의도를 문서화하세요. 꼭 필요한 경우만 한정적으로 적용하세요.
  1. KotlinNativeLink와 구성 캐시 불호환 처리
  • 왜 문제인가: notCompatibleWithConfigurationCache 설정은 구성 캐시 사용성을 떨어뜨립니다.
  • 어떻게 개선할지: 불호환 원인을 주석으로 명확히 기록하고, 가능하면 시스템 프로퍼티 접근을 지연시켜 캐시 호환성을 확보하세요.
  1. libs.versions.toml에 플러그인을 libraries와 plugins 모두 등록한 중복성
  • 왜 문제인가: 중복 등록은 혼란을 초래할 수 있습니다(참조 방식 혼동).
  • 어떻게 개선할지: libraries와 plugins의 의도를 명확히 구분하고, 불필요한 중복은 제거하거나 주석으로 목적을 설명하세요.
  1. gradle.properties의 JVM 옵션 변경 영향
  • 왜 문제인가: -Xmx8g, MaxMetaspaceSize 등은 로컬/CI 환경에서 리소스 문제를 일으킬 수 있습니다.
  • 어떻게 개선할지: 환경별 설정(예: CI 전용)을 고려하거나 변경 사유와 영향 범위를 문서화하세요.

확인/토론용 질문

  • libraries와 plugins 양쪽에 동일한 droidmorning 엔트리를 추가한 의도가 무엇인가요? (사용 사례를 공유해 주세요.)
  • KotlinMultiPlatformAndroidPlugin에서 소스셋/asset 경로를 재정의한 구체적 사례가 있나요? 어떤 문제를 해결하기 위함인지 예시를 부탁드립니다.
  • Configuration cache 불호환 원인을 해결할 계획이 있으신가요? 우선순위가 어떻게 되나요?

제안(추가 안전장치)

  1. build-logic/README 추가: 각 플러그인의 목적, 적용 순서, 예시를 문서화하세요.
  2. 간단한 샘플 모듈로 통합 테스트를 추가해 플러그인 적용 안전성을 검증하세요.
  3. VersionCatalog 확장과 다른 핵심 지점에 상세한 예외 메시지와 주석을 추가해 디버깅 비용을 낮추세요.

전반적으로 중앙화된 빌드 로직과 유틸성 확장은 좋은 출발입니다. 위 개선사항을 반영하면 안정성과 유지보수성이 더 향상될 것입니다.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 사항의 주요 내용을 명확하게 반영합니다. 'build-logic 추가'는 이 PR의 핵심 변경사항(build-logic 모듈 추가)을 정확하게 요약합니다.
Description check ✅ Passed PR 설명이 변경 사항과 충분히 관련되어 있으며, 작업 내용을 상세히 기술하고 있습니다. 이슈 번호 참조, 각 항목별 작업 내용, 그리고 전체 변경 범위가 명확히 설명되어 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chanho0908 chanho0908 changed the title build-logic 패키지 구조 개선 및 문서화 build-logic 추가 Jan 20, 2026
@chanho0908 chanho0908 self-assigned this Jan 20, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In
`@build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/ProjectExtensions.kt`:
- Around line 33-46: composeMultiplatformDependencies 함수에서 순수 KMP 모듈에는
"debugImplementation" 구성이 없을 수 있어 빌드가 깨집니다; dependencies 블록을 호출하기 전에
Project.configurations.findByName("debugImplementation")로 해당 구성이 존재하는지 검사하고 존재할
때만 "debugImplementation"(libs.library("compose-ui-tooling"))를 추가하도록 변경하세요; 위치는
Project.composeMultiplatformDependencies 내 dependencies 추가 부분이며
KotlinMultiplatformExtension 설정은 그대로 유지하면 됩니다.

In
`@build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformPlugin.kt`:
- Around line 18-21: Remove the direct application of the "kotlin-multiplatform"
plugin from KotlinMultiPlatformPlugin so it becomes configuration-only: delete
the apply(libs.plugin("kotlin-multiplatform").pluginId) call inside
KotlinMultiPlatformPlugin and keep only the
extensions.configure<KotlinMultiplatformExtension> { ... } setup logic; in
contrast, ensure KotlinMultiplatformConventionPlugin is the single place that
applies the plugin and then applies the configuration plugin (use
apply(libs.plugin("kotlin-multiplatform").pluginId) in
KotlinMultiplatformConventionPlugin followed by
apply<KotlinMultiPlatformPlugin>() so convention applies the plugin and
KotlinMultiPlatformPlugin only provides settings), and update any references
like DroidMorningFeaturePlugin to rely on the convention plugin for plugin
application.

In `@build-logic/README.md`:
- Around line 95-99: The README's Android Library settings are out of sync with
the implementation; update the documentation to match the actual values declared
in AndroidLibraryConventionPlugin.kt (e.g., compileSdk = 36, minSdk = 24, Java
compatibility = Java 11 / JavaVersion.VERSION_11, BuildConfig enabled) or
alternately change the implementation in AndroidLibraryConventionPlugin (the
class and its compileSdk/minSdk/Java compatibility assignments) to match the
README—pick one approach and make both sources consistent.
- Around line 64-66: The README claims "Android target (JVM 17)" but the
implementation in KotlinMultiPlatformAndroidPlugin.kt and
KotlinMultiPlatformPlugin.kt sets JvmTarget.JVM_11; fix by making doc and code
consistent: either update the README to state JVM 11 or change the JvmTarget
usage in the KotlinMultiPlatformAndroidPlugin and KotlinMultiPlatformPlugin
classes from JvmTarget.JVM_11 to JvmTarget.JVM_17 (and adjust any related
compilation settings), ensuring the JvmTarget symbol and any target
compatibility settings are updated together.
- Around line 283-301: Update the README directory tree to reflect the actual
package layout after the "package flattening" change: replace occurrences of
com/peto/droidmorning/app/ with com/peto/droidmorning/, remove or relocate the
primitive/ subsection (or list its files at the top-level) so entries like
KotlinMultiPlatformPlugin.kt, KotlinMultiPlatformAndroidPlugin.kt, and
KotlinMultiPlatformiOSPlugin.kt match their real locations, and ensure the
example file list (AndroidLibraryConventionPlugin.kt,
KotlinMultiplatformConventionPlugin.kt, ComposeMultiplatformConventionPlugin.kt,
DroidMorningFeaturePlugin.kt) reflects the current package structure exactly.

In `@gradle/libs.versions.toml`:
- Around line 67-68: Remove the obsolete compose-compiler-gradle-plugin entry
from libs.versions.toml (the entry named compose-compiler-gradle-plugin) because
Kotlin 2.3.0 uses org.jetbrains.kotlin.plugin.compose (the kotlin-compose entry
already defined) instead; leave compose-gradle-plugin in place and, if you
prefer not to delete, replace the entry with a short “deprecated/unused” comment
to make the intent explicit and avoid confusion about compatibility with Kotlin
2.3.0 and Compose Multiplatform 1.10.0.
🧹 Nitpick comments (8)
gradle.properties (1)

6-9: 병렬 빌드 + Xmx 8g 조합의 메모리 여유 확인을 권장합니다.

왜: 병렬 빌드와 큰 힙 설정이 겹치면 CI/로컬 환경에서 OOM로 불안정해질 수 있습니다.
어떻게: CI에 맞춰 org.gradle.workers.max로 상한을 두거나, 환경별 ~/.gradle/gradle.properties 오버라이드를 안내하는 방식이 안정적입니다. 필요하면 팀 문서에 최소 메모리 요구사항도 적어두는 게 좋겠습니다.

build-logic/convention/src/main/kotlin/com/peto/droidmorning/AndroidLibraryConventionPlugin.kt (1)

16-25: SDK 버전과 플러그인 ID를 버전 카탈로그로 통일하면 중복을 줄일 수 있습니다.

왜: 다른 플러그인에서는 libs.version("compileSdk")/minSdk를 쓰고 있어 한 곳만 하드코딩하면 추후 버전 변경 시 불일치가 생기기 쉽습니다.
어떻게: 아래처럼 버전 카탈로그를 사용해 단일 소스로 맞추는 것을 권장합니다. 코딩 가이드 기준입니다.

♻️ 제안 변경
-            with(pluginManager) {
-                apply("com.android.library")
-            }
+            with(pluginManager) {
+                apply(libs.plugin("android-library").pluginId)
+            }

             extensions.configure<LibraryExtension> {
-                compileSdk = 36
+                compileSdk = libs.version("compileSdk").toInt()

                 defaultConfig {
-                    minSdk = 24
+                    minSdk = libs.version("minSdk").toInt()
                 }
build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiplatformConventionPlugin.kt (1)

15-21: kotlin-multiplatform 적용이 중복됩니다.

왜: 여기서 한 번 적용하고, KotlinMultiPlatformPlugin에서도 다시 적용하면 책임 경계가 흐려져 추후 설정 순서/중복 판단이 어려워집니다.
어떻게: 둘 중 한 곳만 적용하도록 정리하면 더 명확합니다(권장: KotlinMultiPlatformPlugin 내부에만 두고 여기서는 제거). 코딩 가이드 기준입니다.

♻️ 제안 변경
-        with(pluginManager) {
-            apply(libs.plugin("kotlin-multiplatform").pluginId)
-        }
-
         apply<KotlinMultiPlatformPlugin>()
         apply<KotlinMultiPlatformAndroidPlugin>()
         apply<KotlinMultiPlatformiOSPlugin>()
build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformAndroidPlugin.kt (1)

19-29: Version Catalog 접근 방식이 일관되지 않습니다.

compileSdklibs.version("compileSdk")를 사용하지만, minSdklibs.findVersion("minSdk").get().requiredVersion을 직접 호출하고 있습니다. VersionCatalogExtensions.kt에 정의된 version() 확장 함수를 일관되게 사용하면 코드가 더 깔끔해집니다.

♻️ 일관된 API 사용 제안
 defaultConfig {
-    minSdk = libs.findVersion("minSdk").get().requiredVersion.toInt()
+    minSdk = libs.version("minSdk").toInt()
 }
build-logic/convention/src/main/kotlin/com/peto/droidmorning/DroidMorningFeaturePlugin.kt (1)

21-33: ComposeMultiplatformConventionPlugin과 설정이 중복됩니다.

현재 DroidMorningFeaturePlugin에서 직접 compose-multiplatform, kotlin-compose 플러그인을 적용하고 composeMultiplatformDependencies()를 호출하고 있습니다. 이는 ComposeMultiplatformConventionPlugin이 수행하는 작업과 동일합니다.

중복을 제거하고 재사용성을 높이려면 ComposeMultiplatformConventionPlugin을 적용하는 방식을 고려해 보세요:

♻️ 컨벤션 플러그인 재사용 제안
 with(pluginManager) {
     apply(libs.plugin("android-library").pluginId)
     apply(libs.plugin("kotlin-multiplatform").pluginId)
-    apply(libs.plugin("compose-multiplatform").pluginId)
-    apply(libs.plugin("kotlin-compose").pluginId)
     apply(libs.plugin("kotlin-serialization").pluginId)
 }

 apply<KotlinMultiPlatformPlugin>()
 apply<KotlinMultiPlatformAndroidPlugin>()
 apply<KotlinMultiPlatformiOSPlugin>()
+apply<ComposeMultiplatformConventionPlugin>()

-composeMultiplatformDependencies()
build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/VersionCatalogExtensions.kt (1)

1-1: 패키지 이름에 오타가 있습니다.

extentionsextensions로 수정하는 것이 좋습니다. 이 오타는 ProjectExtensions.kt와 README.md의 디렉토리 구조에서도 동일하게 나타납니다. 나중에 수정하려면 여러 파일을 변경해야 하므로, 지금 수정하는 것이 좋을 수 있습니다.

build-logic/README.md (1)

112-128: 코드 블록에 언어를 지정하면 linting 경고를 해결할 수 있습니다.

정적 분석 도구(markdownlint)가 언어가 지정되지 않은 코드 블록을 감지했습니다. 디렉토리 구조를 표시하는 블록에는 text 또는 plaintext를 사용할 수 있습니다.

📝 수정 예시
-```
+```text
 📁 build-logic              // Convention Plugin
 📁 app                      // Application 진입점
 ...
build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/ProjectExtensions.kt (1)

23-27: 예외 기반 흐름 제어/println 대신 findByType + 명확한 오류를 권장합니다.
runCatching + println은 구성 단계에서 불필요한 예외/표준출력을 유발할 수 있습니다. findByType로 분기하고 명확한 오류를 내는 편이 더 읽기 쉽고 로그 품질도 좋아집니다.

♻️ 제안 수정안
 internal val Project.androidExtension: CommonExtension<*, *, *, *, *, *>
-    get() = runCatching { libraryExtension }
-        .recoverCatching { applicationExtension }
-        .onFailure { println("Could not find Library or Application extension from this project") }
-        .getOrThrow()
+    get() = extensions.findByType<LibraryExtension>()
+        ?: extensions.findByType<ApplicationExtension>()
+        ?: error("Could not find Library or Application extension from this project")

Repository owner deleted a comment from coderabbitai bot Jan 20, 2026
Repository owner deleted a comment from coderabbitai bot Jan 20, 2026
chanho0908 and others added 4 commits January 20, 2026 13:00
🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
🤖 Generated with [Firebender](https://firebender.com)

Co-Authored-By: Firebender <help@firebender.com>
@chanho0908 chanho0908 merged commit 4df90d1 into main Jan 20, 2026
3 checks passed
@chanho0908 chanho0908 deleted the feature/38-build-logic branch January 20, 2026 04:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant