욱'S 노트

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

Programming/Gradle

Gradle - 빌드 스크립트 기초

devsun 2015. 5. 4. 09:43

Projects and tasks


Gradel에서 두가지 기본 컨셉이 있다 : projects 그리고 tasks


모든 Gradle 빌드는 하나 혹은 그 이상의 프로젝트들로 구성된다. 프로젝트는 Gradle과 함께 동작하는 관련된 것들을 정의한 것을 의미한다. 예를 들면 프로젝트는 라이브러리 jar 파일 혹은 웹 어플리케이션을 대표할 수 있다. 또 다른 프로젝트에 제공할 JAR들을 패키지한 배포판 ZIP일 수도 있다. 프로젝트는 빌드할 무엇을 대표할 필요는 없다. 그것은 수행되어야 할 어떤 것, 즉 스테이징 이나 프로덕션 환경에 어플리케이션을 배포하는 것 일수도 있다. 약간의 논란에 대해서는 지금 걱정할 필요는 없다. Gradle의 컨벤션 빌드는 프로젝트에 적용할 다양한 구현 정의를 지원한다.


각 프로젝트는 하나 또는 다수의 task로 구성된다. task는 빌드를 수행할 때 하나의 작업 단위를 의미한다. 이것은 클래스 컴파일, JAR 생성, javadoc 생성 또는 리파지토리로 아카이브를 퍼블리쉬하는 것일 수 있다. 


이제 하나의 프로젝트와 한께 몇몇의 단순한 task들의 정의하는 것을 살펴보자. 


Hello world


Gradle 빌드를 실행하기 위해선 gradle 커맨드를 이용한다. gradle 커맨드는 현재 디렉토리에서 build.gradle 파일을 찾는다. build.gradle 파일을 빌드 스크립트라고 부른다. 엄격하게 말하자만 빌드 정의 스크립트지만 그에 대해선 나중에 알아보자. 빌드 스크립트에는 프로젝트와 그에 맞는 타스크들을 정의한다.


아래와 같은 빌드 스크립트를 생성해보자.


task hello {
    doLast {
        println 'Hello world!'
    }
}


빌드 스크립트가 포함된 디렉토리로 이동해서 gradle -q hello 커맨드를 실행해보자. -q 옵션은 Gradle의 로그 메시지를 노출하는 옵션이다.


toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q hello

Hello world!


빌드 스크립트에는 hello라고 불리는 하나의 타스크가 정의 되어 있고, 그에 대한 액션이 추가되어 있다. gradle hello를 실행했을때, Gradle은 hello 타스크를 실행한다. action은 단순하게 실행할 수 있는 grooy code이다. 

만약 Ant의 타켓으로 본다면 맞다. Gradle의 타스크는 Ant의 타겟이랑 동등하다. 그리고 훨씬 강력하다. Ant랑 다른 용어를 사용한 이유는 task가 target보다 훨씬 표현력이 있다고 생각했기 때문이다. 

A shortcut task definition

위의 hello 타스크를 더욱 간단하게 정의하는 방법에 대해서 알아보자. 

task hello << {
    println 'Hello world!'
}

hello 타스크를 하나의 클러져로 정의한 예이다.

Build scripts are code

Gradle의 빌드 스크립트는 Groovy의 모든 지원을 활용할 수 있다.

