지금까지는 Groovy DSL을 통해 의존성을 관리하고 있었고, 이를 너무 당연하게 생각하고 있었습니다.
Gradle 도움말 및 레시피를 보던 중 코드 예시가 Groovy/Kotlin으로 나뉘어 설명되어 있는 것을 보게 되었고..! 😲 (역시 공부할 건 끝이 없다..)
그리하여 새로운 프로젝트에는 한번 Kotlin DSL을 적용해 의존성을 관리해보기로 했습니다.
우선 DSL(Domain Specific Language)은 도메인 특화 언어를 말합니다.
즉, Kotlin-DSL은 코틀린의 언어적 특성을 살려 Gradle(빌드 배포 도구) 스크립트를 작성하는 것을 목적으로 하는 DSL인 것입니다.
// groovy로 문자열 작성 시 작은 따옴표(')와 큰 따옴표(") 둘 다 사용 가능
// 함수 호출 시 괄호 생략 가능
// 속성 할당 시 '=' 없이 할당 가능
android {
...
defaultConfig {
...
versionCode 1
}
}
dependencies {
testImplementation "junit:junit:4.12"
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
// kotlin으로 문자열 작성 시 모든 문자열을 큰따옴표(")로 작성
// 함수 호출 시 괄호 필요
// 속성 할당 시 '=' 필요
android {
...
defaultConfig {
...
versionCode = 1
}
}
dependencies {
testImplementation("junit:junit:4.12")
androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2")
}
아래 코드를 적어 줍니다.
plugins {
`kotlin-dsl` // enable the Kotlin-DSL
}
repositories {
google()
mavenCentral()
}
하나의 파일을 만들어 관리해주어도 좋지만, 저는 AppConfig.kt
와 Dependencies
파일을 만들어 분리해 관리하기로 했습니다.
ex)
// AppConfig.kt
object AppConfig {
const val compileSdk = 31
const val buildToolsVersion = "30.0.2"
const val minSdk = 24
const val targetSdk = 31
const val versionCode = 1
const val versionName = "0.0.1"
}
// Dependencies.kt
object Versions {
// AndroidX
const val APP_COMPAT = "1.4.1"
const val MATERIAL = "1.5.0"
const val CONSTRAINT_LAYOUT = "2.1.3"
// KTX
const val CORE = "1.7.0"
// TEST
const val JUNIT = "1.1.3"
// Android Test
const val ESPRESSO_CORE = "3.4.0"
}
object Libraries {
object AndroidX {
const val APP_COMPAT = "androidx.appcompat:appcompat:${Versions.APP_COMPAT}"
const val MATERIAL = "com.google.android.material:material:${Versions.MATERIAL}"
const val CONSTRAINT_LAYOUT = "androidx.constraintlayout:constraintlayout:${Versions.CONSTRAINT_LAYOUT}"
}
object KTX {
const val CORE = "androidx.core:core-ktx:${Versions.CORE}"
}
object Test {
const val JUNIT = "androidx.test.ext:junit:${Versions.JUNIT}"
}
object AndroidTest {
const val ESPRESSO_CORE = "androidx.test.espresso:espresso-core:${Versions.ESPRESSO_CORE}"
}
}
+) 참조한 medium글을 보니 아래 코드처럼 함수를 만들어 더욱 편리하게 사용할 수도 있는 것 같다. 중복되는 부분은 저렇게 하나로 묶어 선언해놓고 여러 모듈에서 가져다 쓰면 좋을 것 같다.
object Libraries {
//android ui
private val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
private val coreKtx = "androidx.core:core-ktx:${Versions.coreKtx}"
private val constraintLayout =
"androidx.constraintlayout:constraintlayout:${Versions.constraintLayout}"
val appLibraries = arrayListOf<String>().apply {
add(kotlinStdLib)
add(coreKtx)
add(appcompat)
add(constraintLayout)
}
}
//util functions for adding the different type dependencies from build.gradle file
fun DependencyHandler.kapt(list: List<String>) {
list.forEach { dependency ->
add("kapt", dependency)
}
}
fun DependencyHandler.implementation(list: List<String>) {
list.forEach { dependency ->
add("implementation", dependency)
}
}
fun DependencyHandler.androidTestImplementation(list: List<String>) {
list.forEach { dependency ->
add("androidTestImplementation", dependency)
}
}
fun DependencyHandler.testImplementation(list: List<String>) {
list.forEach { dependency ->
add("testImplementation", dependency)
}
}
ex) 나의 프레젠테이션 계층 모듈의 경우 (예시입니다!!!)
// build.gradle.kts(:presentation)
plugins {
id("com.android.application")
id("kotlin-android")
}
android {
compileSdk = AppConfig.compileSdk
buildToolsVersion = AppConfig.buildToolsVersion
defaultConfig {
applicationId = "com.yuuuzzzin.id"
minSdk = AppConfig.minSdk
targetSdk = AppConfig.targetSdk
versionCode = AppConfig.versionCode
versionName = AppConfig.versionName
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation(project(":data"))
implementation(project(":domain"))
// AndroidX
implementation(Libraries.AndroidX.APP_COMPAT)
implementation(Libraries.AndroidX.MATERIAL)
implementation(Libraries.AndroidX.CONSTRAINT_LAYOUT)
// KTX
implementation(Libraries.KTX.CORE)
// TEST
testImplementation(Libraries.Test.JUNIT)
// AndroidTest
androidTestImplementation(Libraries.AndroidTest.ESPRESSO_CORE)
}
ex) 나의 경우
// build.gradle.kts (project 수준)
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath ("com.android.tools.build:gradle:7.0.4")
classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
}
}
tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
// settings.gradle.kts
rootProject.name = "ProjectName"
/**
* presentation: 프레젠테이션 모듈
* data: 데이터 모듈
* domain: 도메인 모듈
*/
include(":presentation", ":data", ":domain")
참고
Groovy에서 KTS로 빌드 구성 이전
우아한 형제들 기술 블로그 - ‘Gradle Kotlin DSL’ 이야기
Gradle 공식 문서 - Kotlin DSL
Kotlin DSL: Gradle scripts in Android made easy