[Android] buildSrc를 통한 Dependency 관리
Android

[Android] buildSrc를 통한 Dependency 관리

728x90

 

 

 클린 아키텍처를 공부하며 Github에서 여러 가지 오픈소스를 분석하던 중, Fernando Cejas님의 Android-CleanArchitecture-Kotlin 프로젝트를 보게 되었습니다. 그중 dependency를 관리하는 방법이 기존에 알고 있던 방법과 달라서 buildSrc에 대해 공부하게 되었습니다. 멀티 모듈로 구성된 프로젝트에서 buildSrc를 통해 dependency를 관리하면 좋을 것 같습니다.

 

 

Gradle 공식 문서에 아래와 같은 설명이 나와 있습니다.

Use buildSrc to abstract imperative logic ….
The directory buildSrc is treated as an included build. Upon discovery of the directory, Gradle automatically compiles and tests this code and puts it in the classpath of your build script. For multi-project builds there can be only one buildSrc directory, which has to sit in the root project directory. buildSrc should be preferred over script plugins as it is easier to maintain, refactor and test the code.

 Gradle이 수행되면 buildSrc 디렉토리가 존재하는지 체크합니다. 이 경우에 Gradle은 자동적으로 코드를 컴파일하고 테스트한 뒤 빌드 스크립트의 classpath에 넣습니다. 이 방법은 유지 보수, 리팩토링 및 코드 테스트가 더 쉬워진다고 합니다.

 

 


 

 

시작하기

buildSrc를 통해 dependency를 관리하는 방법은 다음과 같습니다.

 

1. 루트 폴더에 buildSrc 폴더를 생성합니다.

2. buildSrc 폴더 안에 build.gradle.kts 파일을 생성한 뒤, 아래의 코드와 같이 kotlin-dsl를 enable를 합니다. 그리고 gradle sync를 하여 이 plugin을 활성화합니다.

plugins {
  `kotlin-dsl`
}

repositories {
  jcenter()
}

3. src > main > java 폴더를 생성합니다.

4. java 폴더안에 Kotlin 파일을 생성하고, 원하는 이름을 지정합니다.

5. 생성한 Kotlin 파일에 dependency를 지정합니다.

object Versions {
    const val KOTLIN_VERSION = "1.5.0"
    const val KOTLINX_COROUTINES = "1.5.0"
    const val BUILD_GRADLE = "4.2.1"
    const val COMPILE_SDK_VERSION = 30
    const val BUILD_TOOLS_VERSION = "30.0.3"
    const val MIN_SDK_VERSION = 23
    const val TARGET_SDK_VERSION = 30

    const val CORE_KTX = "1.5.0"
    const val APP_COMPAT = "1.3.0"
    const val ACTIVITY_KTX = "1.2.3"
    const val FRAGMENT_KTX = "1.3.4"
    const val LIFECYCLE_KTX = "2.3.1"
    const val ROOM = "2.3.0"

    const val HILT = "2.35.1"
    const val MATERIAL = "1.3.0"

    const val RETROFIT = "2.7.1"
    const val OKHTTP = "4.3.1"

    const val JUNIT = "4.13.2"
    const val ANDROID_JUNIT = "1.1.2"
    const val ESPRESSO_CORE = "3.3.0"
}

object Kotlin {
    const val KOTLIN_STDLIB      = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.KOTLIN_VERSION}"
    const val COROUTINES_CORE    = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.KOTLINX_COROUTINES}"
    const val COROUTINES_ANDROID = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.KOTLINX_COROUTINES}"
}

object AndroidX {
    const val CORE_KTX                = "androidx.core:core-ktx:${Versions.CORE_KTX}"
    const val APP_COMPAT              = "androidx.appcompat:appcompat:${Versions.APP_COMPAT}"

    const val ACTIVITY_KTX            = "androidx.activity:activity-ktx:${Versions.ACTIVITY_KTX}"
    const val FRAGMENT_KTX            = "androidx.fragment:fragment-ktx:${Versions.FRAGMENT_KTX}"

    const val LIFECYCLE_VIEWMODEL_KTX = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.LIFECYCLE_KTX}"
    const val LIFECYCLE_LIVEDATA_KTX  = "androidx.lifecycle:lifecycle-livedata-ktx:${Versions.LIFECYCLE_KTX}"

    const val ROOM_RUNTIME            = "androidx.room:room-runtime:${Versions.ROOM}"
    const val ROOM_KTX                = "androidx.room:room-ktx:${Versions.ROOM}"
    const val ROOM_COMPILER           = "androidx.room:room-compiler:${Versions.ROOM}"
}

object Google {
    const val HILT_ANDROID          = "com.google.dagger:hilt-android:${Versions.HILT}"
    const val HILT_ANDROID_COMPILER = "com.google.dagger:hilt-android-compiler:${Versions.HILT}"

    const val MATERIAL = "com.google.android.material:material:${Versions.MATERIAL}"
}

object Libraries {
    const val RETROFIT                   = "com.squareup.retrofit2:retrofit:${Versions.RETROFIT}"
    const val RETROFIT_CONVERTER_GSON    = "com.squareup.retrofit2:converter-gson:${Versions.RETROFIT}"
    const val OKHTTP                     = "com.squareup.okhttp3:okhttp:${Versions.OKHTTP}"
    const val OKHTTP_LOGGING_INTERCEPTOR = "com.squareup.okhttp3:logging-interceptor:${Versions.OKHTTP}"
}

object UnitTest {
    const val JUNIT         = "junit:junit:${Versions.JUNIT}"
}

object AndroidTest {
    const val ANDROID_JUNIT = "androidx.test.ext:junit:${Versions.ANDROID_JUNIT}"
    const val ESPRESSO_CORE = "androidx.test.espresso:espresso-core:${Versions.ESPRESSO_CORE}"
}

6. 이후 아래와 같이 build.gradle 파일에서 사용 가능합니다.

dependencies {
    implementation Kotlin.KOTLIN_STDLIB

    implementation AndroidX.CORE_KTX
    implementation AndroidX.APP_COMPAT

    implementation Google.MATERIAL

    testImplementation UnitTest.JUNIT

    androidTestImplementation AndroidTest.ANDROID_JUNIT
    androidTestImplementation AndroidTest.ESPRESSO_CORE
}

 

 

 

 

 buildSrc를 사용하면 좋은 점이 Kotlin을 사용해 관리해주기 때문에 Auto Complete이 지원됩니다.

 

 

 

예제 소스

https://github.com/tkdgusl94/blog-source/tree/master/buildSrc

 

tkdgusl94/blog-source

https://leveloper.tistory.com/ 에서 제공하는 예제 source. Contribute to tkdgusl94/blog-source development by creating an account on GitHub.

github.com

 

참고

https://proandroiddev.com/gradle-dependency-management-with-kotlin-94eed4df9a28

 

Gradle dependency management with Kotlin (buildSrc)

Hello everyone! 👋 Gradle Dependency Management (GDM) is the practice of keeping your dependencies centralized and under control. Today I…

proandroiddev.com

 

728x90