사용자 도구

사이트 도구


gradle:task

Gradle Task

선언

task hello << {
    println "hello"
}
 
// 괄호하고 이름
task(hello) << {
    println "hello"
}
 
task(copy, type: Copy) {
    from(file('srcDir'))
    into(buildDir)
}
 
// 이름을 문자열로
task('hello') <<
{
    println "hello"
}
 
// tasks 에 추가
tasks.add(name: 'taskName', type: org.something.GradleTask, dependsOn: 'anotherTask') {
    // task 설정
    println "hello"
}
 
// with create
 
tasks.create(name: 'taskName', type: org.something.GradleTask, dependsOn: 'anotherTask') {
   // task 설정
}

태스크 정보 설정

  • Task의 description과 group을 지정하면 gradle tasks 시에 정보를 표시해 준다.
  • group은 마음대로 정할 수 있지만, 기본적으로 build 등이 있다.
    dist {
        description = '태스크 설명'
        group = '태스크의 그룹'
    }
    // 혹은
    dist.description = '태스크 설명'
    dist.group = '태스크의 그룹'
  • 동적 프라퍼티 설정
    task something {
        ext.prop1 = 'xxx'
        ext.prop2 = 'yyy'
    }
    // 외부에서 something.prop1 으로 접근 가능

task에 접근하기

  • task hello가 있을 때,
    • hello.name
    • project.hello.name
    • tasks.hello.name
    • tasks['hello'].name
  • tasks.getByPath()로 접근
    project(':projectA') {
        task hello
    }
     
    task hello
     
    println tasks.getByPath('hello').path // :hello
    println tasks.getByPath(':hello').path // :hello
    println tasks.getByPath('projectA:hello').path // :projectA:hello
    println tasks.getByPath(':projectA:hello').path // :projectA:hello

task 설정

  • 설정하기
    // 단일 선언
    task myCopy(type: Copy)
     
    // 태스크의 메소드 호출 등으로 설정하기 1
    Copy myCopy = task(myCopy, type: Copy)
    myCopy.from 'resources'
    myCopy.into 'target'
    myCopy.include('**/*.txt', '**/*.xml', '**/*.properties')
     
    // 설정 2
    task(myCopy, type: Copy)
        .from('resources')
        .into('target')
        .include('**/*.txt', '**/*.xml', '**/*.properties')
     
    // 설정 3
    task myCopy(type: Copy)
     
    myCopy {
       from 'resources'
       into 'target'
       include('**/*.txt', '**/*.xml', '**/*.properties')
    }
     
    // 설정 4, configure() 메소드
    task myCopy(type: Copy)
     
    myCopy.configure {
       from('source')
       into('target')
       include('**/*.txt', '**/*.xml', '**/*.properties')
    }
     
    // 설정 5. 선언시
    task copy(type: Copy) {
       from 'resources'
       into 'target'
       include('**/*.txt', '**/*.xml', '**/*.properties')
    }
  • 의존성 설정
    // 다른 프로젝트의 태스크
    project('projectA') {
        task taskX(dependsOn: ':projectB:taskY') << {
            println 'taskX'
        }
    }
     
    // 나중에 설정
    taskX.dependsOn taskY
     
    // 여러 태스크에 의존
    taskX.dependsOn ['taskY', 'taskZ']
     
    // 이름을 리턴하는 클로저를 통한 다중 설정
    taskX.dependsOn {
        tasks.findAll { task -> task.name.startsWith('lib') }
    }
  • 설명(description) 추가 : 태스크에 description 프라퍼티를 설정하면 gradle tasks에서 볼 수 있게 된다.
  • 태스크 대체 : 플러그인에서 생성한 태스크를 개발자가 원하는 것으로 대체하길 원하거나 할 때 사용 overwrite: true
    task copy(type: Copy)
     
    task copy(overwrite: true) << {
        println('I am the new one.')
    }

태스크 건너 뛰기

  • onlyIf
    // hello task에 대해
    hello.onlyIf { !project.hasProperty('skipHello') }
     
    // 실행시 skipHello 프라퍼티 지정
    gradle hello -PskipHello 
  • StopExecutionException 예외를 던지면, 해당 지점부터 그 태스크는 실행이 안되고 건너뛴다. 그 이후 실행할 태스크는 계속 실행된다.
    task compile << {
        println 'We are doing the compile.'
    }
     
    compile.doFirst {
        // if문에 원하는 조건을 지정한다.
        if (true) { throw new StopExecutionException() }
    }
    task myTask(dependsOn: 'compile') << {
       println 'I am not affected'
    }
  • task.enabled=true|false 이 값이 true여야만 해당 태스크가 실행된다.

