Gradle은 Maven을 대체하는 빌드 도구입니다.
Grooby 기반의 DSL(Domain Specific Language)를 사용합니다.
스프링 부트, 안드로이드 스튜디오에서는 Gradle을 사용되고 있습니다.
[1] Ant
Ant의 가장 큰 장점은 개발자가 자유롭게 빌드 단위(target)을 지정하고 빌드 단위간의 의존관계를 자유롭게 설정할 수 있다는 것입니다. 하지만 자유도가 높다는 것은 잘 활용할 경우 좋은 도구가 될 수 있지만, 잘 활용하지 못하면 그렇지 않을 수도 있습니다.
[2] Maven
Maven의 가장 큰 장점은 Convention Over Configuration 전략에 따라 프로젝트 빌드 과정에 대한 많은 부분이 이미 관례로 정해져 있다는 것입니다. 따라서 Maven 기반 프로젝트를 경험한 개발자는 Maven을 기반으로 하고 있는 새로운 프로젝트에서도 쉽게 적용 할 수 있다는 것입니다. 하지만 관례가 항상 좋은 것은 아니며, 특수한 상황이 발생하는 경우에는 맞지 않는 경우도 종종 발생합니다.
[3] Gradle
Gradle은 진화된 빌드툴로 빌드,테스트, 배포, 개발등을 자동화 할수있습니다. 또한 Ant의 유연성과 효과적인 빌드 툴인 Maven의 편리성을 조합하여 많은 오픈소스 프로젝트의 빌드 시스템으로 채택되고 있습니다. 그리고 Ant와 Maven빌드 툴 모두 가지고 있었던 가장 큰 단점인 XML에 대한 이슈도 Groovy언어를 사용해 해결하고 있습니다.
그래들 스크립트는 크게 프로젝트(project) 와 작업(task)으로 구분할 수 있고, 모든 그래들 빌드는 하나 이상의 project 로 이루어집니다.
프로젝트가 나타내는 것은 그래들로 수행하는 작업에 따라 다릅니다.
- 프로젝트는 JAR 라이브러리 또는 웹 애플리케이션으로 나타낼 수 있습니다.
- 프로젝트는 여러개의 프로젝트에서 생성된 JAR 파일을 ZIP 파일로 묶는 용도로 사용할 수도 있습니다.
- 어떤 프로젝트는 빌드가 필요 없을 수도 있습니다. 단순히 스테이징 또는 프로덕션 환경에 배포하는 작업만 할 수도 있습니다.
각 프로젝트는 하나 이상의 작업으로 구성됩니다.이 때, 작업은 빌드가 수행하는 클래스 컴파일, JAR 작성, Javadoc 생성 등이 있습니다.
# Ex 1
doLast 블록 안에 있는 println 함수를 이용하여 Hello world! 가 실행됩니다.
<< Groovy >>
task hello {
doLast {
println 'Hello world!'
}
}
<< Command >>
> gradle -q hello
Hello world!
# Ex 2
String 으로 변수를 저장하여 사용할 수도 있고, toUpperCase 를 이용하면 소문자를 대문자로 변환할 수도 있습니다.
<< Groovy >>
task upper {
doLast {
String someString = 'mY_nAmE'
println "Original: $someString"
println "Upper case: ${someString.toUpperCase()}"
}
}
<< Command >>
> gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME
# Ex 3
?.times 를 활용하면 물음표의 숫자만큼 반복해서 실행할 수 있습니다.
<< Groovy >>
task count {
doLast {
4.times { print "$it " }
}
}
<< Command >>
> gradle -q count
0 1 2 3
# Ex 1
task 안에 다른 task 를 호출하여 실행할 수 있습니다.
<< Groovy >>
task hello {
doLast {
println 'Hello world!'
}
}
task intro {
dependsOn hello
doLast {
println "I'm Gradle"
}
}
<< Command >>
> gradle -q intro
Hello world!
I'm Gradle
# Ex 2
이후에 선언된 task도 실행할 수 있다.
<< Groovy >>
task taskX {
dependsOn 'taskY'
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
<< Command >>
> gradle -q taskX
taskY
taskX
# Ex 1
?.times 를 통해 반복적으로 task 를 생성합니다.
1 ~ ? 까지의 태스크를 생성하는 스크립트입니다.
<< Groovy >>
4.times { counter ->
task "task$counter" {
doLast {
println "I'm task number $counter"
}
}
}
<< Command >>
> gradle -q task1
I'm task number 1
# Ex 1
0 ~ 3 번의 작업을 생성한 후, dependsOn 을 통해서 0번 작업에 2, 3 번 작업을 포함시킵니다. 이렇게 생성 이후에도 특정 작업 안에 또다른 작업을 포함시킬 수 있습니다.
<< Groovy >>
4.times { counter ->
task "task$counter" {
doLast {
println "I'm task number $counter"
}
}
}
task0.dependsOn task2, task3
<< Command >>
> gradle -q task0
I'm task number 2
I'm task number 3
I'm task number 0
# Ex 2
작업을 생성한 후 [작업명].[추가할 작업명] 의 형식으로 작업을 정의하면, 생성된 작업에 또다른 작업을 추가할 수 있습니다. 이러한 표현방식을 DSL 표기법이라고 합니다.
<< Groovy >>
task hello {
doLast {
println 'Hello Earth'
}
}
hello.doFirst {
println 'Hello Venus'
}
hello.configure {
doLast {
println 'Hello Mars'
}
}
hello.configure {
doLast {
println 'Hello Jupiter'
}
}
<< Command >>
> gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
# Ex 1
위에서 사용한 방식과 같이, 하나의 작업을 생성한 다음 [작업명].[추가할 작업명] 의 형식으로 작업을 정의하면, 생성된 작업에 또다른 작업을 추가할 수 있습니다.
<< Groovy >>
task hello {
doLast {
println 'Hello world!'
}
}
hello.doLast {
println "Greetings from the $hello.name task."
}
<< Command >>
> gradle -q hello
Hello world!
Greetings from the hello task.
# Ex 2
하나의 작업에서 ext.[변수명] 으로 선언하면, 다른 작업에서 이 변수에 접근할 수 있습니다.
<< Groovy >>
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties {
doLast {
println myTask.myProperty
}
}
<< Command >>
> gradle -q printTaskProperties
myValue
# Ex 1
폴더 안에있는 파일들을 files 에 담아서 데이터를 가져온 후, 파일 이름과 내용을 출력하는 작업입니다.
<< Groovy >>
task loadfile {
doLast {
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]}"
}
}
}
}
<< Command >>
> gradle -q loadfile
*** agile.manifesto.txt ***
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
*** gradle.manifesto.txt ***
Make the impossible possible, make the possible easy and make the easy elegant.
(inspired by Moshe Feldenkrais)
# Ex 1
java 의 함수 생성방식과 많이 비슷하게 되어있습니다. 맨 아래에 fileList 라는 함수를 만들고, 작업을 생성할 때에 불러와서 사용할 수 있습니다.
<< Groovy >>
task checksum {
doLast {
fileList('./antLoadfileResources').each { File file ->
ant.checksum(file: file, property: "cs_$file.name")
println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
}
}
}
task loadfile {
doLast {
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()
}
<< Command >>
> gradle -q loadfile
I'm fond of agile.manifesto.txt
I'm fond of gradle.manifesto.txt
# Ex 1
생성한 작업을 defaultTasks 에 등록을 해 두면, gradle -q 로 스크립트를 지정하지 않을 경우에 등록해 둔 작업이 순서대로 실행됩니다.
<< Groovy >>
defaultTasks 'clean', 'run'
task clean {
doLast {
println 'Default Cleaning!'
}
}
task run {
doLast {
println 'Default Running!'
}
}
task other {
doLast {
println "I'm not a default task!"
}
}
<< Command >>
> gradle -q
Default Cleaning!
Default Running!
# Ex 1
gradle.taskGraph.whenReady 라는 함수를 통해 작업이 release 인지 distribution 인지에 따라서 변수값을 변경할 수 있습니다. 개발/운용 환경 빌드에도 적합할 것 같습니다.
<< Groovy >>
task distribution {
doLast {
println "We build the zip with version=$version"
}
}
task release {
dependsOn 'distribution'
doLast {
println 'We release now'
}
}
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(":release")) {
version = '1.0'
} else {
version = '1.0-SNAPSHOT'
}
}
<< Command >>
> gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
> gradle -q release
We build the zip with version=1.0
We release now
# Ex 1
repositories 에는 mavenCentral() 을 입력하고, dependencies 안에는 classpath 를 통해서 라이브러리를 등록해줍니다.
<< Groovy >>
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
# Ex 2
buildscript 작성 후 하단에 task 를 추가할 수도 있습니다.
<< Groovy >>
import org.apache.commons.codec.binary.Base64
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
task encode {
doLast {
def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
println new String(encodedString)
}
}
<< Command >>
> gradle -q encode
aGVsbG8gd29ybGQK
[Gradle - Basic] 로깅 (0) | 2020.03.06 |
---|---|
[Gradle - Basic] 빌드 라이프 사이클 (0) | 2020.03.05 |
[Gradle - Basic] 플러그인 (0) | 2020.03.05 |
[Gradle - Basic] 파일 관련 API (0) | 2020.03.01 |
[Gradle - Basic] 빌드 스크립트 기초 - (2) (0) | 2020.02.29 |