DEV Community

dss99911
dss99911

Posted on • Originally published at dss99911.github.io

Gradle Task - 태스크 정의, 의존성, 커스텀 태스크

Gradle Task

Task는 ANT의 target과 유사하며, project 객체의 하위 객체입니다. 태스크를 호출하면 서브 프로젝트에 동일한 태스크가 있는 경우 서브 프로젝트의 태스크도 함께 호출됩니다.

Task 정의하기

기본 형식

task hello {
    doLast {
        println 'tutorialspoint'
    }
}
Enter fullscreen mode Exit fullscreen mode

Deprecated 방식 (<< 연산자)

// In Groovy, << is the left shift operator to append elements to a list:
// this is deprecated.
task hello << {
    println 'tutorialspoint'
}
Enter fullscreen mode Exit fullscreen mode

문자열 이름으로 정의

task "hello" {
}
Enter fullscreen mode Exit fullscreen mode

프로그래밍 방식으로 태스크 추가

project.tasks.create("copy", CopyTask.class)
Enter fullscreen mode Exit fullscreen mode

여러 액션 추가하기

등록된 모든 액션이 호출됩니다.

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" }
Enter fullscreen mode Exit fullscreen mode

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")
}
Enter fullscreen mode Exit fullscreen mode

Task Methods

getByPath

tasks.getByPath('projectA:hello').path
Enter fullscreen mode Exit fullscreen mode

Task Dependencies (의존성)

기본 의존성 정의

task taskX << {
    println 'taskX'
}

task taskY(dependsOn: 'taskX') << {
    println "taskY"
}

task task1(dependsOn: [task2, task3])
Enter fullscreen mode Exit fullscreen mode

실행:

gradle -q taskY
Enter fullscreen mode Exit fullscreen mode

나중에 의존성 추가

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]
}
Enter fullscreen mode Exit fullscreen mode

동적 의존성

taskX.dependsOn {
    tasks.findAll {
        task -> task.name.startsWith('lib')
    }
}
Enter fullscreen mode Exit fullscreen mode

Task 건너뛰기

enabled 속성

sampleTask12.enabled = false  // configuration scope
Enter fullscreen mode Exit fullscreen mode

조건부 건너뛰기

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' }
Enter fullscreen mode Exit fullscreen mode

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()
    }
}
Enter fullscreen mode Exit fullscreen mode

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"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Rule: Dynamic Task

태스크가 없을 때 rule을 호출하고, rule이 태스크를 정의하여 호출합니다. 변수 값이 있을 때, 태스크 이름 뒤에 값을 넣는 방식으로 사용됩니다.

tasks.addRule("Pattern: sync<repoServer>") { String taskName ->
    if (taskName.startsWith("sync")) {
        task(taskName) << {
            println "Syncing from repository: " + (taskName - 'sync')
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
gradle -b build_rule.gradle tasks
Enter fullscreen mode Exit fullscreen mode

출력:

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>
Enter fullscreen mode Exit fullscreen mode

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'
    }
}
Enter fullscreen mode Exit fullscreen mode

실행 결과:

A config
B config
A do First
A do Last
B do First
B do Last
Enter fullscreen mode Exit fullscreen mode

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 " }
Enter fullscreen mode Exit fullscreen mode

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'
    }
}
Enter fullscreen mode Exit fullscreen mode

{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 " }
Enter fullscreen mode Exit fullscreen mode

독립 태스크 (다른 프로젝트에서 사용)

build.gradle:

apply plugin: 'groovy'
version = 1.0

dependencies {
    compile gradleApi()
    compile localGroovy()
}
Enter fullscreen mode Exit fullscreen mode

빌드 후 다른 프로젝트에서 사용:

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)
Enter fullscreen mode Exit fullscreen mode

Task Types (태스크 타입)

from, into 등은 모두 클래스 내부의 메서드입니다. 따라서 액션 전에 configuration을 설정합니다.

Copy

task copyTask(type: Copy) {
    from "."
    into "abc"
    include('employees.xml')
}
Enter fullscreen mode Exit fullscreen mode

이름 변경

task copyWithRename(type: Copy) {
    from "."
    into "dir1"
    include('employees.xml')
    rename { String fileName ->
        fileName.replace("employees", "abc")
    }
}
Enter fullscreen mode Exit fullscreen mode

Zip

task zipTask(type: Zip) {
    File destDir = file("dest")
    archiveName "sample.zip"
    from "src"
    destinationDir destDir
}
Enter fullscreen mode Exit fullscreen mode

Delete

task clean(type: Delete) {
    delete rootProject.buildDir
}
Enter fullscreen mode Exit fullscreen mode

태스크 내부에서 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"
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Originally published at https://dss99911.github.io

Top comments (0)