Gradle Task
Task는 ANT의 target과 유사하며, project 객체의 하위 객체입니다. 태스크를 호출하면 서브 프로젝트에 동일한 태스크가 있는 경우 서브 프로젝트의 태스크도 함께 호출됩니다.
Task 정의하기
기본 형식
task hello {
doLast {
println 'tutorialspoint'
}
}
Deprecated 방식 (<< 연산자)
// In Groovy, << is the left shift operator to append elements to a list:
// this is deprecated.
task hello << {
println 'tutorialspoint'
}
문자열 이름으로 정의
task "hello" {
}
프로그래밍 방식으로 태스크 추가
project.tasks.create("copy", CopyTask.class)
여러 액션 추가하기
등록된 모든 액션이 호출됩니다.
task sampleTask2 {
println "This is sampleTask2 configuration statements"
doFirst {
println "Task getProjectDetailsTask properties are: " + sampleTask1.taskDetail
}
}
sampleTask2.doFirst { println "Actions added separately" }
sampleTask2.doLast { println " More Actions added " }
sampleTask2.doFirst { println "Actions added separately2" }
sampleTask2.doLast { println " More Actions added 2" }
Task Properties
| Property | Description |
|---|---|
tasks |
태스크 목록 |
name |
태스크 이름 |
path |
태스크 경로 |
description |
태스크 설명 (gradle tasks 명령어에서 표시됨) |
task copy(type: Copy) {
description 'Copies the resource directory to the target directory.'
from 'resources'
into 'target'
include('**/*.txt', '**/*.xml', '**/*.properties')
println("description applied")
}
Task Methods
getByPath
tasks.getByPath('projectA:hello').path
Task Dependencies (의존성)
기본 의존성 정의
task taskX << {
println 'taskX'
}
task taskY(dependsOn: 'taskX') << {
println "taskY"
}
task task1(dependsOn: [task2, task3])
실행:
gradle -q taskY
나중에 의존성 추가
task taskY << {
println 'taskY'
}
task taskX << {
println 'taskX'
}
taskY.dependsOn taskX
taskY.dependsOn taskX, taskZ
// exclusively override existing dependencies
// this ignores compileJava task.
classes {
dependsOn = [task1, task2]
}
동적 의존성
taskX.dependsOn {
tasks.findAll {
task -> task.name.startsWith('lib')
}
}
Task 건너뛰기
enabled 속성
sampleTask12.enabled = false // configuration scope
조건부 건너뛰기
ext {
environment = 'prod'
// can set this value from property file or command line using -Pname=value option
}
task prodTask << {
println 'Executing prod tasks ' + environment
}
prodTask.onlyIf { project.hasProperty('environment') && project.environment == 'prod' }
task qaTask << {
println 'Executing qa tasks ' + environment
}
qaTask.onlyIf { project.hasProperty('environment') && project.environment == 'qa' }
closure로 조건 지정
// #1st approach - closure returning true, if the task should be executed, false if not.
eclipse.onlyIf {
project.hasProperty('usingEclipse')
}
// #2nd approach - alternatively throw an StopExecutionException() like this
// this stops only the task.
eclipse.doFirst {
if (!usingEclipse) {
throw new StopExecutionException()
}
}
Task Optimization
입력과 출력이 변경되지 않으면 태스크는 'UP-TO-DATE'로 표시되어 실행되지 않습니다. 입력과 출력이 있는 경우에만 작동합니다.
출력이 없는 경우 TaskOutputs.upToDateWhen() 또는 outputs.upToDateWhen을 사용합니다.
task updateExample {
ext {
propXml = file('PropDetails.xml')
}
File envFile = file('envproperty.txt')
File sysFile = file('sysproperty.txt')
inputs.file propXml
outputs.files(envFile, sysFile)
doLast {
println "Generating Properties files"
def properties = new XmlParser().parse(propXml)
properties.property.each { property ->
def fileName = property.filedetail[0].name[0].text()
def key = property.filedetail[0].key[0].text()
def value = property.filedetail[0].value[0].text()
def destFile = new File("${fileName}")
destFile.text = "$key = ${value}\n"
}
}
}
Task Order (순서)
- finalizedBy: 태스크 실행 후 다른 태스크를 실행합니다.
- mustRunAfter: 실행할 태스크가 있으면 해당 태스크 이후에 실행됩니다. 없으면 실행되지 않습니다.
- shouldRunAfter: mustRunAfter와 동일하지만, 순환 의존성이 있으면 이 순서를 무시합니다.
(1..6).each {
task "sampleTask$it" << {
println "Executing $name"
}
}
sampleTask1.dependsOn sampleTask2
sampleTask3.dependsOn sampleTask2
sampleTask5.finalizedBy sampleTask6
sampleTask5.mustRunAfter sampleTask4
Rule: Dynamic Task
태스크가 없을 때 rule을 호출하고, rule이 태스크를 정의하여 호출합니다. 변수 값이 있을 때, 태스크 이름 뒤에 값을 넣는 방식으로 사용됩니다.
tasks.addRule("Pattern: sync<repoServer>") { String taskName ->
if (taskName.startsWith("sync")) {
task(taskName) << {
println "Syncing from repository: " + (taskName - 'sync')
}
}
}
gradle -b build_rule.gradle tasks
출력:
Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
Pattern: sync<repoServer>
Task 구조
모든 태스크의 configuration이 먼저 실행되고, 그 다음 doFirst -> doLast 순서로 실행됩니다.
task A {
println 'A config'
doFirst {
println 'A do First'
throw new StopExecutionException()
}
doLast {
println 'A do Last'
}
}
task B(dependsOn: 'A') {
println 'B config'
doFirst {
println 'B do First'
}
doLast {
println 'B do Last'
}
}
실행 결과:
A config
B config
A do First
A do Last
B do First
B do Last
Custom Task (커스텀 태스크)
@TaskAction
doFirst -> TaskAction -> doLast 순서로 실행됩니다.
class SampleTask extends DefaultTask {
String systemName = "DefaultMachineName"
String systemGroup = "DefaultSystemGroup"
@TaskAction
def action1() {
println "System Name is " + systemName + " and group is " + systemGroup
}
@TaskAction
def action2() {
println 'Adding multiple actions for refactoring'
}
}
task hello(type: SampleTask)
hello {
systemName = 'MyDevelopmentMachine'
systemGroup = 'Development'
}
hello.doFirst { println "Executing first statement " }
hello.doLast { println "Executing last statement " }
buildSrc: 별도 파일에 커스텀 태스크 정의
buildSrc는 gradle 빌드용 소스입니다. 같은 프로젝트나 서브프로젝트에서만 사용할 수 있습니다.
{projectDir}/buildSrc/src/main/groovy/ch3/SampleTask.groovy:
package ch3
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
class SampleTask extends DefaultTask {
String systemName = "DefaultMachineName"
String systemGroup = "DefaultSystemGroup"
@TaskAction
def action1() {
println "System Name is " + systemName + " and group is " + systemGroup
}
@TaskAction
def action2() {
println 'Adding multiple actions for refactoring'
}
}
{projectDir}/build.gradle:
task hello(type: ch3.SampleTask)
hello {
systemName = 'MyDevelopmentMachine'
systemGroup = 'Development'
}
hello.doFirst { println "Executing first statement " }
hello.doLast { println "Executing last statement " }
독립 태스크 (다른 프로젝트에서 사용)
build.gradle:
apply plugin: 'groovy'
version = 1.0
dependencies {
compile gradleApi()
compile localGroovy()
}
빌드 후 다른 프로젝트에서 사용:
buildscript {
repositories {
// relative path of sampleTaskProject jar file
flatDir { dirs "../SampleTaskProj/build/libs" }
}
dependencies {
classpath group: 'ch3', name: 'SampleTaskProj', version: '1.0'
}
}
task hello(type: ch3.SampleTask)
Task Types (태스크 타입)
from, into 등은 모두 클래스 내부의 메서드입니다. 따라서 액션 전에 configuration을 설정합니다.
Copy
task copyTask(type: Copy) {
from "."
into "abc"
include('employees.xml')
}
이름 변경
task copyWithRename(type: Copy) {
from "."
into "dir1"
include('employees.xml')
rename { String fileName ->
fileName.replace("employees", "abc")
}
}
Zip
task zipTask(type: Zip) {
File destDir = file("dest")
archiveName "sample.zip"
from "src"
destinationDir destDir
}
Delete
task clean(type: Delete) {
delete rootProject.buildDir
}
태스크 내부에서 copy 사용
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy { // clear project하면 사라지니까 복사
from variant.mappingFile
into "${rootDir}/mappingFiles"
rename { String fileName ->
"mapping-${variant.name}${data}.txt"
}
}
}
}
Originally published at https://dss99911.github.io
Top comments (0)