码迷,mamicode.com
首页 > 其他好文 > 详细

Building and Testing with Gradle

时间:2015-06-10 22:43:05      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:gradle

Chapter 1. Hello, Gradle!


  • ANT:灵活,没有任何的约定俗成,没有依赖管理,虽然后来加入了依赖管理,但是还是不支持约定
  • Maven:提供了严格的标准和依赖管理,但是使用麻烦
  • Gradle:提供开箱即用的约定即约定大于配置,并且也可以灵活的改变
                     支持依赖管理,也支持传递依赖,通过Maven或者Ivy仓库(当然你也可以手动的下载依赖JAR包,当需要迁移到Gradle的时候特别有用)

1.1.Build Files in Groovy

  •  XML:适合机器阅读,人读很疼苦;方便表达嵌套关系,不利于描述程序流程,数据访问;构建工具选用XML是错误的。
  • Groovy:Gradle选用Groovy,一种基于JVM的动态语言;每个Gradle构建文件都是一个可执行的Groovy脚本;
    基于Groovy的Gradle允许你编写通用的任务;但是由于ANT中没有控制流所以很难实现,Maven中借助插件才能编写非标准的任务;

1.2. Domain-Specific Build Languages

DSL为构建软件的任务定义了构建的习语,和具体编程语言无关。通用的编码是后备存在的,优先使用构建习语,然后才是编码。
遇到DSL没有定义的构建任务,可以通过插件来扩展;例如,标准的Gradle定义了java的编译和打War包,但是没有发布到基于云的QA(测试)服务器的任务。
扩展Gradle的DSL通常更好于在构建文件中编码。

1.3. Getting Started

  • 下载最新版 http://gradle.org/downloads.html 

  • 解压

  • 添加环境变量GRADLE_HOME, 指向上面的路径 (可选)

  • 添加环境变量到path中$GRADLE_HOME/bin


1.4. The Hello World Build File

task helloWorld << {
  println ‘hello, world‘
}

$ gradle -q helloWorld



task hello << {
  print ‘hello, ‘
}

task world(dependsOn: hello) << {
  println ‘world‘
}

$ gradle -q world


1.5. Building a Java Program

apply plugin: ‘java‘
 
$ gradle build

Chapter 2. Gradle Tasks

在Gradle构建文件中,构建活动的单位是任务(Task),任务是一组Gradle执行的指令。

2.1. Declaring a Task

Declaring a task by name only

task hello

2.2. Task Action

task hello << {
  println ‘hello, world‘
}
在Groovy中 << 会被重载出不同的意义;在本例中,<< 意思是将代码块赋值给任务的动作列表,等价于doLast()方法;

Appending a task’s actions one at a time

task hello

hello << {
  print ‘hello, ‘
}

hello << {
  println ‘world‘
}


Tasks are not one-off declarations of build activity, but are first-class objects in the Gradle programming environment. 
构建活动的任务虽然不是一次性声明的,但是在Gradle 环境中是first-class(第一出现?头等重要?)对象;

2.3. Task Configuration

任务配置和任务动作定义

task initializeDatabase
initializeDatabase << { println ‘connect to database‘ }
initializeDatabase << { println ‘update database schema‘ }
initializeDatabase { println ‘configuring database connection‘ }
输出
$ gradle -b scratch.gradle initializeDatabase
configuring database connection
:initializeDatabase
connect to database
update database schema

initializeDatabase { println ‘configuring database connection‘ }称为配置块(和Action相比少了<<),采用了闭包的方式实现,闭包函数像一个对象一样可以被作为参数传递或者赋值到变量上,然后被执行。

Gradle执行过程分为三个阶段:初始化--配置--执行
执行:任务按照依赖关系顺序的执行
配置:被装配到内部对象模型的任务在此阶段会被执行
初始化:确定构建活动中参与的项目,多个项目构建中使用;

配置模块用来设置任务运行过程中需要用到的变量和数据结构。


2.4. Tasks Are Objects

在Gradle中任务就是对象;所有的任务都是继承自DefaultTask,类似java中的Object;DefaultTask不做任务实质性工作,但是包含Gradle项目构建模型中所要求的功能接口;

2.4.1. DefaultTask中的方法

dependsOn(task)

Different ways of calling the dependsOn method

// Declare that world depends on hello
// Preserves any previously defined dependencies as well
task loadTestData {
  dependsOn createSchema
}

// An alternate way to express the same dependency
task loadTestData {
  dependsOn << createSchema
}

// Do the same using single quotes (which are usually optional)
task loadTestData {
  dependsOn ‘createSchema‘
}

// Explicitly call the method on the task object
task loadTestData
loadTestData.dependsOn createSchema

// A shortcut for declaring dependencies
task loadTestData(dependsOn: createSchema)

Different ways of calling the dependsOn method for multiple dependencies

// Declare dependencies one at a time
task loadTestData {
  dependsOn << compileTestClasses
  dependsOn << createSchema
}

// Pass dependencies as a variable-length list
task world {
  dependsOn compileTestClasses, createSchema
}

// Explicitly call the method on the task object
task world
world.dependsOn compileTestClasses, createSchema