이미 최신으로 갱신된 태스크 건너뛰기

  • 자바 컴파일 태스크 같은 경우 이미 모든 최신 java 파일이 컴파일 돼 있다면 건너뛰는 기능이 있다. 이 같은 것을 구현하는 방법.
  • 모든 태스크에는 TaskInputs inputsTaskOutputs outputs 프라퍼티가 있다. 이 값을 설정해주면 자동으로 UP-TO-DATE인지 검사하여 실행 여부를 결정한다.
    task transform {
        ext.srcFile = file('mountains.xml')
        ext.destDir = new File(buildDir, 'generated')
        inputs.file srcFile
        outputs.dir destDir
        doLast {
            println "Transforming source file."
            destDir.mkdirs()
            // outputs.dir 영역에 파일을 생성하는 코드..
        }
    }
  • 작동방식
    • 태스크 실행시작시 inputs에 있는 파일의 스냅샷을 찍는다.
    • 태스크 실행후 outputs에 있는 파일의 스냅샷을 찍는다.
    • 태스크를 재실행할 때 이전 inputs, outputs의 스냅샷과 현재 inputs와 outputs의 스냅샷을 비교하여 변경 사항이 없으면 해당 태스크를 건너뛴다. 아니면 태스크를 실행하고 모든 스냅샷을 다시 찍는다.

멀티 프로젝트에서 각 프로젝트 별 최신 갱신 여부 검사

inputs/outputs를 사용하여 VCS에서 받은 멀티 프로젝트의 프로젝트별 갱신 여부를 검사할 수 있다.

task checkUpToDate {
    description = '프로젝트 최신 갱신 여부 검사'
 
    def checkFile = file(new File(tmpDir, "gradle_${project.name}_check_up_to_date").absoluteFile)
 
    FileTree projectFileTree = fileTree(dir: project.projectDir)
    projectFileTree.exclude "${builDir}/**/*"
 
    inputs.files projectFileTree
    outputs.file checkFile
 
    doLast {
        println "[${project.name}] needs refresh."
        if (checkFile.exists()) {
            checkFile.delete()
        }
 
        checkFile.createNewFile()
    }
}

Task Rules

  • tasks.addRule 태스크 생성 규칙을 통해 동적으로 태스크를 만들어낼 수 있다.
    tasks.addRule("Pattern: ping<ID>") { String taskName ->
        if (taskName.startsWith("ping")) {
            task(taskName) << {
                println "Pinging: " + (taskName - 'ping')
            }
        }
    }
     
    // Rule에 대해 의존성을 지정하는 것도 가능하다.
    task groupPing {
        dependsOn pingServer1, pingServer2
    }

태스크의 실행 순서

  • 태스크에 dependsOn [a, b] 형태로는 실행 순서를 지정할 수 없다. dependsOn 은 의존 대상을 명시할 뿐 의존 대상의 실행순서는 명시하지 않는다.
  • 기존방법 : 다음과 같은 방식으로 순서를 명확히 하는 것도 가능하다.
    task somethingLastTask << {
        tasks.somethingFirstTask.execute()
        tasks.somethingSecondTask.execute()
        ....
        // do somthing last
    }
  • 새로운 방법(2015년 1월 현재 incubating) :
    // 보통은 task1 -> task2 순서로 실행하지만 특정 상황에서는 이를 무시한다.
    task2.shouldRunAfter task1
     
    // 무조건 task1 -> task2 순서를 지킨다.
    task2.mustRunAfter task1

tasks

UP-TO-Date upToDate 조건

  • TaskOutputs.upToDateWhen을 통해 upToDate 검사 조건을 변경할 수 있다.
  • 태스크를 무조건 실행하게 만들고자 한다면 Up to date 검사를 안하게 만들면 된다.
    // 태스크 선언부에서 아래와 같은 형태를 띄게 된다.
     
    task someTask {
      outputs.upToDateWhen { false }
     
      doLast {
         ... 
      }
    }

--rerun-tasks

  • –rerun-tasks 옵션을 주면 up-to-date 상태와 무관하게 무조건 태스크를 실행한다.

Task 실행에서 제외

  • “aaa” 태스크 실행시 “bbb” 태스크가 의존성에 걸려있더라도 실행을 하지 않고 건너뛰게 해야하는 경우가 있다.
gradle.taskGraph.whenReady { taskGraph ->
  def tasks = taskGraph.allTasks
 
  // 태스크 실행 그래프에 'aaa'가 들어있으면
  if (tasks.find { it.name.toLowerCase() == 'aaa'}) {
    bbb.enabled = false // bbb 태스크를 skip 한다. 로그상에 SKIP으로 뜸
  }
}

참조

gradle/task.txt · 마지막으로 수정됨: 2018/05/31 13:45 저자 kwon37xi