task upper << {
    String someString = 'mY_nAmE'
    println "Original: " + someString 
    println "Upper case: " + someString.toUpperCase()
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME

task count << {
    4.times { print "$it " }
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q count
0 1 2 3 

Task dependencies

예상했다시피 타스크는 다른 타스크를 참조할 수 있다.

task hello << {
    println 'Hello world!'
}
task intro(dependsOn: hello) << {
    println "I'm Gradle"
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q intro
Hello world!
I'm Gradle

Dynamic tasks

Groovy의 특징을 이용하여 task를 다이나믹하게 생성할 수도 있다.

4.times { counter ->
    task "task$counter" << {
        println "I'm task number $counter"
    }
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q task1
I'm task number 1

Manipulating existing tasks

만약 하나의 타스크가 생성되면 해당 타스크들은 API를 통해 접근할 수 있다. 예를 들어 실행시에 다이나믹하게 타스크에 대한 디펜던시를 추가할 수 있다.

4.times { counter ->
    task "task$counter" << {
        println "I'm task number $counter"
    }
}
task0.dependsOn task2, task3

toddsonui-MacBook-Pro:gradle-test devsun$ gradle task0
:task2
I'm task number 2
:task3
I'm task number 3
:task0
I'm task number 0

BUILD SUCCESSFUL

Total time: 2.106 secs

다음의 예도 살펴 보자.

task hello << {
println 'Hello Earth'
}
hello.doFirst {
println 'Hello Venus'
}
hello.doLast {
println 'Hello Mars'
}
hello << {
println 'Hello Jupiter'
}
toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter

doFirst와 doLast는 여러번 호출될 수 있다. 호출 될때마다, 타스크의 액션의 시작과 끝에 추가될 것이다. << 오퍼레이커는 doLast의 alias이다.

Shortcut notations

task hello << {
    println 'Hello world!'
}
hello.doLast {
    println "Greetings from the $hello.name task."
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q hello
Hello world!
Greetings from the hello task.

Extra task properties

타스크에 필요한 프로퍼티들을 추가할 수 있다. myProperty라는 프로퍼티를 추가하기 위해 ext.myProperty에 초기 값을 세팅한다. 이렇게 지정한 후 프로포티는 기정의된 타스크 프로퍼티로 읽어질 수 있다.

task myTask {
    ext.myProperty = "myValue"
}

task printTaskProperties << {
    println myTask.myProperty
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q printTaskProperties
myValue

Using Ant Tasks

Ant 타스크들은 Gradle의 first-class citizens이다. Gradle은 Ant task와의 완벽한 통합을 지원한다. Groovy에는 fantasticAntBuilder가 탑재되어 있다. Gradle에서 Ant task를 이용하는 것은 build.xml에서 Ant 타스크를 이용하는 것보다 더 강력하고 편리하다. 

task loadfile << {
def files = file('../antLoadfileResources').listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
}

Using methods

Gradle 빌드 로직은 method로 추출할 수 있다.
task checksum << {
fileList('../antLoadfileResources').each {File file ->
ant.checksum(file: file, property: "cs_$file.name")
println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
}
}

task loadfile << {
fileList('../antLoadfileResources').each {File file ->
ant.loadfile(srcFile: file, property: file.name)
println "I'm fond of $file.name"
}
}

File[] fileList(String dir) {
file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
}

Default tasks

프로젝트에서 하나 혹은 그 이상의 디폴트 타스크를 지정할 수 있다. 

defaultTasks 'clean', 'run'

task clean << {
    println 'Default Cleaning!'
}

task run << {
    println 'Default Running!'
}

task other << {
    println "I'm not a default task!"
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q
Default Cleaning!
Default Running!

이는 gradle clean run과 동일하다. 

Configure by DAG

Gradle은 configuration phase와 execution phase를 가진다. configuration phase 후에 Gradle은 실행할 수 있는 모든 타스크들을 알게 된다. Gradle은 후킹할 수 있는 모든 정보를 사용자에게 알려준다. 이러한 유스케이스는 릴리이즈 타스크에서 다양한 체크포인트를 제공하는 예를 들 수 있다. 이러한 과정에서 다양한 변수들을 세팅할 수 있다.

task distribution << {
    println "We build the zip with version=$version"
}

task release(dependsOn: 'distribution') << {
    println 'We release now'
}

gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(release)) {
        version = '1.0'
    } else {
        version = '1.0-SNAPSHOT'
    }
}

toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
toddsonui-MacBook-Pro:gradle-test devsun$ gradle -q release
We build the zip with version=1.0
We release now


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

Gradle - Dependency Management Basics  (0) 2015.05.04
Gradle - Java Quick Start  (0) 2015.05.04
Gradle - 설치하기  (0) 2015.05.04
Gradle - 소개  (0) 2015.04.02
Comments