기존에 Java로 작성한 프로젝트를 Kotlin으로 변경하면서 gradle도 Kotlin DSL로 Migration 해야겠다 생각했는데, 하다보니 정리를 할 필요성을 느끼게 되어 작성해보고자 한다.
DSL
이란 Domain Specific Language
의 약어로 특정 분야에 최적화된 프로그래밍 언어를 뜻한다.
상용구 코드를 최소화 하기 위해 명령형 코드 대신 선언적 코드 형식
을 따른다.
Kotlin DSL은 코틀린의 언어적인 특징으로 가독성이 좋고 간략한 코드를 사용하여 Gradle 스크립팅을 하는 것을 목적으로 하는 DSL이다.
빌드 스크립트에서 사용하는 객체, 함수, 속성들은 Gradle API와 적용한 plugin API에서 가져온다.
왜 Groovy DSL 에서 Kotlin DSL로 변경해야 하는지... 의문이 들었다.🤔
Kotlin DSL로 변경하면 아래와 같은 장점이 있다.
컴파일 타임에 에러 확인
코드 탐색
자동 완성
구문 강조
IDE의 지원으로 향상된 편집환경
소스코드와 동일한 언어의 사용
반면 단점도 존재한다.
시작하기 전 아래 활동을 해준다.
buildSrc
디렉터리 생성build.gradle.kts
파일 생성plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
다양한 블로그를 참고하면 jcenter()로 나와있지만 deprecated 되어서 mavenCentral() 를 사용해주어야 한다.
여기까지 완료했다면 프로젝트에서 Kotlin DSL이 활성화되었을 것이다!!
buildSrc > src > main > java
폴더 생성
위 java 폴더 안에 앱 레벨, 버전 정보나 라이브러리 관련 버전 정보를 저장할 파일들을 생성해 줄 예정이다.
AppConfig
프로젝트와 관련된 앱 수준 구성을 한 번에 관리Versions
라이브러리 버전 관리를 한 곳에서 분리Dependencies
UI, 테스트 및 기타 타사 라이브러리와 관련된 앱의 모든 종속성이 포함object AppConfig {
const val compileSdk = 33
const val targetSdk = 33
const val minSdk = 24
const val versionCode = 1
const val versionName = "1.0.0"
const val buildToolsVersion = "29.0.3"
const val jvmTarget = "1.8"
}
object Versions {
// App Level
const val KOTLIN = "1.6.10"
// 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 Dependencies {
const val KOTLIN_STDLIB = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.KOTLIN}"
}
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}"
}
}
위 활동을 마쳤다면 마무리로 모든 .gradle 파일을 .gradle.kts
로 변환해주어야 한다. (Kotlin DSL 파일의 확장자는 .kts
이기 때문)
setting.gradle은 gradle 프로젝트를 세팅하기 위한 정보가 담겨있다. 이 gradle 파일을 .kts를 추가하여 변경해준다.
위와 같이 변경하였다면 내부 코드도 당연히 변경해주어야 한다.
변경 전
rootProject.name = "VelogProject"
include ':app'
변경 후
rootProject.name = "VelogProject"
include(":app")
Kotlin 에서는 ' 대신 "로 사용한다.
다음 build.gradle(project) 파일을 위와 같이 .kts를 추가하여 변경해준다.
그 다음 마찬가지로 내부 코드를 수정해주어야 한다.
변경 후
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:${Versions.GRADLE}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.KOTLIN}")
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
모듈 수준의 build.gradle 파일에는 '가 많기 때문에 모두 "로 변경해주어야 한다.
plugin 변경 후
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
android 블록 변경 후
안드로이드 블록은 함수 또는 내부 프로퍼티로 짜여있으므로 하나씩 잘 변경해주어야 한다.
android {
compileSdk = AppConfig.compileSdk
buildToolsVersion = AppConfig.buildToolsVersion
buildFeatures {
dataBinding = true
}
defaultConfig {
applicationId = "com.example.example"
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-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = AppConfig.jvmTarget
}
}
dependencies 블록 변경 후
dependencies {
implementation(Dependencies.KOTLIN_STDLIB)
// 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)
implementation(Dependencies.CARD_VIEW)
implementation(Dependencies.NAVIGATION_FRAGMENT)
implementation(Dependencies.NAVIGATION_UI)
implementation(Dependencies.GLIDE)
implementation(Dependencies.GLIDE_COMPILER)
implementation(Dependencies.RETROFIT)
implementation(Dependencies.CONVERTER_GSON)
implementation(Dependencies.GSON)
implementation(Dependencies.OKHTTP)
implementation(Dependencies.LOGGING_INTERCEPTOR)
implementation(Dependencies.ROOM)
implementation(Dependencies.LIFECYCLE_VIEWMODEL)
implementation(Dependencies.LIFECYCLE_LIVEDATA)
}
참고
https://medium.com/android-dev-hacks/kotlin-dsl-gradle-scripts-in-android-made-easy-b8e2991e2ba