๐ Groovy ์์ KTS๋ก ์ ํํ๊ธฐ
๐ ๋ชฉํ
gradle ๊ด๋ฆฌ ์ธ์ด Groovy -> kts๋ก ๋ฐ๊พธ๊ธฐ
๐ Gradle
์๋๋ก์ด๋ ํ๋ก์ ํธ์์ ๋ค์ํ ์คํ ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ํ์ฉํ ์ ์๋ค๋ ๊ฒ ์ฅ์ ์ ๋๋ค.
ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ ๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๋๊ตฌ๊ฐ ํ์ํ๋ฐ, Android Studio์์๋ ๊ทธ ๋๊ตฌ๋ก Gradle์ ์ฌ์ฉํฉ๋๋ค.
Gradle์ JVM์์ ๋์ํ๋ ๋น๋ ์๋ํ ์์คํ ์ผ๋ก,
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ด๋ฆฌ ๋ฟ ์๋๋ผ ์ปดํ์ผ, ํ ์คํธ, ํจํค์ง ๋ฑ์ ๋น๋ ์์ ์ ์๋ํํ๋ ์ญํ ์ ํฉ๋๋ค.
๊ธฐ์กด์ ์กด์ฌํ๋ Ant, Maven์ ๋นํด ๊ฐ๊ฒฐํ๊ฒ ์์ฑํ ์ ์์ผ๋ฉฐ ์๋๊ฐ ๋น ๋ฅด๋ค๋ ๊ฒ์ด ์ฅ์ ์ ๋๋ค.
๐ Groovy vs KTS
Gradle์ ์๋ฐ์ ๋น์ทํ Groovy ์ธ์ด๋ก ์์ฑํ์๋๋ฐ, ์ด์ ๋ KTS(์ฝํ๋ฆฐ ์คํฌ๋ฆฝํธ)๋ก ์ด๋ฅผ ๋์ฒดํ ์ ์์ต๋๋ค.
Groovy๋ฅผ ๋์ฒดํ๋ KTS์ ์ฅ์ ์ ์๋์ ๊ฐ์ต๋๋ค.
- Groovy ์ธ์ด๋ฅผ ๋ฐ๋ก ๋ฐฐ์ฐ์ง ์์๋ ๋๋ค.
- Groovy๋ ํ์ผ์ ์คํํด์ผ ์ค๋ฅ๋ฅผ ๊ฐ์งํ๋ ๋ฐ๋ฉด, KTS๋ ์ปดํ์ผ ํ์์ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ ์ ์๋ค.
- IDE๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์๋์์ฑ์ ์ง์ํ๋ค.
๊ทธ๋ฌ๋ Groovy๋ณด๋ค ๋๋ฆฌ๋ค๋ ๋จ์ ์ด ์กด์ฌํฉ๋๋ค.
๋น๋ก ๋๋ ค์ง๋ค๋ ๋จ์ ์ด ์์์ง๋ง (์ ๋ง ๊ฝค ๋๋ ค์ง๋๋ค)
๋ ์ ์๋ ์ฝํ๋ฆฐ์ ์ฌ์ฉํ๊ณ ์ถ์๊ณ , gradle ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ๊ด๋ฆฌํ๊ณ ์ ํ๋ ๋ชฉ์ ์ ๊ฐ์ง๊ณ ํ๋ก์ ํธ์ KTS๋ฅผ ๋์ ํ๊ฒ ๋์์ต๋๋ค.
๐ KTS Migration
KTS๋ก ์ ํํ๊ธฐ ์ํด์
1. .gradle ํ์ผ์ .gradle.kts๋ก ํ์ผ ์ด๋ฆ์ ๋ณ๊ฒฝํ๊ณ
2. ์ฝํ ์ธ ๋ฅผ KTS ๋ฌธ๋ฒ์ ๋ง๊ฒ ์์ ํ๋ ๊ณผ์ ์ด ํ์ํฉ๋๋ค.
์ ๊ณผ์ ์ ์งํํ๊ธฐ ์์ build.gradle ์ฝ๋๋ฅผ ์ข ๋ ๊น๋ํ๊ฒ ๊ด๋ฆฌํ๊ธฐ ์ํด์
buildSrc ๋๋ ํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ์์กด์ฑ ๊ด๋ จ ๋ด์ฉ์ ์์๋ก ์ ์ํ์ฌ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
1. ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ buildSrc ๋๋ ํ ๋ฆฌ ์์ฑ
buildSrc ๋๋ ํ ๋ฆฌ์์๋ KTS ๋น๋ ์คํฌ๋ฆฝํธ ์ ์ฒด์์ ์ฌ์ฉํ ์ ์๋ ์์ ๊ณผ ๋๊ตฌ๋ฅผ ์ ์ํฉ๋๋ค.
1. ํ๋ก์ ํธ ๋ฃจํธ์ buildSrc ๋๋ ํ ๋ฆฌ ์์ฑ (New → Directory)
2. buildSrc ๋๋ ํ ๋ฆฌ์ build.gradle.kts ํ์ผ ์ถ๊ฐ ํ sync
plugins {
`kotlin-dsl`
}
repositories {
google()
mavenCentral()
}
2. gradle ๊ด๋ฆฌ์ ํ์ํ ์ค์ ํ์ผ ๋ง๋ค๊ธฐ
buildSrc ์ฐํด๋ฆญ ํ
new → Directory : src\main\kotlin ์ ํ ํ object ํ์ผ ์์ฑ
๋ค์์ ๋ด์ฉ์ ๊ฐ ํ์ผ์ ์ ์ํฉ๋๋ค.
Configs
์ฑ ๊ธฐ๋ณธ ์ ๋ณด ๊ด๋ฆฌ ํ์ผ
Libraries
์ฑ์์ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ด๋ฆฌ ํ์ผ
Versions
์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฒ์ ๊ด๋ฆฌ ํ์ผ
์์ ํํ์ ๊ฐ๋ค๋ก ์ด๋ฃจ์ด์ง ์ค์ ํ์ผ์ ๋ง๋ค ๊ฑด๋ฐ, kotlin ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ ํ์์ผ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
object Obj {
const val value1 = "value"
const val value2 = 30
}
Configs ์์
// buildSrc/src/main/kotlin/Configs.kt
object Configs {
const val applicationId = "applicationId"
const val compileSdkVersion = 31
const val minSdkVersion = 26
const val targetSdkVersion = 30
const val versionCode = 1
const val versionName = "1.0.0"
}
Versions ์์
// buildSrc/src/main/kotlin/Versions.kt
object Versions {
// classpath
const val classPathVersion = "7.2.0"
const val kotlinVersion = "1.6.21"
const val hiltVersion = "2.40.1"
const val navigationVersion = "2.5.0"
// core
const val coreKtxVersion = "1.7.0"
const val coroutineVersion = "1.6.0"
// .. ์๋ต
// test
const val junit = "4.13.2"
const val espressoVersion = "3.4.0"
const val androidxTestVersion = "1.2.0"
const val mockitoVersion = "2.24.5"
}
Libraries ์์
object Libraries {
object CLASSPATH {
const val classpathGradle = "com.android.tools.build:gradle:${Versions.classPathVersion}"
const val classpathKotlinGradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlinVersion}"
const val classpathHilt = "com.google.dagger:hilt-android-gradle-plugin:${Versions.hiltVersion}"
const val classpathNavigation = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.navigationVersion}"
}
object Core {
const val KOTLIN_STDLIB = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlinVersion}"
const val COROUTINE = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutineVersion}"
}
object UI {
// ์๋ต..
}
object AndroidX {
// ์๋ต..
}
object DI {
// ์๋ต..
}
object ThirdParty {
// ์๋ต..
}
object Test {
// ์๋ต..
}
object AndroidTest {
// ์๋ต..
}
}
2. settings.grade ํ์ผ ํ์ฅ์ kts๋ก ๋ณ๊ฒฝ ํ kotlin ๋ฌธ๋ฒ์ ๋ง๊ฒ ํ์ผ ์์ ํ๊ธฐ
1. setting.gradle → setting.gradle.kts ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
2. kts ๋ฌธ๋ฒ์ ๋ง๊ฒ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
rootProject.name = "Mindgarden"
include(":app")
4. ํ๋ก์ ํธ ์์ค build.gradle ํ์ผ ํ์ฅ์ kts๋ก ๋ณ๊ฒฝ ํ ๋ฌธ๋ฒ์ ๋ง๊ฒ ์์
build.src์ ์ ์ํ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
classpath(Libraries.CLASSPATH.classpathHilt)
build.gradle(Project) ์ฝ๋
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath(Libraries.CLASSPATH.classpathGradle)
classpath(Libraries.CLASSPATH.classpathKotlinGradle)
classpath(Libraries.CLASSPATH.classpathHilt)
classpath(Libraries.CLASSPATH.classpathNavigation)
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
5. ๋ชจ๋ ์์ค build.gradle ํ์ผ kts๋ก ์ด๋ฆ ๋ณ๊ฒฝ ํ ๋ฌธ๋ฒ์ ๋ง๊ฒ ์์
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-kapt")
id("androidx.navigation.safeargs.kotlin")
id("dagger.hilt.android.plugin")
}
android {
compileSdk = Configs.compileSdkVersion
defaultConfig {
applicationId = Configs.applicationId
minSdk = Configs.minSdkVersion
targetSdk = Configs.targetSdkVersion
versionCode = Configs.versionCode
versionName = Configs.versionName
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
testOptions {
unitTests {
isReturnDefaultValues = true
}
}
buildFeatures {
viewBinding = true
dataBinding = true
}
namespace = "com.app.myapp"
}
dependencies {
// core
implementation(Libraries.Core.KOTLIN_STDLIB)
implementation(Libraries.Core.COROUTINE)
// UI
implementation(Libraries.UI.MATERIAL)
implementation(Libraries.UI.CONSTRAINT_LAYOUT)
implementation(Libraries.UI.FRAGMENT_KTX)
// AndroidX
implementation(Libraries.AndroidX.CORE_KTX)
implementation(Libraries.AndroidX.APP_COMPAT)
// di hilt
implementation(Libraries.DI.HILT)
kapt(Libraries.DI.HILT_COMPILER)
// 3rd
// glide
implementation(Libraries.ThirdParty.GLIDE)
kapt(Libraries.ThirdParty.GLIDE_COMPILER)
// test
testImplementation(Libraries.Test.JUNIT)
androidTestImplementation(Libraries.AndroidTest.JUNIT_KOTLIN)
androidTestImplementation(Libraries.AndroidTest.ROOM)
androidTestImplementation(Libraries.AndroidTest.ESPRESSO_CORE)
androidTestImplementation(Libraries.AndroidTest.COROUTINE)
androidTestImplementation(Libraries.AndroidTest.TEST_RUNNER)
androidTestImplementation(Libraries.AndroidTest.TEST_RULES)
androidTestImplementation(Libraries.AndroidTest.MOCKITO)
}
// Allow references to generated code
kapt {
correctErrorTypes = true
}
๐ Meaning
- Groovy์ ์ญํ
- Groovy์ KTS ๋น๊ต, KTS์ ์ฅ์ ๊ณผ ๋จ์
- Groovy์์ KTS๋ก ์ ํํ๋ ๋ฐฉ๋ฒ๊ณผ ์ฅ์
๋น๋ ์๋๊ฐ ์๊ฐ๋ณด๋ค ๋ ๋๋ ค์ง๊ธด ํ์ง๋ง ๐ง
IDE๋ฅผ ํตํด ์๋ ์์ฑ์ด ์ง์๋๊ณ ์ฝ๋๋ฅผ ๋ ๊ฐ๋ ์ฑ ์๊ฒ ๋ง๋ค๊ณ ๊น๋ํ๊ฒ ๊ด๋ฆฌํ ์ ์๋ค๋ ์ ์ด ๋ง์กฑ์ค๋ฌ์ ์ต๋๋ค.
๐ ์ฐธ๊ณ
https://docs.gradle.org/nightly/userguide/migrating_from_groovy_to_kotlin_dsl.html
Migrating build logic from Groovy to Kotlin
Declaring dependencies in existing configurations is similar to the way it’s done in Groovy build scripts, as you can see in this example: build.gradle.kts plugins { `java-library` } dependencies { implementation("com.example:lib:1.1") runtimeOnly("com.e
docs.gradle.org
https://developer.android.com/studio/build/migrate-to-kts?hl=ko
Groovy์์ KTS๋ก ๋น๋ ๊ตฌ์ฑ ์ด์ | Android ๊ฐ๋ฐ์ | Android Developers
Gradle ๊ตฌ์ฑ ํ์ผ์ Groovy์์ KTS๋ก ์ด์ ํฉ๋๋ค.
developer.android.com
Kotlin DSL, BuildSrc, Product Flavors, Flavor Icon and more
I wanted for a long time migrate gradle files to kotlin dsl but i was always procrastinating. I finally put an end to it and also I…
blog.kotlin-academy.com
https://github.com/gradle/gradle/issues/15886
The Kotlin and Groovy DSLs should have similar performance characteristics · Issue #15886 · gradle/gradle
Expected Behavior The Kotlin and Groovy DSLs have as much as possible similar performance characteristics. IOW there's no outlier use case for which the performance characteristics make using o...
github.com