모종닷컴

Gradle - 빌드 스크립트 작성 기초 본문

Programming/Gradle

Gradle - 빌드 스크립트 작성 기초

모종 2022. 9. 17. 17:03
반응형

그레이들 빌드 스크립트 작성의 기본적인 부분들을 다룹니다. 글에서 간단한 예시를 보면서 기초 개념들에 대해 알려줍니다.

Projects, plugins and tasks

모든 그레이들 빌드는 하나 이상의 projects로 구성됩니다. 그레이들로 무엇을 하려는지에 따라 project가 정의가 달라집니다. 예를 들어 project는 JAR 라이브러리 혹은 웹 애플리케이션을 말하는 걸수도 있습니다. 혹은 다른 프로젝트에서 생산된 JAR로부터 어셈블된 ZIP을 말하는 걸수도 있습니다. 프로젝트가 반드시 무엇인가를 만들어야 한다는 것이 아닙니다. 스테이징 또는 프로덕션 환경에 애플리케이션을 배포하는 것과 같이 수행해야 할 작업을 나타낼 수도 있습니다(이 이야기들이 좀 애매해 보이는데 걱정하지 말라고 다독이네요ㅋㅋ ). 그레이들의 build-by-convention이 프로젝트가 무엇인지에 대해 좀 더 구체적인 정의를 더할 수 있도록 도와줄겁니다.

그레이들이 프로젝트에서 수행하는 작업(work)은 하나 이상의 태스크(task)에 의해 정의됩니다. 태스크란 빌드가 수행하는 원자적인 작업을 말합니다. 태스크는 몇몇 클래스를 컴파일하거나, JAR를 만들거나, Javadoc을 생성하거나, 레파지토리에 일부 아카이브를 퍼블리싱할 수 있습니다. 

Hello world

gradle 커맨드를 사용하여 그레이들 빌드를 실행해 보세요. gradle 커맨드는 현재 디렉토리의 build.gradle로 불리우는 파일을 찾습니다. 그리고 우리는 이 build.gradle 파일을 빌드 스크립트라고 부르지만, 엄밀히 말하자면 정확히는 빌드 구성 스크립트입니다.  빌드 스크립트는 프로젝트와 태스크를 정의합니다.

빌드 스크립트를 아래와 같이 구성하여 실행해보죠. 커맨드는 gradle hello 입니다. (-q를 붙이면 output만 보도록 할 수 있습니다)

tasks.register('hello') {
    doLast {
        println 'Hello world!'
    }
}

위의 빌드 스크립트를 해석해보자면 일단 빌드 스크립트에는 hello 라고 불리는 하나의 태스크를 정의하였습니다. 그리고 태스크 안에 액션(중괄호 내부 코드)을 추가하였습니다.  그리고 gradle hello 명령어를 통해 hello 태스크를 실행하였습니다. 

빌드 스크립트는 코드입니다.

그레이들의 빌드 스크립트에서는 그루비와 코틀린을 제공합니다. 예시를 먼저 보겠습니다.

tasks.register('upper') {
    doLast {
        String someString = 'mY_nAmE'
        println "Original: $someString"
        println "Upper case: ${someString.toUpperCase()}"
    }
}

tasks.register('count') {
    doLast {
        4.times { print "$it " }
    }
}

커맨드는 gradle upper count  입니다.

태스크 의존성

태스크가 다른 태스크를 의존하도록 선언할수도 있습니다.

tasks.register('hello') {
    doLast {
        println 'Hello world!'
    }
}
tasks.register('intro') {
    dependsOn tasks.hello
    doLast {
        println "I'm Gradle"
    }
}

개인적으로 궁금해서 테스트해 본 것인데 depensOn을 doLast {} 블럭 뒤로 옮겨도 실행 순서는 hello 태스크가 먼저 실행되는 모습이네요. 

유연한 태스크 등록

그루비나 코틀린을 이용하면 태스크를 정의하는 것 외에도 사용될 수 있습니다. 예를 들어 루프에 동일한 유형의 여러 태스크를 등록하는 데 사용할 수 있습니다.

