Gradle의 스크립트 파일에 대해 알아보도록 하겠습니다. 이번 포스팅은 Gradle 철저 입문
이라는 서적을 참고하여 작성되었습니다.
Gradle Script 파일
gradle 스크립트 파일에 기술된 내용은 실행시 Gradle의 도메인 객체들에게 적절히 위임됩니다. 따라서 작성한 내용이 어떤 도메인 객체에 위임되어 어떻게 실행되는지 파악하면, 스크립트 파일을 쉽게 이해할 수 있습니다.
1. Script 파일 구조
Gradle의 Script 파일은 처리문
과 스크립트 블록
으로 구성됩니다.
1.1 처리문
xxxxxxxxxx
def message = 'hi'
hello()
...
우선, 처리문의 경우 지역변수, 속성 설정 및 메소드 실행등 일반적인 언어들의 처리문과 같습니다. java의 경우 method 의 처리문에 해당하는 {}
안에 기술되는 내용과 같습니다.
1.2 스크립트 블록
스크립트 블록은 특정 설정을 위한 영역을 의미합니다. 간단히 말씀드리자면, 클로저
를 인수로하는 메소드라고 표현할 수 있습니다.
xxxxxxxxxx
repositories {
mavenCentral()
}
예를들어 repositories{}
블록을 작성하고 그안에 mavenCentral()
을 작성하여, 의존관계를 해결하는 중앙저장소를 설정하는 등의 행위가 바로 스크립트 블록을 사용한 것입니다.
xxxxxxxxxx
//groovy 방식
def closure = { mavenCentral() }
this.repositories(closure)
앞서 설정한 repositories 블록
을 groovy방식으로 작성하면, 위와 같습니다. 즉, mavenCentral()
을 호출하는 closure를 repositories로 넘겨 처리한것입니다. repositories()에 전달된 클로저는 저장소를 관리하는 도메인 객체인 RepositoryHandler 객체에 위임이 되고, 이 객체의 mavenCentral() 이라는 메소드가 호출됩니다.
앞서 살펴본 것을 토대로 다시한번 정리해드리면, 스크립트 블록
을 작성하는 것은 특정 설정을 위해서, gradle의 도메인 객체의 API를 호출하는 것과 같습니다.
주요 스크립트 블록
script 블록 | 개요 | 도메인 객체 |
---|---|---|
buildscript | buildScript의 클래스패스 설정 | ScriptHandler |
dependencies | 의존관계 해결을 위한 설정 | DependencyHandler |
repositories | 중앙저장소 설정 | RepositoryHandler |
gradle script 파일 작성시, 자주 보았던 스크립트 블록들입니다. 앞서 설명드렸듯이 스크립트 블록은, 도메인 객체에 위임되어 실행되며, 또한 특정 설정을 위해 존재합니다.
2. Task 객체
우선 Gradle의 각각의 도메인 객체들은 크게 속성
과 API
로 이루어져 있습니다. 여러 도메인 객체들중 중요한 Task 객체에 대해 알아보도록 하겠습니다.
Task 객체는 대상작업을 나타내는 도메인 객체입니다. 즉 필요한 처리들이 정의되고 이를 수행하는 역할을 하는 객체입니다.
속성
속성 | 개요 |
---|---|
inputs | 태스크의 입력정보 |
outputs | 태스크의 출력정보 |
dependsOn | 태스크가 의존하는 태스크 정보 |
mustRunAfter | 반드시 먼저 실행되어야 하는 태스크지정 |
먼저 Task 객체의 속성을 살펴보도록 하겠습니다. 참고로 위의 표에 작성된 속성보다 더 많은 속성이 존재합니다. 위의 속성들은 Task객체의 실행 순서를 제어하거나, 상태에 따라 실행을 건너띄는 등의 설정을 할 수 있도록 도와주는 속성들입니다.
actions 속성
Task에는 actions
라는 속성이 존재합니다. 이것은 그레들의 최소 처리단위를 나타내는 Action
객체의 리스트로, Task 스크립트 블록에서 정의한 작업들이 모인것입니다.
주요 API
- 테스크 처리
- 테스크 실행
- 속성 접근
Task 객체의 API는 위와 같이 크게 세가지로 분류됩니다. 이 포스팅에서는 테스크 처리관련한 API만을 다루겠습니다.
API | 개요 |
---|---|
doFirst() | 태스크처리를 actions 리스트의 선두에 Action 객체로 추가 |
doLast() | 태스크처리를 actions 리스트의 마지막에 Action 객체로 추가 |
leftShift() | 태스크처리를 actions 리스트의 마지막에 Action 객체로 추가 |
deleteAllActions() | actions 리스트의 Action 객체들을 삭제 |
간단한 사용예제를 통해 설명드리겠습니다.
x
task greet {
doFirst {
println 'first'
}
}
greet.doFirst {
println 'first of first'
}
greet.doLast {
println 'last'
}
greet.doLast {
println 'last of last'
}
build.gradle 파일을 생성하고, 위와 같이 작성합니다.
그 후, build.gradle이 존재하는 디렉토리에서 해당 테스크를 실행하면 위와같이 결과가 나타납니다.
x
List<Action> actions = new ArrayList<>();
//diFirst() 처리
Closure doFirstAction = { println 'first' }
actions.add(0, doFirstAction)
//diFirst() 처리
Closure doFirstOfFirstAction = { println 'first of first' }
actions.add(0, doFirstOfFirstAction)
//doLast() 처리
Closure doLastAction = {println 'last'}
actions.add(doLastAction)
//doLast() 처리
Closure doLastOfLastAction = {println 'last of last'}
actions.add(doLastOfLastAction)
//actions 처리
actions.each { action ->
action.execute()
}
앞서 작성한 내용을 groovy로 나타내면 내부에서는 위와 같은 처리가 일어납니다.
Task 작성시 오해할만한 부분
설정을 위한 영역
Task 공부를 하다보면, 약간 헷갈릴 수 있는 부분이 존재합니다. 앞서 Script 파일 구조를 설명 드릴때에, {}
안에 기술되는 부분은 설정을 위한 영역이라고 설명드렸습니다.
task hello {
println '설정을 위한 영역입니다.'
}
즉, 위와 같이 task 블록안에 코드를 기술하여도 저부분은 설정을 위한 부분으로 인식이 됩니다.
위의 hello task를 작성한뒤 gradle hello
명령어로 task를 실행해보면, 위와 같이 나타나는데요. 여기서 "뭐야? 실행이되는데?"
라고 착각을 하실 수 있습니다만. 자세히 보시면, Configure project
를 보실 수 있습니다.
처리문을 추가해보자
그럼 어떻게 task 객체에 처리를 추가하는 거냐고 하실 수 있습니다. 앞서 설명을 드렸었는데요 doFirst, doLast
등의 API를 사용하시면 됩니다.
xtask hello {
println '설정을 위한 영역입니다.'
doLast {
println '진짜 실행영역'
}
}
위와 같이 hello task를 변경한 뒤 다시 실행을 해봅시다.
이제 조금 감이오시나요 ?!
Task의 dependsOn 속성을 이용해 조금 더 이해하기
설정 영역과 task처리 영역을 조금더 깊이있게 이해하기 위해서, 앞서 설명드린 Task 도메인 객체의 속성중 dependsOn
이란 속성을 이용해보면서, 설정영역과 task처리영역을 조금 더 이해 해보도록 하겠습니다.
xxxxxxxxxx
task todo {
//테스크 처리를 위한 부분
doFirst {
println '준비'
}
}
task doing {
//설정을 위한 부분
dependsOn todo
//테스크 처리를 위한 부분
doFirst {
println '실행 중'
}
}
task done {
//설정을 위한 부분
dependsOn doing
//테스크 처리를 위한 부분
doFirst {
println '실행 완료'
}
}
위 처럼 build.gradle
에 작성을 합니다.
간단히 설명 드리면, task done
은 설정 영역에서 doing에 의존을 함을 설정했고, 테스크 처리를 위한 영역을 별도로 가지고 있습니다. 이어서 task doing
역시 todo에 의존하며 별도의 테스크 처리영역을 가지고 있습니다. 마지막으로 task todo
는 의존을 가지는 부분이 없으며 별도의 task처리 영역을 가지고 있습니다.
task done
을 실행해 봅니다. 위와 같이 의존성을 가지는 task들을 먼저 실행한뒤 각각의 task가 처리되는 것을 볼 수 있습니다.
'Software Engineering > Build Tool' 카테고리의 다른 글
Build Tool - Gradle 개념 정리 (0) | 2020.12.19 |
---|---|
BuildTool - Groovy란? (Groovy 문법과, 초간단 build.gradle 작성 예제) (0) | 2019.10.06 |
BuildTool - Gradle 구성 파일 요약(init.gradle, settings.gradle, build.gradle) (0) | 2019.10.05 |
BuildTool - Build란? (0) | 2019.10.05 |
Gradle - Intellij Build sync fail (Invalid gradle JDK Configuration found) (0) | 2019.02.02 |