Gradle系列(二)-使用Gradle构建项目

上一篇文章中简单介绍了一下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构建项目_第5张图片
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'
}

总结

  1. 简单体验了下Gradle,感受到了其灵活和高度可定制,可折腾性不错。
  2. task和plugin是两个重要的东东。
  3. Wrapper好用。

你可能感兴趣的:(Gradle系列(二)-使用Gradle构建项目)