Gradle Kotlin 컨벤션 플러그인을 사용한 모듈 관리 -3 Convention Plugin 적용

TRASALBY·2024년 4월 23일
1

Android

목록 보기
10/10
post-thumbnail

Gradle Plugin이란?

이전 글에서 언급했든 우리는 안드로이드를 개발하면서 계속 plugin을 사용해 왔다.

안드로이드의 Gradle Plugin은 쉽게 말해 Gradle의 작업(Task)들을 묶어둔 하나의 작업 단위 이다. 애플리케이션의 빌드과정을 관리하고 필요한 Task를 정의해 주어 관련된 복잡한 작업을 손쉽게 처리할 수 있도록 도와준다.

구체적으로 Gradle에 관한 글은 나중에 추가로 작성하도록하겠다.

Convention Plugin

모듈에 특정한 컨벤션을 적용하는 플러그인

앞선 글로 version catalog를 사용해 dependency의 버전을 일괄적으로 관리하는 방법을 알아보았다.

Convention Plugin은 여기서 한발 더 나아가 각 모듈에서 공통된 빌드 구성을 뽑아내고 이를 재사용할 수 있도록 구성하는 방법이다.

이러한 방식은 다음과 같은 이점을 가질 수 있다.

  • 코틀린 사용 : 함수형 프로그래밍, 가독성
  • 재빌드 최소화 : 변경된 로직을 사용하는 모듈만 재빌드
  • 명확한 의존성 관리 : 각 플러그인과 모듈별로 의존성을 분리하여 관리
  • 캐싱 개선 : Gradle의 캐싱 기능을 효과적으로 활용해 빌드 성능 최적화

적용 방법

build-logic 모듈 생성

build-logic:convention모듈을 Java or Kotlin Library로 생성한다.

그리고 convention안의 build.gradle.kts 파일을 다음과 같이 선언한다.

plugins {
    `kotlin-dsl`
}

group = "com.sixkids.ulban.buildlogic"

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

dependencies{
    compileOnly(libs.android.gradle.plugin)
    compileOnly(libs.kotlin.gradle.plugin)
}

컴파일 시점에만 필요한 내용을 compileOnly로 선언해 준다고 한다(사실 여기에 구체적으로 어떤 것들이 들어가야하는지 좀더 확인해 볼 필요가 있다.)

이후 build-logic의 하위에 settings.gradle.kts 파일을 생성하고 다음과 같이 작성한다.

//settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

rootProject.name = "build-logic"
include(":convention")

마지막으로 프로젝트 root의 settings.gradle.kts에서 자동으로 생성된
include(":build-logic")과 include(":build-logic:convention")를 지워줘고 pluginManagement에 includeBuild("build-logic")을 넣어준다.

pluginManagement {
    repositories {
    	...
        includeBuild("build-logic")
    }
}
...
include(":app")
include(":domain")
include(":data")
//include(":build-logic") 제거
//include(":build-logic:convention") 제거

확장 함수 선언 및 const 선언

Const.kt
object Const {
    const val COMPILE_SDK = 34
    const val MIN_SDK = 26
    const val TARGET_SDK = 34
    val JAVA_VERSION = JavaVersion.VERSION_17
}
//KotlinAndorid.kt
internal fun Project.configureKotlinAndroid(
    commonExtension: CommonExtension<*, *, *, *, *, *>,
){
    commonExtension.apply {
        compileSdk = Const.COMPILE_SDK
        defaultConfig {
            minSdk = Const.MIN_SDK
            testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
            vectorDrawables{
                useSupportLibrary = true
            }
        }

        buildTypes {
            named("release"){
                isMinifyEnabled = false
                proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.pro"
                )
            }
        }

        compileOptions {
            sourceCompatibility = Const.JAVA_VERSION
            targetCompatibility = Const.JAVA_VERSION
        }

        kotlinOptions {
            jvmTarget = Const.JAVA_VERSION.toString()
        }

        packaging {
            resources {
                excludes += "/META-INF/{AL2.0,LGPL2.1}"
            }
        }
    }
}
internal fun CommonExtension<*, *, *, *, *, *>.kotlinOptions(
    block: KotlinJvmOptions.() -> Unit
){
    (this as ExtensionAware).extensions.configure("kotlinOptions", block)
}

공통으로 사용되는 gradle의 속성값들을 뽑아내어 확장 함수로 선언한다.

컨벤션 플러그인 추가

업로드중..

//AndroidApplicationConventionPlugin.kt
@Suppress("unused")
internal class AndroidApplicationConventionPlugin : Plugin<Project>{
    override fun apply(target: Project) {
        with(target){
            with(pluginManager){
                apply("com.android.application")
                apply("org.jetbrains.kotlin.android")
            }

            extensions.configure<ApplicationExtension>{
                configureKotlinAndroid(this)
                defaultConfig.targetSdk = Const.TARGET_SDK
            }

        }
    }
}

프로젝트에 맞게 컨벤션을 생성하면 된다.

플러그인 등록

build-logic:convention 모듈의 build.gradle.kts 파일에 새로 생성한 컨벤션을 등록해 준다.


gradlePlugin {
    plugins {
        register("androidApplication"){
            id="sixkids.android.application"
            implementationClass = "AndroidApplicationConventionPlugin"
        }
    }
}

이제 version catalog와 함께 플러그인을 사용 할 수 있다.

[plugins]
sixkids-android-application = { id = "sixkids.android.application", version = "unspecified" }

직접 만든 플러그인을 등록하고 원하는 모듈에서 해당 플러그인을 불러와 사용할 수 있다.

plugins{
  ...
  alias(libs.plugins.sixkids.android.application)
}

1개의 댓글

comment-user-thumbnail
2024년 4월 25일

따봉박고 갑니다

답글 달기