// A shortcut for dependencies only
// Note the Groovy list syntax
task world(dependsOn: [ compileTestClasses, createSchema ])

doFirst(closure)

Calling the doFirst method on the task object

task setupDatabaseTests << {
  // This is the task‘s existing action
  println ‘load test data‘
}

setupDatabaseTests.doFirst {
  println ‘create schema‘
}


Calling the doFirst method inside the task’s configuration block

task setupDatabaseTests << {
  println ‘load test data‘
}

setupDatabaseTests {
  doFirst {
    println ‘create schema‘
  }
}


Repeated calls to doFirst are cumulative

task setupDatabaseTests << {
  println ‘load test data‘
}

setupDatabaseTests.doFirst {
  println ‘create database schema‘
}

setupDatabaseTests.doFirst {
  println ‘drop database schema‘
}


Repeated calls to doFirst, refactored

// Initial task definition (maybe not easily editable)
task setupDatabaseTests << {
  println ‘load test data‘
}

// Our changes to the task (in a place we can edit them)
setupDatabaseTests {
  doFirst {
    println ‘create database schema‘
  }
  doFirst {
    println ‘drop database schema‘
  }
}

doLast(closure)



onlyIf(closure)

用以判定任务是否被执行,返回True执行任务,否则不执行;
在Groovy中闭包最后的语句就是返回值;

A build file making use of the onlyIf method.

task createSchema << {
  println ‘create database schema‘
}

task loadTestData(dependsOn: createSchema) << {
  println ‘load test data‘
}

loadTestData.onlyIf {
  System.properties[‘load.data‘] == ‘true‘
}

两种不同的调用方式,注意不同的结果

$ build loadTestData

create database schema
:loadTestData SKIPPED

$ gradle -Dload.data=true loadTestData
:createSchema
create database schema
:loadTestData
load test data
$


2.4.2. DefaultTask中的属性

didWork

boolean类型的属性标识任务是否执行完毕;

编译成功发送邮件

apply plugin: ‘java‘

task emailMe(dependsOn: compileJava) << {
  if(tasks.compileJava.didWork) {
    println ‘SEND EMAIL ANNOUNCING SUCCESS‘
  }
}

enabled

boolean类型的属性标识任务是否可以被执行;

设置任务不可用

task templates << {
  println ‘process email templates‘
}

task sendEmails(dependsOn: templates) << {
  println ‘send emails‘
}

sendEmails.enabled = false

path

字符串属性标识任务的路径;默认情况路径是冒号加上任务名;

A single-level build file that echoes its only task’s path

task echoMyPath << {
  println "THIS TASK‘S PATH IS ${path}"
}

冒号表示任务在构建文件中是占据是顶级层次结构;如果任务存在于一个叫做subProject的嵌套构建环境中,那么路径就为:subProject:echoMyPath;

logger

记录Gradle内部logger对象;org.slf4j.Logger的实现类;
日志的级别包括:
DEBUG INFO LIFECYCLE WARN QUIET ERROR

logging

用以设置日志的级别

description

设置任务的描述信息

 设置任务动作的同时设置任务描述

task helloWorld(description: ‘Says hello to the world‘) << {
  println ‘hello, world‘
}

两种不同的方式分开设置任务动作和描述

task helloWorld << {
  println ‘hello, world‘
}

helloWorld {
  description = ‘Says hello to the world‘
}

// Another way to do it
helloWorld.description = ‘Says hello to the world‘

temporaryDir

返回File对象指向构建文件的临时目录,在此可以存放一些临时文件;


2.4.3. Dynamic Properties

Task不仅有固定的属性,用户还可以自定义属性

任务的动态属性

task copyFiles {
  // Find files from wherever, copy them
  // (then hardcode a list of files for illustration)
  fileManifest = [ ‘data.csv‘, ‘config.json‘ ]
}

task createArtifact(dependsOn: copyFiles) << {
  println "FILES IN MANIFEST: ${copyFiles.fileManifest}"
}

The output of the above build file

$ gradle -b dynamic.gradle createArtifact
 FILES IN MANIFEST: [data.csv, config.json]
$

 > No such property: fileManifest for class: org.gradle.api.DefaultTask_Decorated



2.5. Task Types

Copy

每个任务都有一个类型,除了DefaultTask外,任务的类型有拷贝,归档,执行程序等,这些类型都是继承自DefaultTask的子类。

拷贝任务

task copyFiles(type: Copy) {
  from ‘resources‘
  into ‘target‘
  include ‘**/*.xml‘, ‘**/*.txt‘, ‘**/*.properties‘
}

Jar

根据源文件生成jar文件

JavaExec

运行java类的main方法;


2.6. Custom Task Types

有很多中创建自定义任务的方式,以下是常见的两种:

 Custom Tasks Types in the Build File


 Custom Tasks in the Source Tree


2.7. Where Do Tasks Come From?

Gradle的核心策略是提供高扩展性和低复杂性的构建框架;它提供了丰富的可扩展的任务功能,这些任务的代码对你来说是不可见的,由Gradle DSL来调用,而不是通过Groovy代码;

2.8. 结论

Building and Testing with Gradle

标签:gradle

原文地址:http://blog.csdn.net/easion_zms/article/details/46445031

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!