Building and Testing with Gradle笔记2——Gradle Tasks
来源:互联网 发布:淘宝分享88元红包 编辑:程序博客网 时间:2024/06/08 11:45
声明一个Task
task hello
执行gradle tasks
输出当前Project中所有task
:tasks------------------------------------------------------------All tasks runnable from root project------------------------------------------------------------Build Setup tasks-----------------init - Initializes a new Gradle build. [incubating]wrapper - Generates Gradle wrapper files. [incubating]Help tasks----------components - Displays the components produced by root project 'gradle-test-2'. [incubating]dependencies - Displays all dependencies declared in root project 'gradle-test-2'.dependencyInsight - Displays the insight into a specific dependency in root project 'gradle-test-2'.help - Displays a help message.model - Displays the configuration model of root project 'gradle-test-2'. [incubating]projects - Displays the sub-projects of root project 'gradle-test-2'.properties - Displays the properties of root project 'gradle-test-2'.tasks - Displays the tasks runnable from root project 'gradle-test-2'.Other tasks-----------hello
Gradle每当开始执行一个Task,都会输出一个冒号加上该task的名字,如:tasks
。因此tasks也是一个task,正如输出所示。
添加Task要执行的操作
声明后的Task可以作为一个可编程的对象,使用左移操作符给其添加要执行的操作
task hellohello << { print 'hello, '}hello << { println 'world'}
配置Task
task initializeDatabaseinitializeDatabase << { println 'connect to database' }initializeDatabase << { println 'update database schema' }initializeDatabase { println 'configuring database connection' }
执行gradle -b scratch.gradle initializeDatabase
输出:
configuring database connection:initializeDatabaseconnect to databaseupdate database schema
首先,-b
选项可以执行gradle要执行的build文件。
其次,没有使用左移操作符的代码块是指定task的配置部分。在Gradle的声明周期的配置阶段执行,早于task的执行阶段。比配置阶段更早的是初始化阶段。
配置代码块同样可以追加,如下:
task initializeDatabaseinitializeDatabase << { println 'connect to database' }initializeDatabase << { println 'update database schema' }initializeDatabase { print 'configuring ' }initializeDatabase { println 'database connection' }
Task是对象
Task对象的默认类型是DefaultTask,Gradle中的所有Task都是派生自该类型。正如Java中的所有对象都派生自java.lang.Object
。
DefaultTask的方法
dependsOn(task)
// Declare that world depends on hello// Preserves any previously defined dependencies as welltask loadTestData { dependsOn createSchema}// An alternate way to express the same dependencytask loadTestData { dependsOn << createSchema}// Do the same using single quotes (which are usually optional)task loadTestData { dependsOn 'createSchema'}// Explicitly call the method on the task objecttask loadTestDataloadTestData.dependsOn createSchema// A shortcut for declaring dependenciestask loadTestData(dependsOn: createSchema)
如果一个Task有多个依赖,如下:
// Declare dependencies one at a timetask loadTestData { dependsOn << compileTestClasses dependsOn << createSchema}// Pass dependencies as a variable-length listtask world { dependsOn compileTestClasses, createSchema}// Explicitly call the method on the task objecttask worldworld.dependsOn compileTestClasses, createSchema// A shortcut for dependencies only// Note the Groovy list syntaxtask world(dependsOn: [ compileTestClasses, createSchema ])
doFirst(closure)
传递一个closure在指定Task执行之前执行,注意和Task配置区分。
task setupDatabaseTests << { // This is the task's existing action println 'load test data'}setupDatabaseTests.doFirst { println 'create schema'}
执行gradle setupDatabaseTests
输出,
:setupDatabaseTestscreate schemaload test data
当然,这个closure可以在Task配置块中指定:
task setupDatabaseTests << { println 'load test data'}setupDatabaseTests { doFirst { println 'create schema' }}
doFirst也可以追加closure:
task setupDatabaseTests << { println 'load test data'}setupDatabaseTests.doFirst { println 'create database schema'}setupDatabaseTests.doFirst { println 'drop database schema'}
输出如下:
:setupDatabaseTestsdrop database schemacreate database schemaload test data
doLast(closure)
示例如下:
task setupDatabaseTests << { println 'create database schema'}setupDatabaseTests.doLast { println 'load test data'}setupDatabaseTests.doLast { println 'update version table'}
本质上,<<
操作符等同于doLast方法。
onlyIf(closure)
在Task执行以前,进行判断,是否要执行该Task。
task createSchema << { println 'create database schema'}task loadTestData(dependsOn: createSchema) << { println 'load test data'}loadTestData.onlyIf { System.properties['load.data'] == 'true'}
直接执行build loadTestData
输出:
:createSchemacreate database schema:loadTestData SKIPPED
指定一个系统属性并执行gradle -Dload.data=true loadTestData
,输出:
:createSchemacreate database schema:loadTestDataload test data
DefaultTask的属性
didWork
判断一个Task是否执行成功
apply plugin: 'java'task emailMe(dependsOn: compileJava) << { if(tasks.compileJava.didWork) { println 'SEND EMAIL ANNOUNCING SUCCESS' }}
enabled
是否启用Task
task templates << { println 'process email templates'}task sendEmails(dependsOn: templates) << { println 'send emails'}sendEmails.enabled = false
执行gradle -b enabled.gradle sendEmails
,输出:
:templatesprocess email templates:sendEmails SKIPPED
path
task echoMyPath << { println "THIS TASK'S PATH IS ${path}"}
执行gradle -b path.gradle echoMyPath
,输出:
THIS TASK'S PATH IS :echoMyPath
这表示该Task位于顶层Project,如果是子项目subProject的Task,那么path应该是:subProject:echoMyPath
。
logger
Gradle内部的logger引用,看代码:
task logLevel << { def levels = ['DEBUG', 'INFO', 'LIFECYCLE', 'QUIET', 'WARN', 'ERROR'] levels.each { level -> logging.level = level def logMessage = "SETTING LogLevel=${level}" logger.error logMessage logger.error '-' * logMessage.size() logger.debug 'DEBUG ENABLED' logger.info 'INFO ENABLED' logger.lifecycle 'LIFECYCLE ENABLED' logger.warn 'WARN ENABLED' logger.quiet 'QUIET ENABLED' logger.error 'ERROR ENABLED' println 'THIS IS println OUTPUT' logger.error ' ' }}
总而言之,logger的级别优先级,从低到高。
logging
description
设置一个Task的描述信息:
task helloWorld(description: 'Says hello to the world') << { println 'hello, world'}
或者
task helloWorld << { println 'hello, world'}helloWorld { description = 'Says hello to the world'}
又或者:
task helloWorld << { println 'hello, world'}helloWorld.description = 'Says hello to the world'
temporaryDir
以File对象的形式返回属于当前build文件的一个临时目录
动态属性
每个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}"}
执行gradle -b dynamic.gradle createArtifact
,输出:
FILES IN MANIFEST: [data.csv, config.json]
Task类型
除了DefaultTask,还有一些用于复制,打包,执行程序的Task类型。声明一个Task类型就好像在面向对象编程中扩展一个类。
Copy
task copyFiles(type: Copy) { from 'resources' into 'target' include '**/*.xml', '**/*.txt', '**/*.properties'}
from,into,和include方法都是继承自Copy。
Jar
这是java插件中引入的一个Task,Jar用于将源码打包成一个jar文件。我们同样可以扩展这个Task。
apply plugin: 'java'task customJar(type: Jar) { manifest { attributes firstKey: 'firstValue', secondKey: 'secondValue' } archiveName = 'hello.jar' destinationDir = file("${buildDir}/jars") from sourceSets.main.classes}
jar包的清单文件属性可以轻易的使用Groovy的map字面量创建。file方法用于从字符串构造一个java.io.File对象。from方法是Jar从Copy继承而来。
JavaExec
该Task用于执行一个带有main方法的Java类
apply plugin: 'java'repositories { mavenCentral()}dependencies { runtime 'commons-codec:commons-codec:1.5'}task encode(type: JavaExec, dependsOn: classes) { main = 'org.gradle.example.commandline.MetaphoneEncoder' args = "The rain in Spain falls mainly in the plain".split().toList() classpath sourceSets.main.classesDir classpath configurations.runtime}
自定义Task类型
在build文件中创建自定义Task类型
task createDatabase(type: MySqlTask) { sql = 'CREATE DATABASE IF NOT EXISTS example'}task createUser(type: MySqlTask, dependsOn: createDatabase) { sql = "GRANT ALL PRIVILEGES ON example.* TO exampleuser@localhost IDENTIFIED BY 'passw0rd'"}task createTable(type: MySqlTask, dependsOn: createUser) { username = 'exampleuser' password = 'passw0rd' database = 'example' sql = 'CREATE TABLE IF NOT EXISTS users(id BIGINT PRIMARY KEY, username VARCHAR(100))'}class MySqlTask extends DefaultTask { def hostname = 'localhost' def port = 3306 def sql def database def username = 'root' def password = 'password' @TaskAction def runQuery() { def cmd if(database) { cmd = "mysql -u ${username} -p ${password} -h ${hostname} -P ${port} ${database} -e " } else { cmd = "mysql -u ${username} -p ${password} -h ${hostname} -P ${port} -e " } project.exec { commandLine = cmd.split().toList() + sql } }}
上面定义的每个Task都用于执行一条sql语句。
在源码树中创建自定义Task类型
如果自定的Task较为复杂,应该将它们保存为单独的Groovy文件。上面的例子还可以写成这样,将build文件中的class移到一个单独的文件中MySqlTask.groovy
,项目的结构如下:
|---build.gradle\---buildSrc \---src \---main \---groovy \---org \---gradle \---example \---task \---MySqlTask.groovy
- Building and Testing with Gradle笔记2——Gradle Tasks
- Building and Testing with Gradle笔记3——Ant and Gradle
- Building and Testing with Gradle笔记1——Hello,Gradle
- Building and Testing with Gradle
- Building Your Project with Gradle
- Building Your Project with Gradle
- 【Spring】Building Java Projects with Gradle
- Gradle笔记——关于Gradle 1.12
- Gradle Tips#1-tasks
- Gradle Tips#1-tasks
- Gradle Tips#1-tasks
- Android Studio(六)Building Your Project with Gradle
- Gradle笔记——Gradle的简介与安装
- Gradle笔记——Gradle的简介与安装
- Gradle笔记——Gradle的简介与安装
- Gradle笔记——Gradle的简介与安装
- Gradle笔记——Gradle的简介与安装
- Gradle——安装Gradle
- Java图形界面-Swing入门与布局管理
- 解决Android Studio的Instant Run导致的错误
- 借助Mathematica理解Voronoi图
- 判断当前脚本运行环境,是浏览器还是node
- MySQL高可用性分析
- Building and Testing with Gradle笔记2——Gradle Tasks
- 【转载】世界上最牛的编辑器: Vim 1 (原创动图演示所有例子!)
- hue sentry界面配置步骤
- 第93篇跳转关闭窗口开发(二)及php
- mysql入门
- 微信小程序初体验(上)
- new创建类对象与直接定义的区别
- 总结小篇
- 动态规划 基础题 数字三角