Gradle详解-Chapter 20. The Build Lifecycle

来源:互联网 发布:软件模块起英文名 编辑:程序博客网 时间:2024/05/21 06:23

Chapter 14 基础脚本构建

Chapter 16. Writing Build Scripts 写脚本

Chapter17. More about Tasks

脚本的生命周期

Chapter 20. The Build Lifecycle

简单说明,Gradle是基于编程语言的,我们可以自己定义task和task之间的依赖,Gradle确保有顺序的去执行这些任务及依赖任务,并且每个任务只执行一次。当任务执行的时候Gradle要完成task及task依赖的图标关系(Directed Acyclic Graph)

  20.1. Build phases 构建阶段
  
Gradle构建有三个不同的阶段:
Initialization
  Gradle支持单个和多个项目的构建。Gradle在初始化阶段决定哪些projects参与构建,并且为每一个项目创建一个Project类的实例对象。

Configuration
  在这个阶段配置每个Project的实例对象。然后就执行这些项目脚本中的一部分task。在Gradle1.4,引入了 incubating opt-in feature被称之为configuration on demand,在这种模式下,Gradle之后配置相关项目,详情(see Section 24.1.1.1, “Configuration on demand”)
Execution
  Grade确定tasks的子集,在配置界面创建和配置这些task,然后执行task。这些子集任务的名称当成参数传递给gradle命令和和当前目录。Then,Gradle执行每一个选择的task。
  
  20.2. Settings file 设置文件
  Gradle定义了一个设置文件,默认名称为settings.gradle
  在Gradle的初始化阶段(Initialization)加载settings.gradle文件。
  多项目的工程settings.gradle文件在工程的根目录。
  对于单个项目settings.gradle是可选择的,但是多个项目的工程它是必须要有的,详细信息 (see Chapter 24, Multi-project Builds)
  settings.gradle定义了工程中包含的项目,你也有可能会添加一些库文件到脚本路径中,详情(see Chapter 41, Organizing Build Logic)
  
eg:
settings.gradle文件:

println ‘This is executed during the initialization phase.’

build.gradle文件:

println 'This is executed during the configuration phase.'task configured {    println 'This is also executed during the configuration phase.'}task test << {    println 'This is executed during the execution phase.'}task testBoth {    doFirst {      println 'This is executed first during the execution phase.'    }    doLast {      println 'This is executed last during the execution phase.'    }    println 'This is executed during the configuration phase as well.'}

结果:

> gradle test testBothThis is executed during the initialization phase.This is executed during the configuration phase.This is also executed during the configuration phase.This is executed during the configuration phase as well.:testThis is executed during the execution phase.:testBothThis is executed first during the execution phase.This is executed last during the execution phase.BUILD SUCCESSFULTotal time: 1 secs

对于一个构建脚本,属性和方法的调用被委托给一个Project类的实例对象。所以类似的settings.gradle中属性和方法被委托给一个Settings类的实例对象。

  20.3. Multi-project builds
  
  多项目构建详情 (see Chapter 24, Multi-project Builds).
  
  20.3.1. Project locations  项目位置
  
  多项目的构建类似于树(只有一个根却有很多分支),每个分支代表一个项目project。每个项目project都有一个path代表其位置。大多数情况下每个项目project位置都是在工程的根目录中。但是每个项目project的path是可以配置的。
  默认情况下settings.gradle文件位置就是工程根目录位置,但是工程根目录root project也是可以再settings.gradle中配置的。
  
  20.3.2. Building the tree 构建项目
  settings.gradle中配置每个project。一般是两种写法:分层布局和平面布局。
   20.3.2.1. Hierarchical layouts  分层布局:子project在root project文件夹下
    settings.gradle文件中:
    include ‘project1’, ‘project2:child’, ‘project3:child1’
   20.3.2.2. Flat layouts 平面布局:子project和root project在同一文件加下
    settings.gradle文件中:
    includeFlat ‘project3’, ‘project4’
   
  20.3.3. Modifying elements of the project tree
  project descriptors在settings.gradle文件中创建每一个子project
  所以我们可以通过descriptor改变子project和root project的名称和位置。
  
  settings.gradle 文件中:

println rootProject.nameprintln project(':projectA').name

  settings.gradle 文件中:

rootProject.name = 'main'project(':projectA').projectDir = new File(settingsDir, '../my-project-a')project(':projectA').buildFileName = 'projectA.gradle'

ProjectDescriptor-API详情

 20.4. Initialization
 这个就是找settings.gradle文件和解析该文件的过程。
 当前目录找settings.gradle,找不到就在父目录找,找不到就认为是单个项目project。父目录找到后解析settings.gradle判断是单个project还是multi-project。

 20.5. Configuration and execution of a single project build
  配置和执行task,如果该task存在。
  The configuration and execution for multi-project builds is discussed in Chapter 24, Multi-project Builds.

 20.6. Responding to the lifecycle in the build script 监听声明周期 
 两种方式:监听器或者是闭包(通知触发)
 
 20.6.1. Project evaluation
 当一个项目在审核之前或者之后,会发出一个通知。
 Project.afterEvaluate()被执行,当project审核后。
 
 build.gradle –>root project 目录下的文件

// 监听器方式allprojects {    afterEvaluate { project ->        if (project.hasTests) { // 哪个子project 设置了该属性值为true,就为哪个子project添加test task。            println "Adding test task to $project"            project.task('test') << {                println "Running tests for $project"            }        }    }}allprojects {  // 所有项目添加属性    ext.hasTests = false}

结果:

D:\GradleTest>gradle -q testAdding test task to project ':project1'Running tests for project ':project1'

afterEvaluate 和 beforeEvaluate是ProjectEvaluationListener接口中的方法。

还可以通过gradle中afterProject通知
beforeProject(closure)
afterProject(closure)

// 闭包方式gradle.afterProject {project, projectState ->    if (projectState.failure) {        println "Evaluation of $project FAILED"    } else {        println "Evaluation of $project succeeded"    }}

详情:You can also add a ProjectEvaluationListener to the Gradle to receive these events.

 20.6.2. Task creation 任务创建
 在初始化阶段给任务添加新的属性或者是行为。

tasks.whenTaskAdded { task ->    task.ext.srcDir = 'src/main/java'}task aprintln "source dir is $a.srcDir"

结果:

> gradle -q asource dir is src/main/java

You can also add an Action to a TaskContainer to receive these events.

 20.6.3. Task execution graph ready
 You can receive a notification immediately after the task execution graph has been populated. We have seen this already in Section 14.13, “Configure by DAG”.

You can also add a TaskExecutionGraphListener to the TaskExecutionGraph to receive these events.

 20.6.4. Task execution
 task 执行前后也可以收到通知。

task oktask 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"    }}

结果:

> gradle -q brokenexecuting task ':ok' ...doneexecuting task ':broken' ...FAILED

You can also use a TaskExecutionListener to the TaskExecutionGraph to receive these events.

0 0
原创粉丝点击