Gradle学习(十一)——构建脚本基础知识

原创 2018年01月03日 16:26:22

转载请注明出处:http://blog.csdn.net/lastsweetop/article/details/78962619

项目和任务

Gradle的所有都是基于两个基础概念:项目和任务

每个Gradle构建是由一个或者多个项目构成的,项目表示什么取决于你用Gradle做什么。比如,项目可以表示jar库或者web程序。它也可以表示由其他项目生产的jar包后打包成的发布zip包。一个项目不一定非要表示构建什么。它也可以表示做什么,比如把你的app发布到脚手架或者生产环境。讲到这里,你可能有点迷糊,但是不要担心,Gradle对按惯例构建的支持给出了项目是什么更明确的定义。

每个项目是由一个和多个任务构成的。任务表示构建运行的工作原件。它可以是编译classes,创建jar,生成javadoc,也可以是发布archives到仓库中。

我们本章内容都是同一个项目下的一些简单的任务操作,多项目交互的要到后面的章节体现。

Hello World

运行gradle命令时,Gralde回去查找当前目录下的build.gradle文件,这个文件就可以叫做构建脚本,虽然看起来更像是构建配置脚本。构建脚本中定义了一个项目和项目的一些任务。

build.gradle的内容如下:

task hello {
    doLast {
        println 'Hello World'
    }
}

然后在当前目录执行gradle -q hello命令,结果如下:

± % gradle -q hello                                                       
Hello World

让我们来看看发生了什么,首先构建脚本定义了一个叫hello的任务,并且添加了一个action。当你运行gradle -q hello的时候,Gradle就会执行hello任务,然后执行你提供的action。这个action只是一个包含了简单的groovy代码的closure。

构建脚本即code

构建脚本其实就是groovy代码,通过强力的脚本语言groovy让构建脚本更加强力,例如:

task upper {
    doLast {
        def str = 'sWeeTop'
        println 'Original:' + str
        println 'Upper Case:'+str.toUpperCase()
    }
}

然后执行upper任务:

± % gradle -q upper                                                       
Original:sWeeTop
Upper Case:SWEETOP

再来一个:

task count {
    doLast {
        4.times { println it}
    }
}

然后执行count任务:

± % gradle -q count                                                       
0
1
2
3

任务依赖

我们在命令行那张也涉及了一点任务依赖的例子,我们现在再来讲解一下,例子如下:

task hello {
    doLast {
        println 'Hello World'
    }
}
task intro(dependsOn:hello) {
    doLast {
        println "I'm Gradle"
    }
}

然后执行intro任务:

± % gradle intro -q                                                       
Hello World
I'm Gradle

所依赖的任务还可以是预先未定义的,例子如下:

task taskX(dependsOn: 'taskY') {
    doLast {
        println 'taskX'
    }
}

task taskY() {
    doLast {
        println 'taskY'
    }
}

然后执行taskX任务:

± % gradle taskX -q                                                       
taskY
taskX

依赖于taskY的任务taskX却比taskY先定义,这个特性对多任务构建来说很重要。

还有一点要注意就是,采取惰性依赖你就无法使用所依赖任务的快捷符号了

动态任务

强力的Groovy各种66666,比如你可以定义动态的任务:

4.times { number ->
    task "task$number" {
        doLast {
            println "I'm task number $number"
        }
    }
}

然后执行task2任务:

± % gradle task2 -q                                                       
I'm task number 2

操作已存在的任务

一旦任务被创建之后,你就可以通过api直接访问了,比如你可以动态的给一个任务增加点依赖,ant可以做不到这点,示例:

4.times { number ->
    task "task$number" {
        doLast {
            println "I'm task number $number"
        }
    }
}

task0.dependsOn task2,task3

然后我们只想task0任务:

± % gradle task0 -q                                                       
I'm task number 2
I'm task number 3
I'm task number 0

或者为已经存在的任务增加点行为:

