모종닷컴

Gradle Custom Task, Plugin with buildSrc 본문

Programming/Gradle

Gradle Custom Task, Plugin with buildSrc

모종 2023. 3. 11. 17:07
반응형

gradle best practice 내용 중에 buildSrc 관련한 내용이 있어서 한번 시도해 봤습니다.

buildSrc ?

  • Gradle 프로젝트에서 사용하는 특수한 디렉터리
  • Gradle 빌드 스크립트에서 사용할 수 있는 커스텀 플러그인, 태스크, 의존성 등을 정의할 수 있음
  • 빌드 스크립트를 더 간결하고 모듈화 된 형태를 유지할 수 있고, 중복 코드를 줄이고 유지보수성을 높일 수 있음.

 

Custom Task 만들어보기

백문불여일견이라고 바로 시작해 보겠습니다. 먼저 gradle 프로젝트 하나를 만들고 시작하겠습니다. spring boot 프로젝트 하나를 만들었으며 kotlin 언어로 세팅하였습니다. spring boot 버전은 2.7.9 & kotlin 버전은 1.6.21입니다.

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.7.9"
    id("io.spring.dependency-management") version "1.0.15.RELEASE"
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.spring") version "1.6.21"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

buildSrc 디렉터리 생성

첫 프로젝트의 구조는 아래와 같습니다. (혹시라도 tree를 사용하고 싶으신 분은 mac 기준 brew install tree로 설치하시고 디렉터리 위에서 tree 커맨드를 치시면 됩니다)

프로젝트의 루트에서 아래 사진과 같이 경로로 디렉터리를 생성해 주세요. 

다음으로 "./gradlew --rerun-tasks" 명령어를 통해 gradle을 다시 reload 시켜줍니다. 저는 그레이들 버전이 7.6.1인데 혹시나 이보다 낮은 그레이들 버전을 사용하시는 분이라면 "./gradlew --reload" 명령어가 위와 동일할 수 있습니다.

빌드 스크립트 추가

buildSrc에도 빌드 스크립트 추가가 필요합니다. buildSrc폴더에서 build.gradle.kts를 추가해 주고 아래와 같이 구성합니다. 저는 kotlin으로 작성할 예정이라 kotlin 플러그인을 추가해 주었습니다.

plugins {
    kotlin("jvm") version "1.6.21"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

 

이렇게 스크립트 파일을 하나 만들어주었으면 다시 리로드 시켜줍니다.

Custom Task 만들어보기

패키지를 하나 만들어주세요. 저는 "com.example.monny.task" 패키지 구조로 만들었습니다.

이제 커스텀 태스크를 하나 정의해 보겠습니다. 간단하게 태스크 실행 시 입력받은 username에게 인사를 하는 태스크를 만들어보았습니다.

DefaultTask, Input, TaskAction 등은 org.gradle.api 밑에 있는 것을 import 시켜주면 됩니다.

import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction

abstract class Hello: DefaultTask() {
    @get:Input
    abstract val username: Property<String>

    @TaskAction
    fun sayHello() {
        println("hello ${username.get()}")
    }
}

Custom Task 등록하기

이제 루트 프로젝트 밑에 있는 빌드스크립트 파일로 돌아가보겠습니다. (*buildSrc/ 밑에 있는 스크립트 파일이 아닙니다)

스크립트 파일 가장 밑에 아래의 코드를 넣어주세요.

tasks.register("hello", com.example.monny.task.Hello::class.java) {
    username.set("모종닷컴")
}

이제 그레이들 프로젝트를 리로드 시키고 "./gradlew hello" 명령어를 이용해 태스크를 실행시켜 봅니다. 

Csutom Plugin 만들어보기

커스텀 태스크를 만들어봤는데 이번에는 커스텀 플러그인을 만들어보도록 하겠습니다.

Precompiled Script

https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins를 참조하였습니다.

Gradle의 Precompiled script plugins는 빌드 스크립트를 빌드하기 전에 컴파일된 스크립트 플러그인(JAR)을 미리 로딩하고 사용할 수 있도록 해줍니다. 이를 통해 빌드 스크립트의 실행 속도를 높일 수 있습니다.

buildSrc/build.gradle.kts 수정

precompiled script를 가능하게 하기 위해서는 아래와 같이 설정할 필요가 있다고 합니다.

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

스크립트 플러그인 생성

커스텀 태스크를 하면서 만들었던 패키지 밑에 plugin이라는 패키지를 만들고 아래와 같이 빌드스크립트 파일을 만들었습니다.

common.gradle.kts

package com.example.monny.plugin

import com.example.monny.task.Hello

tasks.register("hello", Hello::class.java) {
    username.set("모종닷컴 플러그인")
}

빌드스크립트 수정

루트 프로젝트의 빌드스크립트를 수정해 보겠습니다.

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.7.9"
    id("io.spring.dependency-management") version "1.0.15.RELEASE"
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.spring") version "1.6.21"
    id("com.example.monny.plugin.common")
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

이전과 달라진 점은 Hello 태스크를 등록하던 부분이 사라졌고 plugin 선언에 방금 저희가 만들었던 스크립트를 명시해 주었다는 점입니다.

그레이들 프로젝트를 리로드 시키고 다시 hello 태스크를 실행해 보면 아래와 같이 제대로 동작하고 있음을 알 수 있습니다.

 

반응형