上一篇文章中简单介绍了一下Gradle,既然从扩展性、灵活性、性能方面都这么出色,那这次就动手尝试看看如何使用Gradle来构建项目。
Gradle安装
安装可参见官方文档Gradle Installation,todo推荐使用gradlew来管理项目,用过的人都说好,后面会介绍下gradlew的最佳实践。本机环境如下图:
初始化项目
> mkdir gradle_demo
> cd gradle_demo
> gradle init
如上图所示gradle可以支持cpp、grovvy、java、kotlin类型的项目构建,同时可以使用groovy和kotlin做为DSL,看起来还不错,看下初始化后的项目结构:
[站外图片上传中...(image-429164-1555228783031)]
目前新版的Gradle在执行初始化时会自动将gradle wrapper plugin应用于项目。介绍下期中的几个文件:
- build.gradle:当前项目的构建脚本(类似于maven的pom.xml)
- gradle-wrapper.jar:gradle wrapper可执行jar包
- gradle-wrapper.properties:gradle wapper配置文件
- gradlew:gradle wrapper unix-base系统下的可执行脚本
- gradlew.bat:gradle wrapper Windows系统下的可执行脚本
- settings.gradle:当前项目的配置文件
gradle init还可以将pom.xml"翻译"为Gradle项目,使用
-p pom.xml
创建任务
Gradle提供了丰富的API给我们使用基于Groovy或者Kotlin的DSL来创建和配置tasks,一个项目工程包含了一系列的Task,每个Task完成一些基本的操作,最后完成我们整个项目的构建。
Gradle给我们提供了一个方便我们构建项目的基本Task类型库,这里试一试其中的Copy Task。创建一个src目录,在其中添加一个myCopyFile.txt文件(内容为Hello World!),定义一个Copy任务如下:
build.gradle
task copy(
type: Copy,
group: "MyCopyGroup",
description: "Copy File Task"
) {
from "src"
into "dest"
}
执行Task,发现自动为我们创建了dest目录,并将myCopyFile.txt copy到了目标目录,Gradle正是通过这种强大的任务定义机制以及描述性丰富的DSL满足了我们各种定制需求,这点还是很不错的。(想想这个要在maven中实现麻烦多了)
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> ./gradlew copy 19-04-13 22:27
Downloading https://services.gradle.org/distributions/gradle-5.3.1-bin.zip
...................................................................................
BUILD SUCCESSFUL in 36s
1 actionable task: 1 executed
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> tree 19-04-13 22:28
.
├── build.gradle
├── dest
│ └── myCopyFile.txt
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── myCopyFile.txt
4 directories, 8 files
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> cat dest/myCopyFile.txt 19-04-13 22:31
Hello World!
应用插件
插件可以理解为一系列task的集合,Gradle提供了很丰富的基础插件,另外还有很多第三方插件,其中base
插件提供了大多数项目生命周期中都有的task。如下任务利用base插件和Zip打包我们的src目录:
build.gradle
plugins {
id "base"
}
task zip(
type: Zip,
group: "Archive",
description: "Archives src") {
from "src"
setArchiveName "gradle-demo-1.0.zip"
}
执行zip任务
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> ./gradlew zip 19-04-13 22:53
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> tree 19-04-13 22:53
.
├── build
│ └── distributions
│ └── gradle-demo-1.0.zip
├── build.gradle
├── dest
│ └── myCopyFile.txt
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── myCopyFile.txt
6 directories, 9 files
探索 & build scan
更多Gradle使用方法可以查看官方的CLI Interface,在项目中查询有哪些可用的task可使用gradlew task
,会列出我们自己定义的任务以及plugin引入的任务。
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> ./gradlew tasks 19-04-13 23:00
> Task :tasks
------------------------------------------------------------
Tasks runnable from root project
------------------------------------------------------------
Archive tasks
-------------
zip - Archives src
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
clean - Deletes the build directory.
Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'gradle_demo'.
components - Displays the components produced by root project 'gradle_demo'. [incubating]
dependencies - Displays all dependencies declared in root project 'gradle_demo'.
dependencyInsight - Displays the insight into a specific dependency in root project 'gradle_demo'.
dependentComponents - Displays the dependent components of components in root project 'gradle_demo'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'gradle_demo'. [incubating]
projects - Displays the sub-projects of root project 'gradle_demo'.
properties - Displays the properties of root project 'gradle_demo'.
tasks - Displays the tasks runnable from root project 'gradle_demo'.
Verification tasks
------------------
check - Runs all checks.
Rules
-----
Pattern: clean: Cleans the output files of a task.
Pattern: build: Assembles the artifacts of a configuration.
Pattern: upload: Assembles and uploads the artifacts belonging to a configuration.
To see all tasks and more detail, run gradlew tasks --all
To see more detail about a task, run gradlew help --task
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
查询项目设置以及默认的属性信息可使用gradlew properties
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> ./gradlew properties 19-04-13 23:04
> Task :properties
------------------------------------------------------------
Root project
------------------------------------------------------------
allprojects: [root project 'gradle_demo']
ant: org.gradle.api.internal.project.DefaultAntBuilder@2a1a50e0
antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@4d2d5ed3
archivesBaseName: gradle_demo
artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@46b8f540
asDynamicObject: DynamicObject for root project 'gradle_demo'
baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@35e7668d
buildDir: /Users/xiaobai/gradle_study/gradle_demo/build
buildFile: /Users/xiaobai/gradle_study/gradle_demo/build.gradle
……………………………… many properties
state: project state 'EXECUTED'
status: integration
subprojects: []
tasks: task set
version: unspecified
zip: task ':zip'
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
还有一个特别值得提的功能是Gradle为我们提供了一个丰富的,基于Web的分析工具build scan,通过使用--scan
的命令选项或在项目构建脚本中加入build scan插件,可以将我们的build scans结果发布到Gradle的服务上(也提供了企业级服务),并通一个生成的Web链接访问,这极大的方便了我们对构建过程的分析以及问题的排查。(对比当年maven构建除了问题,将整个错误日志贴出来问牛牛们,方便太多了)
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> ./gradlew zip --scan 19-04-13 22:58
BUILD SUCCESSFUL in 9s
1 actionable task: 1 up-to-date
Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service. Do you accept these terms? [yes, no] yes
Gradle Terms of Service accepted.
Publishing build scan...
https://gradle.com/s/ohwhkuety36oc
访问以上生成的build scan链接:https://gradle.com/s/ohwhkuety36oc
gradle wrapper
官方推荐的使用Gradle进行项目构建的方式是使用Gradle Wrapper(后文简称Wrapper),Wrapper是一个使用我们声明的一个gradle版本(如果不存在就预先下载)进行项目构建的脚本,使开发者们可以在自己本地没有安装Gradle的情况下进行项目构建等操作。以下为Wrapper的工作流:
好处:
- 统一构建项目的gradle的版本,避免版本不同导致的构建问题(gradle的版本相比maven非常多)
- 修改或升级gradle版本非常方便
为我们的项目添加Gradle Wrapper
如上文中我使用的版本在执行初始化时,自动引入了Wrapper。但是当我们在使用老版本或需要为没有添加Wrapper的项目添加Wrapper时,可使用gradle wrapper
为我们的项目添加Wrapper支持。生成的Wrapper文件如下:
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> tree gradle 19-04-13 23:06
gradle
└── wrapper
├── gradle-wrapper.jar
└── gradle-wrapper.properties
1 directory, 2 files
在实际开发中,为了让Wrapper对其他开发者也有效,需要将这个目录添加到版本控制中。gradle-wrapper.properties
文件中存放着Gradle的基本信息:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# 我们使用的Gradle远程地址以及版本
distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
# 文件校验码
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10
所有以上的属性都可以通过生成Wrapper时通过指定一下参数来设置:
--gradle-version:指定Gradle版本
--distribution-type:指定Gradle distribution的类型,有bin和all可选,指定bin时只会下载二进制文件;all还会下载源码
--gradle-distribution-url:指定Gradle distribution的URL地址,这个参数会覆盖以上的两个参数,在公司内网使用时会经常用到
--gradle-distribution-sha256-sum:下载的Gradle distribution校验码,为了安全起见,建议设置。
# 指定gradle distribution版本和类型
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> gradle wrapper --gradle-version 5.3.1 --distribution-type all
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
xiaobai:/Users/xiaobai/gradle_study/gradle_demo> cat gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# 远程地址的版本和类型和以上设置对应
distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
PS:在实际工程中还有一种指定版本和类型的方式是在构建脚本中配置,只需要执行gradle wrapper
就好
build.gradle
task wrapper(type: Wrapper){
gradleVersion = '5.3.1'
distributionType = 'bin'
}
总结
- 简单体验了下Gradle,感受到了其灵活和高度可定制,可折腾性不错。
- task和plugin是两个重要的东东。
- Wrapper好用。