task hello {
    doLast {
        println 'Hello World'
    }
}
hello.doFirst {
    println 'Hello Dong'
}
hello.doLast {
    println 'Hello Nan'
}
hello {
    doLast {
        println 'Hello Bei'
    }
}

然后执行hello任务:

± % gradle hello -q                                                       
Hello Dong
Hello World
Hello Nan
Hello Bei

doFirstdoLast能被多次执行,他们可以在任务的开始和结尾增加action,任务执行的时候,action列表就会依次执行。

快捷符号

有个非常方便的符号可以访问已存在的任务,在构建脚本中的每个任务都有这些属性:

task hello {
    doLast {
        println 'Hello World'
    }
}

hello.doLast {
    println "Greeting from the $hello.name task"
}

然后执行hello任务:

± % gradle hello -q                                                      
Hello World
Greeting from the hello task

这样可以写出更加易读性的代码,特别是用那些插件提供的任务,比如compile任务

扩展任务属性

你可以为任务增加自己的属性,要增加myProperty属性你给ext.myProperty设置一个初始值,然后这个属性就和其他预先定义的属性一样被读取和设置。示例:

task myTask {
    ext.myProperty='init value'
}

task printTaskProperty {
    doLast {
        println myTask.myProperty
    }
}

然后执行printTaskProperty任务

± % gradle printTaskProperty -q                                           
init value

使用ant任务

ant任务是gradle的一等公民,gradle把通过把ant任务完全交托给groovy实现了卓越的集成。在groovy这里是由奇妙的AntBuilder提供相关功能。在Gradle里使用ant任务就像直接在build.xml里的任务一样简单而又强力。下面的例子演示了如何执行ant任务和访问ant属性:

task loadFile {
    doLast {
        def files = file('../unpublished').listFiles().sort()
        files.each { File file ->
            if (file.isFile()) {
                ant.loadfile(srcFile: file,property:file.name)
                println "  ***$file.name***  "
                println ant.properties[file.name]
            }
        }
    }
}

然后执行loadFile任务:

± % gradle loadFile -q                                                    
  ***build.gradle***  
apply plugin: 'java'

archivesBaseName='hello'
  ***settings.gradle***  
version = 1.0

使用方法

gralde在组织构建逻辑时可以进行分级扩展,组织构架逻辑的第一级就是提取方法:

task loadFile {
    doLast {
        fileListEachAction('../unpublished') { File file ->
            ant.loadfile(srcFile: file, property: file.name)
            println "  ***$file.name***  "
            println ant.properties[file.name]
        }
    }
}

task checkSum {
    doLast {
        fileListEachAction('../unpublished') { File file ->
            ant.checksum(file: file, property: "cs_$file.name")
            println "$file.name checksum is ${ant.properties["cs_$file.name"]}"
        }
    }
}

def fileListEachAction(String path, Closure closure) {
    def files = file(path).listFiles().sort()
    files.each { File file ->
        if (file.isFile()) {
            closure(file)
        }
    }
}

然后执行checkSum任务:

± % gradle checkSum -q                                                    
build.gradle checksum is 193e5061bf3681c0434d6f4d937f1fc3
settings.gradle checksum is 0cba3f2c2582e03de4dc86f1d495a39b

后面还会讲到,这样的方法在多项目构建中也可以跨项目调用。

默认任务

Gradle可以定义一个或者多个默认任务,当没有特别指定具体任务时,默认任务就会执行

defaultTasks 'clean','run'

task clean {
    doLast {
        println "task $it is running"
    }
}

task run {
    doLast {
        println "task $it is runing"
    }
}

执行默认任务:

± % gradle -q                                                             
task task ':clean' is running
task task ':run' is runing

相当于运行了gralde -q clean run,在多项目构建中,每个子项目都可以设置自己的默认任务,当没有子项目的默认任务被指定那么就会执行root项目的默认任务

通过DAG配置Gradle

