【Gradle】
groovy脚本 , JDK6+
环境变量 PATH: %GRADLE_HOME%/bin
属性文件 ( gradle.properties ) 配置初始化属性
构建脚本 ( build.gradle ) 指定一个项目和它的任务 , 属性 , 仓库 , 依赖
设置文件 ( settings.gradle ) 构建多项目必选 , 描述哪些项目参与构建
每一个Gradle构建都是由一个或多个project构成,
每一个project都是由一个或多个tasks构成,
每个task的实质其实是一些更加细化的构建(譬如编译class、创建jar文件等)
三种关联对象:
Gradle对象: 构建初始化时创建 , 整个构建过程中只有一个 , 一般默认。
Project对象: 每个build.gradle转换成一个Project对象。
Settings对象: settings.gradle转换成一个Settings对象。
一个项目构建流程:
1 , 创建一个Settings实例 , 读取settings.gradle配置初始化。
2 , 通过Settings实例的配置创建项目层级结构的Project实例。
3 , 通过各个Project实例去执行Project对应的build.gradle脚本。
Build生命周期:
1 , 初始化: 创建Settings实例和Project实例 , 实质是执行settings.gradle
2 , 配置: 通过有向图建立整个构建的project和task的依赖关系 , 实质是执行参与构建的build.gradle
3 , 执行: 指定执行task任务的最终构建
【gradle命令】
gradle -----默认构建当前目录下的build.gradle
-b 指定构建文件,settings.gradle不会生效
-p 指定构建目录
gradle projects -----列出所有子项目
gradle tasks -----列出项目的所有任务
gradle task1 task2 -----执行指定任务
-x task1 task2 -----排除任务
–continue -----只要有任务失败默认中断执行,使用–continue不中断执行,然后发现所有失败原因。
gradle dependencies -----列出项目的所有依赖
gradle properties -----列出项目的所有属性
gradle build -----执行项目构建生成jar , 包括测试 , build/libs
gradle assemble -----执行项目构建 , 不执行测试
gradle compileJava -----编译代码
gradle compileTestJava
gradle test -----执行所有测试用例 , build/reports
gradle check -----执行代码检查
gradle distZip/distTar -----打包二进制文件
gradle jar -----打包jar , build/libs
gradle war -----打包Web应用
gradle appStart -----运行Web应用
gradle appStop -----终止Web应用
gradle clean -----清理build输出文件
【插件】2类插件
Gradle的核心只是一个框架,构建由插件支持
脚本插件,配置构建
apply from: 'xx.gradle'
二进制插件
apply plugin: 'java'
是实现了Plugin接口的类,采用编程方式来控制构建,
如Java插件用来构建Java工程,Android插件用来构建打包Android工程,
通过gradle tasks命令来列出项目和插件的所有任务,如build、assemble
一个Java项目会有许多外部依赖JAR包,通过引入仓库提取依赖,如repositories、dependencies
Java插件加入的是常规性的任务,可以另外定制任务,如设置任务属性、在任务中加入行为、改变任务的依赖、完全重写一个任务等,
使用gradle properties命令列出项目的所有属性
可以向构建脚本中加入插件的类路径然后再应用插件和使用插件的任务
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:0.4.1"
}
}
apply plugin: "com.jfrog.bintray"
【脚本执行】
Gradle在构建脚本中定义Gradle、Project、Script对象
-----加载一个gradle文件
apply from: rootProject.getRootDir().getAbsolutePath() + "/common.gradle"
-----使用ext定义属性
ext {
springVersion = "3.1.0.RELEASE"
}
sourceSets.all {
ext.purpose = null
}
sourceSets {
main {
purpose = "production"
}
test {
purpose = "test"
}
}
task printProperties << {
println springVersion
sourceSets.matching { it.purpose == "production" }.each { println it.name}
}
-----文件操作
File configFile = file('src/config.xml')
FileCollection collection = files('src/file1.txt',new File('src/file2.txt'),['src/file3.txt', 'src/file4.txt'])
File srcDir= file('srcDir')
FileCollection collection = files { srcDir.listFiles() }
collection.each {File file ->println file}----- 遍历
collection.collect { relativePath(it) }.sort().each { println it }
collection.findAll {it.name.endsWith('.zip')}.collect { zipTree(it) }
def union = collection + files('src/file3.txt') ----- 增加和减少集合
def different = collection - files('src/file3.txt')
----- 转换文件集合为其他类型
Set set = collection.files
Set set = collection as Set
List list = collection as List
String path = collection.asPath
File file = collection.singleFile
File file = collection as File
-----创建文件树,遍历、合并类似
FileTree tree = fileTree('srcDir')
FileTree zip = zipTree('xx.zip')
FileTree tar = tarTree('xx.tar')
tree.include '**/*.java'
tree.exclude '**/Abstract*'
tree = fileTree('srcDir').include('**/*.java')
tree = fileTree(srcDir) {include '**/*.java'} -----使用闭合创建
tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**') -----使用map创建
FileTree filtered = tree.matching {include 'org/gradle/api/**'} -----过滤文件树
FileTree sum = tree + fileTree(dir: 'src/test') -----合并
tree.each {File file -> println file} ----- 遍历
tree.visit {element ->println "$element.relativePath => $element.file"}
-----文件复制
task copy1(type: Copy) {
form "source" -----复制目录或文件
from copy2 -----复制任务输出的文件
into 'dest'
include '**/*.html'
exclude { details -> details.file.name.endsWith('.html') }
}
-----同步任务,当执行时会复制源文件到目标目录,然后从目标目录删除所有非复制文件
task libs(type: Sync) {
from configurations.runtime
into "$buildDir/libs"
}
-----归档文件Zip、Tar、Jar、War、Ear
task zip(type: Zip) {
from 'src/dist'
into('libs') {
from configurations.runtime
}
}
【引入仓库】 3种仓库类型
仓库就是依赖文件的集合服务器,用来提取或者放置依赖,如提取依赖jar包
repositories {
maven { -----将Maven仓库加入构建
url "http:-----maven.petrikainulainen.net/repo"
}
-----mavenCentral()
ivy { -----将Ivy仓库加入构建
url "http:-----ivy.petrikainulainen.net/repo"
-----url "../ivy-repo"
}
flatDir { -----将Flat Directory仓库加入构建 , 系统将在lib目录下搜索依赖
dirs 'libA', 'libB'
}
}
将Maven仓库加入构建 , Gradle提供三种“别名”使用:
mavenCentral() , 表示依赖是从Central Maven 2 仓库中获取的。
mavenLocal() , 表示依赖是从本地的Maven仓库中获取的。
jcenter() , 表示依赖是从Bintary's JCenter Maven 仓库中获取的。
【依赖配置】
compile 编译+运行所有代码必须
runtime 运行所有代码必须
testCompile 编译+运行测试代码必须
testRuntime 运行测试代码必须
archives 包含项目生成文件 ( 如Jar文件 )
default 包含运行时必须的依赖
外部依赖-分组 , 名称 , 版本
dependencies {
compile 'log4j:log4j:1.2.17'
compile group: 'log4j', name: 'log4j', version: '1.2.17'
compile (
[group: 'foo', name: 'foo', version: '0.1'],
[group: 'bar', name: 'bar', version: '0.1']
)
}
项目依赖-依赖传递-构建所有依赖项目
-----项目B的编译需要项目project1
compile project(':project1';)
【发布jar】
-----集成依赖
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile 'log4j:log4j:1.2.17'
testCompile 'junit:junit:4.11'
}
jar {
-----把所有依赖都打包到Jar文件中
from { configurations.compile.collect { it.isDirectory() ? it: zipTree(it) } }
-----设置Main-Class属性 , 指定程序入口点
manifest {
attributes 'Main-Class': 'net.petrikainulainen.gradle.HelloWorld'
}
}
【发布二进制版本】
-----依赖不集成 , 创建系统启动脚本 , 许可证
apply plugin: 'java'
apply plugin: 'application'
repositories {
mavenCentral()
}
dependencies {
compile 'log4j:log4j:1.2.17'
}
mainClassName = 'net.petrikainulainen.gradle.HelloWorld'
-----将许可证文件加入到二进制发布文件中
task copyLicense {
outputs.file new File("$buildDir/LICENSE")
doLast {
copy {
from "LICENSE"
into "$buildDir"
}
}
}
applicationDistribution.from(copyLicense) {
into ""
}
【发布Web应用】
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'org.akhikhl.gretty'
-----使用Gretty运行Web应用
buildscript {
-----使用Bintray的JCenter Maven仓库配置构建脚本 , 进行依赖解析
repositories {
jcenter()
}
-----将Gretty插件的依赖加入到构建脚本的classpath中
dependencies {
classpath 'org.akhikhl.gretty:gretty:+'
}
}
-----配置Gretty
gretty {
port = 8080
contextPath = '/'
servletContainer = 'jetty9'
}
【多项目构建】
settings.gradle
rootProject.name = 'projectA'
include ':project1'
include ':project2'
project(':project1').projectDir = "$rootDir/project1" as File
project(':project2').projectDir = "$rootDir/project2" as File
build.gradle
-----所有项目通用配置
allprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
}
-----子项目通用配置
subprojects {
}
-----单项目配置
project (':project1') {
}
【发布artifacts】
apply plugin: 'maven'
uploadArchives {
repositories {
-----发布到Maven库
mavenDeployer {
repository(url: "file:-----localhost/tmp/myRepo/")
}
-----发布到本地目录
flatDir {
dirs 'repos'
}
}
}
【任务执行】
-----1、settings.gradle
println 'excute settings.gradle'
-----2、build.gradle
println 'excute build.gradle' -----2.1
-----任务在脚本初始化时执行,没有加<<则闭包在task函数返回前会执行
task task0 {
println 'task0' -----2.2
}
task task1 {
doFirst {
println 'task1 doFirst' -----2.4
}
doLast {
println 'task1 doLast' -----2.5
}
println 'task1' -----2.3
}
task task2 << { -----doLast写法
println 'task2 <<' -----2.7
}
task2.doFirst {
println 'task2 doFirst' -----2.6
}
task task3 << {
println 'task3 <<'
}
task3 << {
println "task3 <<"
}
输出
> gradle task1 task2
excute settings.gradle
excute build.gradle
task0
task1
:task1
task1 doFirst
task1 doLast
:task2
task2 doFirst
task2 <<
-----默认任务
defaultTasks 'task0'
-----任务依赖
定义任务task时指明依赖、通过API为任务加入依赖
task task1(dependsOn: 'task2') << {
println 'task1'
}
-----task task2 ..
-----task task3 ..
task2.dependsOn task3
输出
> gradle task1
:task3
task3
:task2
task2
:task1
task1
-----动态task
4.times { counter ->
task "task$counter" << {
println "task number $counter"
}
}
输出
> gradle task1
:task1
task number 1
【参考资料】
Gradle User Guide
https:-----docs.gradle.org/current/userguide/userguide.html
Gradle入门系列
http:-----blog.jobbole.com/71999/
Gradle脚本基础全攻略
http:-----blog.youkuaiyun.com/yanbober/article/details/49314255