진짜 개발자
본문 바로가기

Software Engineering/Build Tool

BuildTool - Gradle Script 파일과 Gradle 도메인 객체(Task 객체)

728x90
Gradle Script 파일

Gradle의 스크립트 파일에 대해 알아보도록 하겠습니다. 이번 포스팅은 Gradle 철저 입문이라는 서적을 참고하여 작성되었습니다.

 

 

Gradle Script 파일

gradle 스크립트 파일에 기술된 내용은 실행시 Gradle의 도메인 객체들에게 적절히 위임됩니다. 따라서 작성한 내용이 어떤 도메인 객체에 위임되어 어떻게 실행되는지 파악하면, 스크립트 파일을 쉽게 이해할 수 있습니다.

 

 

1. Script 파일 구조

Gradle의 Script 파일은 처리문스크립트 블록으로 구성됩니다.

 

1.1 처리문

우선, 처리문의 경우 지역변수, 속성 설정 및 메소드 실행등 일반적인 언어들의 처리문과 같습니다. java의 경우 method 의 처리문에 해당하는 {} 안에 기술되는 내용과 같습니다.

 

1.2 스크립트 블록

스크립트 블록은 특정 설정을 위한 영역을 의미합니다. 간단히 말씀드리자면, 클로저를 인수로하는 메소드라고 표현할 수 있습니다.

예를들어 repositories{}블록을 작성하고 그안에 mavenCentral()을 작성하여, 의존관계를 해결하는 중앙저장소를 설정하는 등의 행위가 바로 스크립트 블록을 사용한 것입니다.

 

앞서 설정한 repositories 블록을 groovy방식으로 작성하면, 위와 같습니다. 즉, mavenCentral()을 호출하는 closure를 repositories로 넘겨 처리한것입니다. repositories()에 전달된 클로저는 저장소를 관리하는 도메인 객체인 RepositoryHandler 객체에 위임이 되고, 이 객체의 mavenCentral() 이라는 메소드가 호출됩니다.

 

 

앞서 살펴본 것을 토대로 다시한번 정리해드리면, 스크립트 블록을 작성하는 것은 특정 설정을 위해서, gradle의 도메인 객체의 API를 호출하는 것과 같습니다.

 

 

주요 스크립트 블록

script 블록개요도메인 객체
buildscriptbuildScript의 클래스패스 설정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 객체들을 삭제

간단한 사용예제를 통해 설명드리겠습니다.

 

build.gradle 파일을 생성하고, 위와 같이 작성합니다.

 

그 후, build.gradle이 존재하는 디렉토리에서 해당 테스크를 실행하면 위와같이 결과가 나타납니다.

 

앞서 작성한 내용을 groovy로 나타내면 내부에서는 위와 같은 처리가 일어납니다.



Task 작성시 오해할만한 부분

설정을 위한 영역

Task 공부를 하다보면, 약간 헷갈릴 수 있는 부분이 존재합니다. 앞서 Script 파일 구조를 설명 드릴때에, {}안에 기술되는 부분은 설정을 위한 영역이라고 설명드렸습니다.

즉, 위와 같이 task 블록안에 코드를 기술하여도 저부분은 설정을 위한 부분으로 인식이 됩니다.

 

위의 hello task를 작성한뒤 gradle hello명령어로 task를 실행해보면, 위와 같이 나타나는데요. 여기서 "뭐야? 실행이되는데?" 라고 착각을 하실 수 있습니다만. 자세히 보시면, Configure project를 보실 수 있습니다.

 

 

처리문을 추가해보자

그럼 어떻게 task 객체에 처리를 추가하는 거냐고 하실 수 있습니다. 앞서 설명을 드렸었는데요 doFirst, doLast 등의 API를 사용하시면 됩니다.

 

위와 같이 hello task를 변경한 뒤 다시 실행을 해봅시다.

 

이제 조금 감이오시나요 ?!

 

 

 

Task의 dependsOn 속성을 이용해 조금 더 이해하기

설정 영역과 task처리 영역을 조금더 깊이있게 이해하기 위해서, 앞서 설명드린 Task 도메인 객체의 속성중 dependsOn이란 속성을 이용해보면서, 설정영역과 task처리영역을 조금 더 이해 해보도록 하겠습니다.

 

위 처럼 build.gradle에 작성을 합니다.

 

간단히 설명 드리면, task done은 설정 영역에서 doing에 의존을 함을 설정했고, 테스크 처리를 위한 영역을 별도로 가지고 있습니다. 이어서 task doing역시 todo에 의존하며 별도의 테스크 처리영역을 가지고 있습니다. 마지막으로 task todo는 의존을 가지는 부분이 없으며 별도의 task처리 영역을 가지고 있습니다.

 

task done을 실행해 봅니다. 위와 같이 의존성을 가지는 task들을 먼저 실행한뒤 각각의 task가 처리되는 것을 볼 수 있습니다.