이동식 저장소

[Gradle] Version Catalog로 라이브러리 관리하기 본문

Secondary/Gradle

[Gradle] Version Catalog로 라이브러리 관리하기

해스끼 2022. 11. 19. 17:55

모듈을 여러 개 작성하다 보면 ``build.gradle`` 파일이 복잡해지곤 한다.

:database:di
:database

같은 라이브러리를 여러 번 작성하다 보면 오타가 날 수도 있고, 버전 관리가 힘들어지기도 한다. 당장 위의 ``:database`` 모듈에서도 junit 라이브러리를 하나만 사용함에도 불구하고 bom으로 선언하는 오류가 있다.

 

Gradle의 기능을 사용하면 버전 관리를 쉽게 할 수 있다. 이름하여 Version Catalog!

Version Catalog

카탈로그는 상품 목록 등을 한 곳에 모아놓아 보기 쉽게 정리한 것이다. 단어 그대로 Version Catalog는 앱에서 사용하는 라이브러리를 모아놓은 파일이다. 라이브러리를 사용하고 싶다면 catalog에서 선택하기만 하면 된다. 버전 관리는 catalog에서 알아서 해줄 것이다.

 

Version Catalog을 적용하기 전과 후를 비교해 보자.

// Before
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_extension_version"
// After
implementation androidXLibs.lifecycle.runtime.ktx
implementation androidXLibs.lifecycle.viewmodel.ktx
implementation androidXLibs.lifecycle.reactivestreams.ktx
implementation androidXLibs.lifecycle.extensions

코드가 짧아지기도 했고, 무엇보다 중요한 점은 ``build.gradle``에서 버전 관리를 하지 않아도 된다는 점이다. 

적용 방법

Version Catalog는 ``settings.gradle``에서 정의한다. 대략 아래와 같은 형식으로 정의할 수 있다.

// settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            library('core-ktx', 'androidx.core:core-ktx:1.9.0')
        }
    }
}

첫 번째 매개변수는 ``build.gradle``에서 사용할 이름(alias라고도 한다), 두 번째 매개변수는 실제 라이브러리의 경로이다. 이제 ``build.gradle``에서 이렇게 사용하면 된다.

// build.gradle
dependencies {
    implementation libs.core.ktx
    
    // ...
}

참 쉽죠? Alias의 ``-``를 ``.``으로 바꾸어 사용하면 된다.

 

여러 라이브러리에서 하나의 version 문자열을 참조할 수도 있다. 

// settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            version('work', '2.7.1')
            library('work-runtime-ktx', 'androidx.work', 'work-runtime-ktx').versionRef('work')
            library('work-testing', 'androidx.work', 'work-testing').versionRef('work')
        }
    }
}

``build.gradle``에서 버전 문자열만 참조할 수도 있다.

// settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        composeLibs {
            version('compiler', '1.3.2')
        }
    }
}
// build.gradle
android {
    composeOptions {
        kotlinCompilerExtensionVersion composeLibs.versions.compiler.get()
    }
}

카탈로그를 여러 개로 나눌 수도 있다. 이때 카탈로그의 이름은 ``libs``로 끝나야 한다.

// settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            // ...
        }
        testLibs {
            // ...
        }
        kotlinLibs {
            // ...
        }
    }
}

라이브러리 여러 개를 bundle로 묶을 수도 있다.

// settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        kotlinLibs {
            version('coroutines', '1.6.4')
            library('coroutines-core', 'org.jetbrains.kotlinx', 'kotlinx-coroutines-core').versionRef('coroutines')
            library('coroutines-android', 'org.jetbrains.kotlinx', 'kotlinx-coroutines-android').versionRef('coroutines')
            bundle('coroutines', ['coroutines-core', 'coroutines-android'])
        }
    }
}
// build.gradle (app level)
dependencies {
    implementation kotlinLibs.bundles.coroutines
}

그런데 ``settings.gradle``에 Version Control을 정의하면 치명적인 문제가 발생한다. Android Studio에서 최신 버전이 있음을 알려주지 않는다!

클릭하면 원본 이슈로 이동합니다.

대신 ``gradle/libs.version.toml`` 파일에 선언된 라이브러리는 (Android Studio Flamingo부터) 최신 버전이 있음을 알려주는 모양이다. 어차피 ``settings.gradle``에서는 bom도 제대로 지원하지 않아서 toml로 옮기기로 결정했다.

 

Toml 포맷은 따로 설명할 필요가 없을 정도로 쉽다.

[versions]
groovy = "3.0.5"
checkstyle = "8.37"

[libraries]
my-lib = "com.mycompany:mylib:1.4"
my-other-lib = { module = "com.mycompany:other", version = "1.4" }
my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" }
mylib-full-format = { group = "com.mycompany", name = "alternate", version = { require = "1.4" } }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

[plugins]
short-notation = "some.plugin.id:1.4"
long-notation = { id = "some.plugin.id", version = "1.4" }
reference-notation = { id = "some.plugin.id", version.ref = "common" }

Gradle 7.4 이상을 사용할 경우 자동으로 toml 파일을 인식한다. ``build.gradle``에서는 똑같이 사용하면 된다. 끝!

'Secondary > Gradle' 카테고리의 다른 글

클래스 충돌 에러가 날 때는  (0) 2023.04.26
Kotlin jvmTarget  (0) 2023.03.25
sourceCompatibility vs. targetCompatibility  (0) 2023.03.24
[Android] Gradle 테스트 실행 커맨드  (0) 2022.10.05
[Android] gradle vs. gradlew  (0) 2022.09.23
Comments