천복만복 프로그래밍/Gradle

Understanding Gradle #03 – Plugins

U&MeBlue 2023. 2. 5. 16:21

이번 영상에서는 gradle 의 plugin 에 대해서 다룬다. gradle 은 강력하고 다양한 core 시스템으로 구성되는데, 그 중에 가장 중요한 것 중 하나는 plugin 이다.

gradle 에서 plugin 은 대충 3가지 종류로 구분할 수 있다.

  1. Core Plugin : Gradle 프로그램에 내장되어 있고, 간단한 id 를 명시하는 것만으로 적용할 수 있다. ex) id("java-libraray")
  2. Commnunity Plugin : 보통 Gradle Plugin Portal 에 저장되어 있다. Commnunity Plugin 은 qualified id 와 version 명시를 통해 적용할 수 있다.
  3. Convention Plugin : 로컬에서 직접 작성해서 사용하는 플러그인.
plugins {
    id("java-library") // Core Plugin. Gradle 에 내장됨.
    id("org.jetbrains.kotlin.jvm") version "1.5.21" // Community Plugin. gradle version 과 독립적인 버전 정보 명시
    id("my-java-library")
}

business-logic 모듈의 빌드 파일을 다음과 같이 작성할 수 있다.

plugins {
    id("java-library") // Core Plugin
    id("org.jetbrains.kotlin.jvm") version "1.5.21" // Community Plugin
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

tasks.test {
    useJUnitPlatform()
}

kotlin {

}

dependencies {
    implementation(project(":data-model"))
    implementation("org.apache.commons:commons-lang3:3.9")
}

여기서 볼 수 있듯이 빌드 파일이 점차 커지는 것을 확인할 수 있다. 더 많은 플러그인을 적용할수록, extension을 통한 더 많은 플러그인 configuration 이 작성될 필요가 있고, 파일이 점점 더 거대해진다. 또한 많은 서브 프로젝트들의 빌드 파일들에서 반복적으로 작성되는 부분이 존재하게 된다. 만약 모든 서브프로젝트들이 동일한 자바 버전을 이용해서 빌드될 필요가 있고, 모두 코틀린 지원이 필요하다면 모든 서브 프로젝트 빌드 파일에서 위 코드를 중복해서 작성해야 한다.

 

이런 중복을 피하기 위해서 직접 정의한 convention plugins 을 적용할 수 있다. 이 플러그인 안에는 임의의 빌드 설정을 캡슐화해서 관리할 수 있고, 또한 커스텀 빌드 로직도 작성할 수 있다.

 

convention plugin 을 정의하기 위해서는 별도의 gradle build 가 필요하다. 이를 위해서 별도의 프로젝트를 생성해서 완전히 gradle 빌드가 별도로 이루어지도록 한다. 여기서는 예제 프로젝트와 동일한 레벨의 디렉토리 위치에 my-build-logic 이라는 프로젝트를 추가했다. 그리고 예제 프로젝트에서 gradle 이 플러그인을 찾을때 my-build-logic 도 확인할 수 있도록 settings.gradle 파일의 includeBuild 를 추가한다.

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
    includeBuild("../my-build-logic") // 이 부분
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "GradleStudy"
include ':app'
include ':business-logic'

my-build-logic 프로젝트에서는 해당 프로젝트 빌드를 위한 settings.gradle.kts 파일을 갖는다. 이곳에서는 커뮤니티 플러그인에 접근하기 위해서 gradle plugin portal 을 repositories 로 명시한다. 또한 사용자 정의 convention plugin 을 정의하기 위해 사용할 서브 프로젝트도 명시한다.

dependencyResolutionManagement {
    repositories {
        gradlePluginPortal()
    }
}

include("java-plugins")

이 후 java-plugins 서브 프로젝트를 만들고, 여기서도 빌드 파일을 추가한다. 그리고 gradle core plugin 인 kotlin-dsl 플러그인을 적용한다. 이는 kotlin dsl 통해 플러그인을 정의하려고 할때 사용된다. 또한 코틀린 플러그인을 사용하고 싶기 때문에 빌드 파일에 의존성 설정도 해주어야 한다. convetion plugin 을 정의할때 다른 의존성 플러그인 라이브러리를 찾기 위해서 일반적인 의존성 명시 방법(dependencies)이 사용된다.

plugins {
    `kotlin-dsl` // convention plugin 을 적용하기 위한 gradle core plugin
    // id("groovy-gradle-plugin") <- for Groovy DSL
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
}

이제 kotlin-dsl 플러그인을 적용했으니, Gradle scripts 를 'src/main/kotlin' 폴더에 작성할 수 있다. 이 폴더에 my-java-library.gradle.kts 파일을 추가한다. 이제 이곳에서 기존에 빌드파일에 작성했던 내용들을 이 플러그인에 작성할 수 있다. 이 파일의 이름이 플러그인의 이름이 될것이다.

 

my-java-library.gradle.kts 파일

plugins {
  id("java-library")
  id("org.jetbrains.kotlin.jvm")
}

java {
  toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}

tasks.test {
  useJUnitPlatform()
}

kotlin {
  // ...
}

이제 business-logic 프로젝트 빌드파일에 자바 라이브러리 선언을 위해서 긴 보일러 플레이트를 작성하지 않고도 'my-java-library' 라는 직접 만든 플러그인을 적용함으로써 간단하가 자바 라이브러리 선언이 가능해졌다.

business-logic 프로젝트의 build.gradle.kts 파일

plugins {
    id("my-java-library") // 이 커스텀 플러그인을 통해 이 모듈을 자바 라이브러리로 만들기 위한 보일러 플레이트 한번에 추가
}

dependencies {
    implementation("org.apache.commons:commons-lang3:3.9")
}
 
 
 
728x90