Gradle有配置阶段和运行阶段,在配置阶段之后,Gradle就会知道所以需要执行的任务,Gradle提供了hook可以让你使用这些信息,有一个用例就是你需要确认release任务是否在执行的任务之中,在这个基础上你可以设置不同的变量。

下面的例子会演示contribution任务和release任务下会有不同的version值:

task distribution {
    doLast {
        println "Current Version is $version"
    }
}

task release(dependsOn: distribution) {
    doLast {
        println 'We release now'
    }
}

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.hasTask(release)) {
        version = '1.0.0'
    } else {
        version = '1.0.0-SNAPSHOT'
    }
}

执行distribution任务:

± % gradle distribution -q                                                
Current Version is 1.0.0-SNAPSHOT

执行release任务:

± % gradle release -q                                                     
Current Version is 1.0.0
We release now

最重要的是whenReady会影响release任务是在release任务执行之前,即使release任务不是该次构建的主要任务。

版权声明:本文为博主原创文章,未经博主允许不得转载。

SQL SERVER 基础篇(一):知识点、SQL语句学习及详细总结

SQL SERVER 基础篇,详细总结学习sql语句和知识点,适合入门
  • ITermeng
  • ITermeng
  • 2016年12月09日 07:48
  • 2864

【Unity3D】基础知识学习笔记

Unity3D基础知识学习笔记 1、基础知识: 标题栏 菜单栏 工具栏:变换工具、gizmos切换、播放控件、层列表、布局列表 功能窗口 2、资源及资源类型:在project里面能够create的资...
  • woaini454186694
  • woaini454186694
  • 2016年05月25日 22:53
  • 4607

计算机网络基础知识学习资料

1.1.1 什么是计算机网络 计算机网络,是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和...
  • u014312890
  • u014312890
  • 2014年03月29日 11:31
  • 2588

Gradle学习基础(3):build脚本基础知识

本章介绍如何新建一个build.gradle 1.Project和Task 在Gradle中,所有内容都是基于这两个概念:Projects和Tasks。      每个gradle的构建是由一个或...
  • huachao1001
  • huachao1001
  • 2016年01月20日 14:25
  • 789

Gradle详解-脚本基础知识

Gradle- 构建脚本基础知识
  • huyuchaoheaven
  • huyuchaoheaven
  • 2016年06月22日 12:04
  • 1615

Linux——学习shell脚本之前的基础知识

日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员。目前很多单位在招聘linux系统管理员时,shell脚本的编写是必考的项目。有的单位...
  • u012627502
  • u012627502
  • 2015年01月05日 11:40
  • 542

C#基础知识(十一)——泛型集合、文件管理、多态、接口

一、泛型集合: List是泛型集合,就是为了专门处理某种类型。ArrayList对应的是List。在尖括号中写什么类型,这个集合就变成了什么类型的集合。 例子: //随机往这个List集合中 添加十个...
  • sz15732624895
  • sz15732624895
  • 2016年08月21日 21:02
  • 619

【二】Gradle 基础知识学习笔记

一、Groovy 语法 1. 定义变量及函数: 2. 列表及遍历 3. 类定义(跟java类似) 4. 闭包设置代理对象 二、 Gradle Tasks 1. 定义Task 2. Task之间依赖关系...
  • yk3372
  • yk3372
  • 2016年11月05日 20:45
  • 484

SHELL脚本的基础知识2——使用结构化命令

结构化命令:允许脚本根据变量值的条件或者其他命令的结果跳过一些命令或者循环执行这些命令 1、使用if_then语句 if command then      commands fi ...
  • xinying0424
  • xinying0424
  • 2012年10月12日 17:25
  • 274

SHELL脚本的基础知识3——更多结构化命令

for,while,until 1、for命令 for var in list do    commands done    在参数list中提供一系列用于迭代的值。 (1)读...
  • xinying0424
  • xinying0424
  • 2012年10月12日 17:24
  • 329
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Gradle学习(十一)——构建脚本基础知识
举报原因:
原因补充:

(最多只允许输入30个字)