사용자 도구

사이트 도구


gradle:buildlifecycle

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
gradle:buildlifecycle [2012/10/08 17:09]
kwon37xi [멀티 프로젝트 빌드]
gradle:buildlifecycle [2014/08/29 14:40] (현재)
kwon37xi [프로젝트 평가]
줄 71: 줄 71:
 설정 파일에서 만들어진 멀티 프로젝트 트리는 프로젝트 기술자(project descriptors)라는 것으로 만들어진다. 이 기술자를 변경할 수 있다. 설정 파일에서 만들어진 멀티 프로젝트 트리는 프로젝트 기술자(project descriptors)라는 것으로 만들어진다. 이 기술자를 변경할 수 있다.
  
-  * ''프로젝트 트리의 요소 수정 전 ''settings.gradle'' <code groovy>+  * 프로젝트 트리의 요소 수정 전 ''settings.gradle'' <code groovy>
 println rootProject.name println rootProject.name
 println project(':projectA').name println project(':projectA').name
줄 84: 줄 84:
  
 ===== 초기화 ===== ===== 초기화 =====
 +Gradle이 단일 혹은 멀티 프로젝트 빌드를 실행할지 판단하는 기준이 있다. 설정 파일이 있는 디렉토리에서 멀티 프로젝트를 빌드를 실행하면 판단이 쉽다. 하지만 서브 프로젝트 아무데서나 빌드를 실행할 수도 있다. ''settings.gradle''이 없는 곳에서 빌드를 실행하면
  
 +  * 현재 디렉토리와 동일한 계층 단계의 ''master''라는 디렉토리에서 ''settings.gradle''을 찾는다.
 +  * 없으면, 부모 디렉토리에서 ''settings.gradle''을 찾는다.
 +  * 없으면, 단일 프로젝트로 빌드를 실행한다.
 +  * ''settings.gradle''가 존재하면 현재 프로젝트가 멀티 프로젝트 계층에 속하는지 판단한다. 아니라면 단일 프로젝트로 실행하고 맞다면 멀티 프로젝트로 빌드를 실행한다.
 +
 +이런 식으로 작동하는 이유는 멀티 프로젝트 일 경우 모든 멀티프로젝트 빌드 구성을 생성해야하기 때문이다. ''-u'' 명령행 옵션을 주면 부모 디렉토리에서 설정파일 찾는 것을 막는다. 이 경우에는 항상 단일 프로젝트로 실행한다. ''settings.gradle'' 파일이 있는 곳에서 ''-u''는 아무 기능도 없다.
 +
 +설정 파일 자동 탐색은 물리적으로 계층/단층 레이아웃인 멀티 프로젝트에서만 작동한다. 단층 레이아웃에서는 위에서 기술한 명명규칙을 지켜야 한다. Gradle은 멀티 프로젝트에 임의의 물리적 레이아웃을 지원하지만 이 때는 항상 설정 파일이 있는 곳에서 빌드를 실행해야 한다. 
 +
 +Gradle은 빌드에 참여하는 모든 프로젝트에 대해 Project 객체를 생성한다. 각 프로젝트는 기본적으로 탑레벨 디렉토리를 ''name''으로 갖는다. 최상위를 제외한 모든 프로젝트는 부모 프로젝트가 있고, 자식 프로젝트를 가질 수 있다.
 +
 +
 +===== 빌드 스크립트 라이프사이클에 반응하기 =====
 +라이프싸이클을 진행하는 동안 빌드 스크립트에서 알림을 받을 수 있다. 알림은 특별한 리스너 인터페이스를 구현하거나 혹은 알림이 발생했을 때 실행할 클로저를 제공해 주는 두가지 방식으로 구현한다.
 +
 +==== 프로젝트 평가 ====
 +프로젝트를 평가하기 직전과 직후에 알림을 받을 수 있다. 빌드 스크립트에서 모든 정의가 적용된 이후에 추가적인 구성을 수행할 때나 로깅 혹은 프로파일링을 하고자 할 때 사용한다.
 +
 +  * ''hasTest'' 프라퍼티가 ''true''인 프로젝트들에 ''test'' 태스크 추가하기 ''build.gradle'' <code groovy>
 +allprojects {
 +    afterEvaluate { project ->
 +        if (project.hasTests) {
 +            println "Adding test task to $project"
 +            project.task('test') << {
 +                println "Running tests for $project"
 +            }
 +        }
 +    }
 +}
 +</code>
 +  * ''projectA.gradle'' <code groovy>
 +hasTests = true
 +</code>
 +  * 실행하면 <code>
 +> gradle -q test
 +Adding test task to project ':projectA'
 +Running tests for project ':projectA'
 +</code>
 +[[http://gradle.org/docs/current/javadoc/org/gradle/api/Project.html#afterEvaluate%28groovy.lang.Closure%29|Project.afterEvaluate()]]를 사용하여 프로젝트 평가 뒤에 실행할 클로저를 추가 하였다.
 +
 +아무 프로젝트든 평가한 뒤에 알림을 받는 것도 가능하다. ''afterProject''는 프로젝트 평가의 성공 여부와 무관하게 호출된다.
 +
 +  * 프로젝트의 성공 여부를 보여주는 ''build.gradle'' <code groovy>
 +gradle.afterProject {project, projectState ->
 +    if (projectState.failure) {
 +        println "Evaluation of $project FAILED"
 +    } else {
 +        println "Evaluation of $project succeeded"
 +    }
 +}
 +</code>
 +  * 실행하면 <code>
 +> gradle -q test
 +Evaluation of root project 'buildProjectEvaluateEvents' succeeded
 +Evaluation of project ':projectA' succeeded
 +Evaluation of project ':projectB' FAILED
 +</code>
 +
 +[[http://www.gradle.org/docs/current/dsl/org.gradle.api.invocation.Gradle.html|Gradle]] 객체에 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/ProjectEvaluationListener.html|ProjectEvaluationListener]] 를 추가해도 된다.
 +
 +  * 최상위 ''build.gradle''에서 특정 하위 프로젝트를 콕 집어서 지정<code groovy>
 +project(':sub-project').afterEvaluate {
 +   // ....
 +}
 +</code>
 +==== 태스크 생성 ====
 +  * 프로젝트에 태스크가 추가된 직후에 알림을 받을 수 있다. 기본값을 설정하거나 태스크가 빌드에 노출되기전에 행위를 추가하고자 할 때 사용한다.
 +  * 각 태스크가 생성된 뒤에 ''srcDir''을 설정하는 ''build.gradle'' <code groovy>
 +tasks.whenTaskAdded { task ->
 +    task.srcDir = 'src/main/java'
 +}
 +
 +task a
 +
 +println "source dir is $a.srcDir"
 +</code>
 +  * 실행하면 <code>
 +> gradle -q a
 +source dir is src/main/java
 +</code>
 +
 +[[http://www.gradle.org/docs/current/javadoc/org/gradle/api/tasks/TaskContainer.html|TaskContainer]]에 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/Action.html|Action]]을 추가해도 된다.
 +
 +==== 태스크 실행 그래프가 정해진 뒤에 ====
 +  * 실행할 태스크에 ''release''가 있는지 여부에 따라 버전 변경하는 ''build.gradle'' <code groovy>
 +task distribution << {
 +    println "We build the zip with version=$version"
 +}
 +
 +task release(dependsOn: 'distribution') << {
 +    println 'We release now'
 +}
 +
 +gradle.taskGraph.whenReady {taskGraph ->
 +    if (taskGraph.hasTask(release)) {
 +        version = '1.0'
 +    } else {
 +        version = '1.0-SNAPSHOT'
 +    }
 +}
 +</code> 
 +
 +''release'' 태스크의 실행여부에 따라 버전값이 달라진다. [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/execution/TaskExecutionGraph.html|TaskExecutionGraph]]에 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/execution/TaskExecutionGraphListener.html|TaskExecutionGraphListener]]를 추가해도 된다.
 +
 +==== 태스크 실행 ====
 +어떤 태스크이든 실행 직전과 직후에 알림을 받을 수 있다.
 +
 +  * 태스크 실행과 종료를 로그로 남기는 ''build.gradle'' <code groovy>
 +task ok
 +
 +task broken(dependsOn: ok) << {
 +    throw new RuntimeException('broken')
 +}
 +
 +gradle.taskGraph.beforeTask { Task task ->
 +    println "executing $task ..."
 +}
 +
 +gradle.taskGraph.afterTask { Task task, TaskState state ->
 +    if (state.failure) {
 +        println "FAILED"
 +    }
 +    else {
 +        println "done"
 +    }
 +}
 +</code>
 +  * 실행하면 <code>
 +> gradle -q broken
 +executing task ':ok' ...
 +done
 +executing task ':broken' ...
 +FAILED
 +</code>
 +
 +[[http://www.gradle.org/docs/current/javadoc/org/gradle/api/execution/TaskExecutionGraph.html|TaskExecutionGraph]]에 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/execution/TaskExecutionListener.html|TaskExecutionListener]]를 추가해도 된다.
  
gradle/buildlifecycle.1349683786.txt.gz · 마지막으로 수정됨: 2012/10/08 17:09 저자 kwon37xi