4.times { counter ->
    tasks.register("task$counter") {
        doLast {
            println "I'm task number $counter"
        }
    }
}

기존 태스크 조작

태스크가 등록되면 API를 통해 엑세스할 수 있습니다. 예로 이런 조작을 통해 런타임 시점에 태스크를 동적으로 다룰 수 있습니다.

tasks.named('task0') { dependsOn('task2', 'task3') }

아래와 같은 방식으로도 조작이 가능합니다.

tasks.register('hello') {
    doLast {
        println 'Hello Earth'
    }
}
tasks.named('hello') {
    doFirst {
        println 'Hello Venus'
    }
}
tasks.named('hello') {
    doLast {
        println 'Hello Mars'
    }
}
tasks.named('hello') {
    doLast {
        println 'Hello Jupiter'
    }
}

doFirst 와 doLast의 호출은 여러번 실행될 수 있습니다. 태스크의 액션 리스트의 처음과 시작부분에 액션이 추가됩니다. 태스크가 실행할 때 액션 리스트의 액션은 순서대로 실행됩니다. 

Ant 태스크 사용가능

Ant의 태스크는 그레이들에서 일급 객체입니다. 그레이들은 그루비에 의존하여 Ant 작업에 대한 통합을 제공합니다. Ant는 제 관심사가 아니므로 그냥 가능하다 정도로 알고 넘깁니다. 이 부분이 궁금한 분들은 링크에서 확인가능합니다.

기본 태스크

그레이들은 기본 태스크를 지정해줄 수 있습니다. 그래서 만약 그레이들 명령어에 태스크를 지정해주지 않더라도 실행이 가능합니다. 

defaultTasks 'clean', 'run'

tasks.register('clean') {
    doLast {
        println 'Default Cleaning!'
    }
}

tasks.register('run') {
    doLast {
        println 'Default Running!'
    }
}

tasks.register('other') {
    doLast {
        println "I'm not a default task!"
    }
}

멀티 프로젝트에서 서브 프로젝트는 모두 자신의 기본 태스크를 정의할 수 있습니다. 만약 서브 프로젝트의 기본 태스크가 정의되어 있지 않고, 부모 프로젝트의 기본 태스크가 정의되어 있다면 부모 프로젝트의 기본 태스크가 동작합니다.

빌드 스크립트를 위한 외부화된 의존성

만약 빌드 스크립트에서 외부 라이브러리가 필요하다면 빌드 스크립트의 classpath에 그들을 추가해줄 수 있습니다. buildscript() 메서드의 block 안에 빌드 스크립트 클래스패스를 지정하여 이를 사용할 수 있습니다. 

buildscript 메서드 블럭은  ScriptHandler 인스턴스를 구성합니다. 클래스패스 구성에 종속성을 추가하여 빌드 스크립트 클래스패스를 선언합니다. 예를 들어 Java 컴파일 클래스패스를 선언하는 방법과 동일합니다. 프로젝트 종속성을 제외한 모든 종속성 유형을 사용할 수 있습니다. 

빌드 스크립트 클래스패스를 선언하면 클래스패스의 다른 클래스와 마찬가지로 빌드 스크립트의 클래스를 사용할 수 있습니다. 아래의 예에서는 클래스패스에 commons-codec 라이브러리를 추가하였고, 빌드 스크립트 내에서 해당 라이브러리를 사용합니다.

import org.apache.commons.codec.binary.Base64

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
    }
}

tasks.register('encode') {
    doLast {
        def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
        println new String(encodedString)
    }
}

멀티 프로젝트 빌드의 경우 프로젝트의 buildscript() 메서드로 선언된 종속성을 모든 하위 프로젝트의 빌드 스크립트에 사용가능합니다.

빌드 스크립트 종속성은 그레이들 플러그인일 수 있습니다. 그레이들 플러그인에 대한 자세한 내용은 그레이들 플러그인을 참조해야합니다.

 

원문

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:using_ant_tasks_tutorial

 

Build Script Basics

You run a Gradle build using the gradle command. The gradle command looks for a file called build.gradle in the current directory. We call this build.gradle file a build script, although strictly speaking it is a build configuration script, as we will see

docs.gradle.org

 

반응형