From d4c81205ea96ead66ba4a27c5e7bdeb6e6857643 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 03:52:18 +0000 Subject: [PATCH 001/102] Updates installing_gradle/README.md Auto commit by GitBook Editor --- installing_gradle/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/installing_gradle/README.md b/installing_gradle/README.md index cbbba84..9a50552 100644 --- a/installing_gradle/README.md +++ b/installing_gradle/README.md @@ -1,8 +1,10 @@ # 安装 Gradle -* 先决条件 -* 下载 -* 解压缩 -* 环境变量 -* 运行并测试您的安装 -* JVM选项 +* 预备知识 +* 通过一个 Package Manager 安装 +* 手动安装 +* 确认是否安装成功 +* 下一步 + + + From a4e996176ffa85b74ff40c60e39816730841278e Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 03:52:47 +0000 Subject: [PATCH 002/102] Updates installing_gradle/README.md Auto commit by GitBook Editor From 3daacc5b5851f5f829ed185edb485109f5c85b2a Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 03:52:52 +0000 Subject: [PATCH 003/102] Updates installing_gradle/README.md Auto commit by GitBook Editor From ea66be7ea7707bb17729d308c177a7579d73d9eb Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 03:52:56 +0000 Subject: [PATCH 004/102] Updates installing_gradle/README.md Auto commit by GitBook Editor From 145e6176a3b2c929b48b100658ca968f7d37c962 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 03:57:46 +0000 Subject: [PATCH 005/102] Updates installing_gradle/README.md Auto commit by GitBook Editor --- installing_gradle/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/installing_gradle/README.md b/installing_gradle/README.md index 9a50552..5cb1b13 100644 --- a/installing_gradle/README.md +++ b/installing_gradle/README.md @@ -1,10 +1,12 @@ # 安装 Gradle * 预备知识 -* 通过一个 Package Manager 安装 +* 通过 Package Manager 安装 * 手动安装 * 确认是否安装成功 * 下一步 +不管是 Linux, macOS 还是 Windows 系统都可以安装 Gradle build tool. 这一章主要是描述通过 package manager \(SDKMAN!, Homebrew 或者 Scoop\) 来安装以及手动安装 Gradle. 推荐使用 [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:upgrading_wrapper) 来安装. +所有的 releases 以及校对请查看 [releases page](https://gradle.org/releases). From 5fdfce77cd50a03aeca6f035e7abb314db18b664 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 03:59:48 +0000 Subject: [PATCH 006/102] Updates installing_gradle/download.md Auto commit by GitBook Editor --- SUMMARY.md | 2 +- installing_gradle/download.md | 28 +++++++++++++--------------- installing_gradle/yu-bei-zhi-shi.md | 4 ++++ 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 installing_gradle/yu-bei-zhi-shi.md diff --git a/SUMMARY.md b/SUMMARY.md index 33c141b..7824f4f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -8,8 +8,8 @@ * [为什么用 Groovy?](overview/why_groovy.md) * [教程](tutorials/README.md) * [安装Gradle](installing_gradle/README.md) - * [准备阶段](installing_gradle/prerequisites.md) * [下载与安装](installing_gradle/download.md) + * [预备知识](installing_gradle/yu-bei-zhi-shi.md) * [JVM选项](installing_gradle/jvm_options.md) * [排除故障](troubleshooting/README.md) * [构建脚本基础](build_script_basics/README.md) diff --git a/installing_gradle/download.md b/installing_gradle/download.md index 95b87c9..25b1011 100644 --- a/installing_gradle/download.md +++ b/installing_gradle/download.md @@ -1,16 +1,15 @@ -### # 下载与安装 你可以从 [Gradle网站](http://www.gradle.org/downloads) 下载任意一个已经发布的版本 # 解压缩 -Gradle 发布的版本为 ****ZIP 格式. 所有文件包含: +Gradle 发布的版本为 _\*\*_ZIP 格式. 所有文件包含: * Gradle 的二进制文件. -* 用户指南 (HTML 和 PDF). +* 用户指南 \(HTML 和 PDF\). * DSL参考指南. -* API文档 (Javadoc和 Groovydoc). +* API文档 \(Javadoc和 Groovydoc\). * 扩展的例子,包括用户指南中引用的实例,以及一些更复杂的实例来帮助用户构建自己的build. * 二进制源码.此代码仅供参考. @@ -18,8 +17,8 @@ Gradle 发布的版本为 ****ZIP 格式. 所有文件包含: 然后我们需要设置环境变量 -1. 添加一个 **GRADLE_HOME** 环境变量来指明 Gradle 的安装路径 -2. 添加 **GRADLE_HOME/bin** 到您的 *PATH* 环境变量中. 通常, 这样已经足够运行Gradle了. +1. 添加一个 **GRADLE\_HOME** 环境变量来指明 Gradle 的安装路径 +2. 添加 **GRADLE\_HOME/bin** 到您的 _PATH_ 环境变量中. 通常, 这样已经足够运行Gradle了. **扩充教程** @@ -27,20 +26,19 @@ Gradle 发布的版本为 ****ZIP 格式. 所有文件包含: 假设您下载好的 Gradle 文件在 /Users/UFreedom/gradle 目录 - 1.vim ~/.bash_profile +``` +1.vim ~/.bash_profile - 2.添加下面内容: - export GRADLE_HOME = /Users/UFreedom/gradle - export export PATH=$PATH:$GRADLE_HOME/bin +2.添加下面内容: +export GRADLE_HOME = /Users/UFreedom/gradle +export export PATH=$PATH:$GRADLE_HOME/bin - 3.source ~/.brash_profile +3.source ~/.brash_profile +``` 实际配置中,您需要将上面的目录换成您的 Gradle 文件在系统中的目录. - - - # 运行并测试您的安装 -然后我们需要测试 Gradle 是否已经正确安装. 您可以通过在控制台输入 **gradle** 命令来运行Gradle. 通过 **gradle -v** 命令来检测Gradle是否已经正确安装. 如果正确安装,会输出Gradle版本信息以及本地的配置环境 ( groovy 和 JVM 版本等). 显示的版本信息应该与您所下载的 gradle 版本信息相匹配. +然后我们需要测试 Gradle 是否已经正确安装. 您可以通过在控制台输入 **gradle** 命令来运行Gradle. 通过 **gradle -v** 命令来检测Gradle是否已经正确安装. 如果正确安装,会输出Gradle版本信息以及本地的配置环境 \( groovy 和 JVM 版本等\). 显示的版本信息应该与您所下载的 gradle 版本信息相匹配. diff --git a/installing_gradle/yu-bei-zhi-shi.md b/installing_gradle/yu-bei-zhi-shi.md new file mode 100644 index 0000000..9a964e3 --- /dev/null +++ b/installing_gradle/yu-bei-zhi-shi.md @@ -0,0 +1,4 @@ +# 预备知识 + + + From 9371fc8e0b29a9481b97586fe9cb71914627b6a6 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:05:28 +0000 Subject: [PATCH 007/102] Updates installing_gradle/yu-bei-zhi-shi.md Auto commit by GitBook Editor --- SUMMARY.md | 2 +- installing_gradle/yu-bei-zhi-shi.md | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/SUMMARY.md b/SUMMARY.md index 7824f4f..6dea5db 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -8,9 +8,9 @@ * [为什么用 Groovy?](overview/why_groovy.md) * [教程](tutorials/README.md) * [安装Gradle](installing_gradle/README.md) - * [下载与安装](installing_gradle/download.md) * [预备知识](installing_gradle/yu-bei-zhi-shi.md) * [JVM选项](installing_gradle/jvm_options.md) + * [下载与安装](installing_gradle/download.md) * [排除故障](troubleshooting/README.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) diff --git a/installing_gradle/yu-bei-zhi-shi.md b/installing_gradle/yu-bei-zhi-shi.md index 9a964e3..5bb3b89 100644 --- a/installing_gradle/yu-bei-zhi-shi.md +++ b/installing_gradle/yu-bei-zhi-shi.md @@ -1,4 +1,17 @@ # 预备知识 +Gradle 可以在所有的主流操作系统上运行. 只需要安装 [Java JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 7 以及更高的版本. 用户可以通过运行 `java -version` 命令来查看Java JDK 的版本: + +``` +❯ java -version +java version "1.8.0_151" +Java(TM) SE Runtime Environment (build 1.8.0_151-b12) +Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) +``` + +Gradle 自带 Groovy library, 所以用户不需要安装 Groovy. 所有已经安装的 Groovy 都会被 Gradle 忽略. + +Gradle uses whatever JDK it finds in your path. Alternatively, you can set the`JAVA_HOME`environment variable to point to the installation directory of the desired JDK. + From 1ca0498e27ef77d3bc26bb5c7064114aa4780859 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:07:56 +0000 Subject: [PATCH 008/102] Updates installing_gradle/yu-bei-zhi-shi.md Auto commit by GitBook Editor --- installing_gradle/yu-bei-zhi-shi.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/installing_gradle/yu-bei-zhi-shi.md b/installing_gradle/yu-bei-zhi-shi.md index 5bb3b89..90c19a1 100644 --- a/installing_gradle/yu-bei-zhi-shi.md +++ b/installing_gradle/yu-bei-zhi-shi.md @@ -11,7 +11,5 @@ Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) Gradle 自带 Groovy library, 所以用户不需要安装 Groovy. 所有已经安装的 Groovy 都会被 Gradle 忽略. -Gradle uses whatever JDK it finds in your path. Alternatively, you can set the`JAVA_HOME`environment variable to point to the installation directory of the desired JDK. - - +Gradle 会直接使用你路径里默认的 JDK. 或者, 你可以设置环境变量`JAVA_HOME `来指定需要使用的 JDK. From a1a97a12bc36c46a48167441d5ef5336984e5b14 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:13:50 +0000 Subject: [PATCH 009/102] Updates installing_gradle/tong-guo-package-manager-an-zhuang.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../tong-guo-package-manager-an-zhuang.md | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 installing_gradle/tong-guo-package-manager-an-zhuang.md diff --git a/SUMMARY.md b/SUMMARY.md index 6dea5db..2449cc2 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -9,6 +9,7 @@ * [教程](tutorials/README.md) * [安装Gradle](installing_gradle/README.md) * [预备知识](installing_gradle/yu-bei-zhi-shi.md) + * [通过 Package Manager 安装](installing_gradle/tong-guo-package-manager-an-zhuang.md) * [JVM选项](installing_gradle/jvm_options.md) * [下载与安装](installing_gradle/download.md) * [排除故障](troubleshooting/README.md) diff --git a/installing_gradle/tong-guo-package-manager-an-zhuang.md b/installing_gradle/tong-guo-package-manager-an-zhuang.md new file mode 100644 index 0000000..d0ccca1 --- /dev/null +++ b/installing_gradle/tong-guo-package-manager-an-zhuang.md @@ -0,0 +1,34 @@ +# 通过 Package Manager 安装 + +[SDKMAN!](http://sdkman.io/) 是类 Unix 系统的一个软件开发工具管理器: + +``` +❯ sdk install gradle 4.6 +``` + +[Homebrew](http://brew.sh/) 是 MacOS 的 package manager: + +``` +❯ brew install gradle +``` + +[Scoop](http://scoop.sh/) 是 Windows 环境下的一个命令行安装工具\(基于 Homebrew\): + +``` +❯ scoop install gradle +``` + +[Chocolatey](https://chocolatey.org/) 是 Windows 的 package manager: + +``` +❯ choco install gradle +``` + +[MacPorts](https://www.macports.org/) 是一个 MacOS 的工具管理系统: + +``` +❯ sudo port install gradle +``` + + + From a15a71cb4b3a77ebe787ee3ab19444d4809e14d4 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:25:46 +0000 Subject: [PATCH 010/102] Updates installing_gradle/shou-dong-an-zhuang.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + installing_gradle/shou-dong-an-zhuang.md | 43 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 installing_gradle/shou-dong-an-zhuang.md diff --git a/SUMMARY.md b/SUMMARY.md index 2449cc2..9d9204e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -10,6 +10,7 @@ * [安装Gradle](installing_gradle/README.md) * [预备知识](installing_gradle/yu-bei-zhi-shi.md) * [通过 Package Manager 安装](installing_gradle/tong-guo-package-manager-an-zhuang.md) + * [手动安装](installing_gradle/shou-dong-an-zhuang.md) * [JVM选项](installing_gradle/jvm_options.md) * [下载与安装](installing_gradle/download.md) * [排除故障](troubleshooting/README.md) diff --git a/installing_gradle/shou-dong-an-zhuang.md b/installing_gradle/shou-dong-an-zhuang.md new file mode 100644 index 0000000..fe6097b --- /dev/null +++ b/installing_gradle/shou-dong-an-zhuang.md @@ -0,0 +1,43 @@ +# 手动安装 + +### Step 1. [下载](https://gradle.org/releases) 最新的 Gradle + +有 2 种 ZIP 文件: + +* Binary-only \(bin\) + +* Complete \(all\) 包含文件和源码 + +如果需要使用老版本的 Gradle, 请查看 [releases page](https://gradle.org/releases). + +### Step 2. 解压缩 + +#### Linux & MacOS + +在你指定的文件夹下解压 zip 文件, e.g.: + +``` +❯ mkdir /opt/gradle +❯ unzip -d /opt/gradle gradle-4.6-bin.zip +❯ ls /opt/gradle/gradle-4.6 +LICENSE NOTICE bin getting-started.html init.d lib media +``` + +#### Windows + +创建一个新的目录`C:\Gradle`. 解压 Zip 文件, 并将`gradle-4.6`文件夹直接复制到新创建的目录. + +### Step 3. 配置系统环境 + +首先需要添加环境变量`GRADLE_HOME`. 指向解压后的文件所在的文件夹. 然后添加_`GRADLE_HOME/bin`_ 到环境变量`PATH` 中. + +#### Linux & MacOS + +配置`PATH`指向解压后的 `bin`文件目录, e.g.: + +``` +❯ export PATH=$PATH:/opt/gradle/gradle-4.6/bin +``` + + + From 50f3248d8f0250d4537ae54bffd27e0efb97cf3d Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:29:59 +0000 Subject: [PATCH 011/102] Updates installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../que-ren-shi-fou-an-zhuang-cheng-gong.md | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md diff --git a/SUMMARY.md b/SUMMARY.md index 9d9204e..6653bba 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -13,6 +13,7 @@ * [手动安装](installing_gradle/shou-dong-an-zhuang.md) * [JVM选项](installing_gradle/jvm_options.md) * [下载与安装](installing_gradle/download.md) + * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) * [排除故障](troubleshooting/README.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) diff --git a/installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md b/installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md new file mode 100644 index 0000000..057d634 --- /dev/null +++ b/installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md @@ -0,0 +1,24 @@ +# 确认是否安装成功 + +打开控制台运行 `gradle -v`, e.g.: + +``` +❯ gradle -v + +------------------------------------------------------------ +Gradle 4.6 +------------------------------------------------------------ + +Build time: 2018-02-21 15:28:42 UTC +Revision: 819e0059da49f469d3e9b2896dc4e72537c4847d + +Groovy: 2.4.12 +Ant: Apache Ant(TM) version 1.9.9 compiled on February 2 2017 +JVM: 1.8.0_151 (Oracle Corporation 25.151-b12) +OS: Mac OS X 10.13.3 x86_64 +``` + +如果碰到任何问题, 请查看 [section on troubleshooting installation](https://docs.gradle.org/current/userguide/troubleshooting.html#sec:troubleshooting_installation). + +你也可以通过下载 SHA-256 文件来确保 Gradle 的完整性 \( 查看 [releases page](https://gradle.org/releases)\) 并跟随这个章节 [verification instructions](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:verification). + From 379af85f4c9bd4f32ec66eec88471930e8fe6540 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:34:12 +0000 Subject: [PATCH 012/102] Updates installing_gradle/xia-yi-bu.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + installing_gradle/xia-yi-bu.md | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 installing_gradle/xia-yi-bu.md diff --git a/SUMMARY.md b/SUMMARY.md index 6653bba..960641f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -14,6 +14,7 @@ * [JVM选项](installing_gradle/jvm_options.md) * [下载与安装](installing_gradle/download.md) * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) + * [下一步](installing_gradle/xia-yi-bu.md) * [排除故障](troubleshooting/README.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) diff --git a/installing_gradle/xia-yi-bu.md b/installing_gradle/xia-yi-bu.md new file mode 100644 index 0000000..d15e61f --- /dev/null +++ b/installing_gradle/xia-yi-bu.md @@ -0,0 +1,16 @@ +# 下一步 + +现在 Gradle 已经安装好了, 可以查阅下列文章开始学习 Gradle: + +* 创建你的第一个 Gradle 项目 [Creating New Gradle Builds](https://guides.gradle.org/creating-new-gradle-builds/). + +* 注册参加 [live introductory Gradle training](https://gradle.org/training/intro-to-gradle/). + +* 学习如何实现常用的任务 [command-line interface](https://docs.gradle.org/current/userguide/command_line_interface.html). + +* [Configure Gradle execution](https://docs.gradle.org/current/userguide/build_environment.html), 比如使用 HTTP proxy 下载依赖. + +* 订阅 [Gradle Newsletter](https://newsletter.gradle.com/) 了解 Gradle 的最新详情. + + + From 7371055dbe05bf44a8d865bc6a81cbf0333f5927 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:37:21 +0000 Subject: [PATCH 013/102] Updates installing_gradle/shou-dong-an-zhuang.md Auto commit by GitBook Editor --- SUMMARY.md | 2 -- installing_gradle/shou-dong-an-zhuang.md | 13 ++++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 960641f..88e3477 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -11,8 +11,6 @@ * [预备知识](installing_gradle/yu-bei-zhi-shi.md) * [通过 Package Manager 安装](installing_gradle/tong-guo-package-manager-an-zhuang.md) * [手动安装](installing_gradle/shou-dong-an-zhuang.md) - * [JVM选项](installing_gradle/jvm_options.md) - * [下载与安装](installing_gradle/download.md) * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) * [下一步](installing_gradle/xia-yi-bu.md) * [排除故障](troubleshooting/README.md) diff --git a/installing_gradle/shou-dong-an-zhuang.md b/installing_gradle/shou-dong-an-zhuang.md index fe6097b..3650cde 100644 --- a/installing_gradle/shou-dong-an-zhuang.md +++ b/installing_gradle/shou-dong-an-zhuang.md @@ -29,14 +29,21 @@ LICENSE NOTICE bin getting-started.html init.d lib media ### Step 3. 配置系统环境 -首先需要添加环境变量`GRADLE_HOME`. 指向解压后的文件所在的文件夹. 然后添加_`GRADLE_HOME/bin`_ 到环境变量`PATH` 中. +1. 添加环境变量`GRADLE_HOME`. 指向解压后的文件所在的文件夹. +2. 添加`GRADLE_HOME/bin` 到环境变量`PATH` 中. #### Linux & MacOS -配置`PATH`指向解压后的 `bin`文件目录, e.g.: +假设下载好的 Gradle 文件在 /Users/UFreedom/gradle 目录 ``` -❯ export PATH=$PATH:/opt/gradle/gradle-4.6/bin +1.vim ~/.bash_profile + +2.添加下面内容: +export GRADLE_HOME = /Users/UFreedom/gradle +export export PATH=$PATH:$GRADLE_HOME/bin + +3.source ~/.brash_profile ``` From ca995c7be714cec13753f0e6fe4b0c34d297693c Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:38:22 +0000 Subject: [PATCH 014/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/SUMMARY.md b/SUMMARY.md index 88e3477..2cd95cc 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -13,7 +13,6 @@ * [手动安装](installing_gradle/shou-dong-an-zhuang.md) * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) * [下一步](installing_gradle/xia-yi-bu.md) -* [排除故障](troubleshooting/README.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) From e3fe1900896a274ce0629f7465327e315504852e Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:44:09 +0000 Subject: [PATCH 015/102] Updates chu-shi-hua-xiang-mu.md Auto commit by GitBook Editor --- SUMMARY.md | 5 +++- chu-shi-hua-xiang-mu.md | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 chu-shi-hua-xiang-mu.md diff --git a/SUMMARY.md b/SUMMARY.md index 2cd95cc..d5b3a61 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -13,6 +13,8 @@ * [手动安装](installing_gradle/shou-dong-an-zhuang.md) * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) * [下一步](installing_gradle/xia-yi-bu.md) +* 创建一个 Gradle 项目 + * [初始化项目](chu-shi-hua-xiang-mu.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) @@ -203,5 +205,6 @@ * [公共配置](the_war_plugin/convention_properties.md) * [War](the_war_plugin/war.md) * [定制War](the_war_plugin/customizing.md) -* [Ear插件](earcha-jian.md) +* 创建一个 Gradle 项目 + * 初始化项目 diff --git a/chu-shi-hua-xiang-mu.md b/chu-shi-hua-xiang-mu.md new file mode 100644 index 0000000..9c82d01 --- /dev/null +++ b/chu-shi-hua-xiang-mu.md @@ -0,0 +1,58 @@ +# 初始化项目 + +First, let’s create a new directory where our project will go. + +``` +❯ mkdir basic-demo +❯ cd basic-demo +``` + +Now we can use Gradle’s`init`command to generate a simple project. We will explore everything that is generated so you know exactly what’s going on. + +``` +❯ gradle init +Starting a Gradle Daemon (subsequent builds will be faster) + +BUILD SUCCESSFUL in 3s +2 actionable tasks: 2 executed +``` + +The command should show "BUILD SUCCESSFUL" and generate the following "empty" project. If it doesn’t, please ensure that Gradle is[installed properly](https://gradle.org/install), and that you have the`JAVA_HOME`environment variable set correctly. + +This is what Gradle generated for you. + +``` +. +├── build.gradle + +├── gradle +│   └── wrapper +│   ├── gradle-wrapper.jar + +│   └── gradle-wrapper.properties + +├── gradlew + +├── gradlew.bat + +└── settings.gradle +``` + +| | Project configuration script for configuring tasks in the current project | +| :--- | :--- | +| | [Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html)executable JAR | +| | Gradle Wrapper configuration properties | +| | Gradle Wrapper script for Unix-based systems | +| | Gradle Wrapper script for Windows | +| | Settings configuration script for configuring which Projects participate in the build | + +| | `gradle init`can generate[various different types of projects](https://docs.gradle.org/4.6/userguide/build_init_plugin.html#sec:build_init_types), and even knows how to translate simple`pom.xml`files to Gradle. | +| :--- | :--- | + + +Boom! Roasted. We could just end the guide here, but chances are you want to know how to_use_Gradle in this project. Let’s do that. + +## [ ](https://guides.gradle.org/creating-new-gradle-builds/?_ga=2.191880558.599696663.1521685504-557532416.1521019880#create_a_task) {#create_a_task} + + + From e9486be6619a0246aa510145bbb4ec0f2e195816 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:46:25 +0000 Subject: [PATCH 016/102] Updates chuangjian-yi-ge-gradle-xiang-mu.md Auto commit by GitBook Editor --- SUMMARY.md | 2 +- chuangjian-yi-ge-gradle-xiang-mu.md | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 chuangjian-yi-ge-gradle-xiang-mu.md diff --git a/SUMMARY.md b/SUMMARY.md index d5b3a61..4bbaf30 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -13,7 +13,7 @@ * [手动安装](installing_gradle/shou-dong-an-zhuang.md) * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) * [下一步](installing_gradle/xia-yi-bu.md) -* 创建一个 Gradle 项目 +* [创建一个 Gradle 项目](chuangjian-yi-ge-gradle-xiang-mu.md) * [初始化项目](chu-shi-hua-xiang-mu.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) diff --git a/chuangjian-yi-ge-gradle-xiang-mu.md b/chuangjian-yi-ge-gradle-xiang-mu.md new file mode 100644 index 0000000..8301f5a --- /dev/null +++ b/chuangjian-yi-ge-gradle-xiang-mu.md @@ -0,0 +1,16 @@ +# 创建一个 Gradle 项目 + +Following this guide, you’ll create a trivial Gradle project, invoke some of the basic Gradle commands, and get a sense of how Gradle manages the project. + +## 你需要什么 {#what_you_ll_need} + +* 大约 11 分钟 + +* A terminal or IDE application + +* A Java Development Kit \(JDK\), version 1.7 or better \(only necessary to run Gradle\) + +* A[Gradle distribution](https://gradle.org/install), version 4.6 or better + + + From ace909eb814129fe22dc2fb905959ea99a3f504c Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 22 Mar 2018 04:48:23 +0000 Subject: [PATCH 017/102] Updates chuangjian-yi-ge-gradle-xiang-mu.md Auto commit by GitBook Editor --- chuangjian-yi-ge-gradle-xiang-mu.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/chuangjian-yi-ge-gradle-xiang-mu.md b/chuangjian-yi-ge-gradle-xiang-mu.md index 8301f5a..7c8b248 100644 --- a/chuangjian-yi-ge-gradle-xiang-mu.md +++ b/chuangjian-yi-ge-gradle-xiang-mu.md @@ -1,16 +1,13 @@ # 创建一个 Gradle 项目 -Following this guide, you’ll create a trivial Gradle project, invoke some of the basic Gradle commands, and get a sense of how Gradle manages the project. +跟随这篇教程, 你将创建一个 Gradle 项目, 使用一些基础的 Gradle 命令, 了解 Gradle 是如何管理项目的. ## 你需要什么 {#what_you_ll_need} * 大约 11 分钟 - -* A terminal or IDE application - -* A Java Development Kit \(JDK\), version 1.7 or better \(only necessary to run Gradle\) - -* A[Gradle distribution](https://gradle.org/install), version 4.6 or better +* 一个终端或 IDE +* Java Development Kit \(JDK\), 1.7 版本及以上 +* 安装好 [Gradle](https://gradle.org/install), 4.6 版本及以上 From 12de7bde10f44c6fbcf281339ce26d5118de8de1 Mon Sep 17 00:00:00 2001 From: DONG Date: Fri, 23 Mar 2018 12:16:33 +0000 Subject: [PATCH 018/102] Updates chuang-jian-task.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + chuang-jian-task.md | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 chuang-jian-task.md diff --git a/SUMMARY.md b/SUMMARY.md index 4bbaf30..46e70df 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -15,6 +15,7 @@ * [下一步](installing_gradle/xia-yi-bu.md) * [创建一个 Gradle 项目](chuangjian-yi-ge-gradle-xiang-mu.md) * [初始化项目](chu-shi-hua-xiang-mu.md) + * [创建 Task](chuang-jian-task.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) diff --git a/chuang-jian-task.md b/chuang-jian-task.md new file mode 100644 index 0000000..4a2d413 --- /dev/null +++ b/chuang-jian-task.md @@ -0,0 +1,57 @@ +# 创建 Task + +Gradle provides APIs for creating and configuring tasks through a Groovy or Kotlin-based DSL. A[`Project`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html)includes a collection of[`Task`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Task.html)s, each of which performs some basic operation. + +Gradle comes with a library of tasks that you can configure in your own projects. For example, there is a core type called`Copy`, which copies files from one location to another. The`Copy`task is very useful \([see the documentation](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.Copy.html)for details\), but here, once again, let’s keep it simple. Perform the following steps: + +1. Create a directory called`src`. + +2. Add a file called`myfile.txt`in the`src`directory. The contents are arbitrary \(it can even be empty\), but for convenience add the single line`Hello, World!`to it. + +3. Define a task called`copy`of type`Copy`\(note the capital letter\) in the main build file,`build.gradle`, that copies the`src`directory to a new directory called`dest`. \(You don’t have to create the`dest`directory — the task will do it for you.\) + +``` +task copy( +type +: Copy, +group +: +" +Custom +" +, +description +: +" +Copies sources to the dest directory +" +) { + from +" +src +" + + into +" +dest +" + +} +``` + +Here,`group`and`description`can be anything you want. You can even omit them, but doing so will also omit them from the`tasks`report, used later. + +Now execute your new`copy`task: + +``` +❯ ./gradlew copy +:copy + +BUILD SUCCESSFUL in 0s +1 actionable task: 1 executed +``` + +Verify that it worked as expected by checking that there is now a file called`myfile.txt`in the`dest`directory, and that its contents match the contents of the same one in the`src`directory. + + + From 785686e065bcf3e5ceeca84ca510b4a11ee59359 Mon Sep 17 00:00:00 2001 From: DONG Date: Fri, 23 Mar 2018 12:20:28 +0000 Subject: [PATCH 019/102] Updates shi-yong-cha-jian.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + shi-yong-cha-jian.md | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 shi-yong-cha-jian.md diff --git a/SUMMARY.md b/SUMMARY.md index 46e70df..992e4cd 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -16,6 +16,7 @@ * [创建一个 Gradle 项目](chuangjian-yi-ge-gradle-xiang-mu.md) * [初始化项目](chu-shi-hua-xiang-mu.md) * [创建 Task](chuang-jian-task.md) + * [使用插件](shi-yong-cha-jian.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) diff --git a/shi-yong-cha-jian.md b/shi-yong-cha-jian.md new file mode 100644 index 0000000..998abc5 --- /dev/null +++ b/shi-yong-cha-jian.md @@ -0,0 +1,58 @@ +# 使用插件 + +Gradle includes a range of plugins, and many, many more are available at[the Gradle plugin portal](http://plugins.gradle.org/). One of the plugins included with the distribution is the`base`plugin. Combined with a core type called[`Zip`](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.bundling.Zip.html), you can create a zip archive of your project with a configured name and location. + +Add the`base`plugin to your`build.gradle`file using the`plugins`syntax. Be sure to add the`plugins {}`block at the top of the file. + +``` +plugins { + id +" +base +" + +} + +... rest of the build file ... +``` + +Now add a task that creates a zip archive from the`src`directory. + +``` +task zip( +type +: Zip, +group +: +" +Archive +" +, +description +: +" +Archives sources in a zip file +" +) { + from +" +src +" + +} +``` + +The`base`plugin works with the settings to create an archive file called`basic-demo-1.0.zip`in the`build/distributions`folder. + +In this case, simply run the new`zip`task and see that the generated zip file is where you expect. + +``` +❯ ./gradlew zip +:zip + +BUILD SUCCESSFUL in 0s +1 actionable task: 1 executed +``` + + + From f57e6b16f508ae61749b69c78b81bdc2bd261781 Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 04:14:22 +0000 Subject: [PATCH 020/102] Updates chu-shi-hua-xiang-mu.md Auto commit by GitBook Editor --- chu-shi-hua-xiang-mu.md | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/chu-shi-hua-xiang-mu.md b/chu-shi-hua-xiang-mu.md index 9c82d01..1104d7e 100644 --- a/chu-shi-hua-xiang-mu.md +++ b/chu-shi-hua-xiang-mu.md @@ -1,13 +1,13 @@ # 初始化项目 -First, let’s create a new directory where our project will go. +首先, 创建一个新的目录: ``` ❯ mkdir basic-demo ❯ cd basic-demo ``` -Now we can use Gradle’s`init`command to generate a simple project. We will explore everything that is generated so you know exactly what’s going on. +使用 Gradle `init` 命令生成一个简单的项目: ``` ❯ gradle init @@ -17,42 +17,35 @@ BUILD SUCCESSFUL in 3s 2 actionable tasks: 2 executed ``` -The command should show "BUILD SUCCESSFUL" and generate the following "empty" project. If it doesn’t, please ensure that Gradle is[installed properly](https://gradle.org/install), and that you have the`JAVA_HOME`environment variable set correctly. +通过这个命令, 生成了一个'空项目. 如果没有生成成功, 请确保 Gradle 已经正确安装并且`JAVA_HOME` 设置正确. -This is what Gradle generated for you. +目录结构如下 ``` . ├── build.gradle ├── gradle -│   └── wrapper -│   ├── gradle-wrapper.jar +│ └── wrapper +│ ├── gradle-wrapper.jar -│   └── gradle-wrapper.properties +│ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat -└── settings.gradle +└── settings.gradle ``` -| | Project configuration script for configuring tasks in the current project | -| :--- | :--- | -| | [Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html)executable JAR | -| | Gradle Wrapper configuration properties | -| | Gradle Wrapper script for Unix-based systems | -| | Gradle Wrapper script for Windows | -| | Settings configuration script for configuring which Projects participate in the build | +* build.gradle - 项目配置脚本, 配置当前项目的各项任务. +* gradle-wrapper.jar - [Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html) 可执行 JAR 文件. +* gradle-wrapper.properties - Gradle Wrapper 配置相关的各项属性. +* gradlew - 基于 Unix 系统的 Gradle Wrapper 脚本. +* gradlew.bat - Windows 系统的 Gradle Wrapper 脚本. +* settings.gradle - 配置设置脚本, 配置哪些项目会加入到构建当中. -| | `gradle init`can generate[various different types of projects](https://docs.gradle.org/4.6/userguide/build_init_plugin.html#sec:build_init_types), and even knows how to translate simple`pom.xml`files to Gradle. | -| :--- | :--- | - - -Boom! Roasted. We could just end the guide here, but chances are you want to know how to_use_Gradle in this project. Let’s do that. - -## [ ](https://guides.gradle.org/creating-new-gradle-builds/?_ga=2.191880558.599696663.1521685504-557532416.1521019880#create_a_task) {#create_a_task} +> `gradle init` 可以生成[许多种不同类型的项目](https://docs.gradle.org/4.6/userguide/build_init_plugin.html#sec:build_init_types), 并把 `pom.xml` 文件转化成 Gradle. From b5472bb5c3c5c928a99890c78b90f42276b2087d Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 04:30:11 +0000 Subject: [PATCH 021/102] Updates chuang-jian-task.md Auto commit by GitBook Editor --- chuang-jian-task.md | 46 +++++++++++---------------------------------- 1 file changed, 11 insertions(+), 35 deletions(-) diff --git a/chuang-jian-task.md b/chuang-jian-task.md index 4a2d413..98476d0 100644 --- a/chuang-jian-task.md +++ b/chuang-jian-task.md @@ -1,47 +1,25 @@ # 创建 Task -Gradle provides APIs for creating and configuring tasks through a Groovy or Kotlin-based DSL. A[`Project`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html)includes a collection of[`Task`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Task.html)s, each of which performs some basic operation. +Gradle 通过 Groovy 或者 Kotlin-based DSL 提供相关的 APIs 来创建和配置任务. 一个[项目](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html)包含许多[任务](https://docs.gradle.org/4.6/dsl/org.gradle.api.Task.html), 每个人物都会执行一些基础的操作. -Gradle comes with a library of tasks that you can configure in your own projects. For example, there is a core type called`Copy`, which copies files from one location to another. The`Copy`task is very useful \([see the documentation](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.Copy.html)for details\), but here, once again, let’s keep it simple. Perform the following steps: +Gradle 本身也自带了一些任务, 你可以直接在自己的项目中直接使用. 比如, 用来复制文件的`Copy`任务. `Copy`任务十分常用 \(具体可以[查看文档](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.Copy.html)了解更多\), 这里, 我们将只展示最基本的用法. 让我们来执行下列操作: -1. Create a directory called`src`. +1. 创建一个文件夹`src`. -2. Add a file called`myfile.txt`in the`src`directory. The contents are arbitrary \(it can even be empty\), but for convenience add the single line`Hello, World!`to it. +2. 在文件夹中添加 `myfile.txt`. 在文件中随意添加内容, 比如`Hello, World!`. -3. Define a task called`copy`of type`Copy`\(note the capital letter\) in the main build file,`build.gradle`, that copies the`src`directory to a new directory called`dest`. \(You don’t have to create the`dest`directory — the task will do it for you.\) +3. 在 `build.gradle`中定义一个叫做`copy` 的任务, 它的类型为`Copy`\(注意首字母大写\), 会将 `src`文件夹中的内容复制到一个新的文件夹, 叫做`dest`. \(你不需要手动创建`dest`文件夹— copy 任务会帮你完成它\) ``` -task copy( -type -: Copy, -group -: -" -Custom -" -, -description -: -" -Copies sources to the dest directory -" -) { - from -" -src -" - - into -" -dest -" - +task copy(type: Copy, group: "Custom", description: "Copies sources to the dest directory") { + from "src" + into "dest" } ``` -Here,`group`and`description`can be anything you want. You can even omit them, but doing so will also omit them from the`tasks`report, used later. +这里,`group`和`description`可以是任何字段. 你甚至可以删除它们, 但是这样也会将它们从`tasks`报告中删除, 由于我们接下来还需要使用它们, 请先不要删除. -Now execute your new`copy`task: +现在可以执行`copy`任务了: ``` ❯ ./gradlew copy @@ -51,7 +29,5 @@ BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed ``` -Verify that it worked as expected by checking that there is now a file called`myfile.txt`in the`dest`directory, and that its contents match the contents of the same one in the`src`directory. - - +请检查现在在`dest`文件夹下是否存在一个 `myfile.txt`文件, 并且该文件与原文件内容相同. From b6f00ea7e8db55963579333133f2f71e523c501b Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 04:37:45 +0000 Subject: [PATCH 022/102] Updates shi-yong-cha-jian.md Auto commit by GitBook Editor --- shi-yong-cha-jian.md | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/shi-yong-cha-jian.md b/shi-yong-cha-jian.md index 998abc5..76f9f7e 100644 --- a/shi-yong-cha-jian.md +++ b/shi-yong-cha-jian.md @@ -1,50 +1,26 @@ # 使用插件 -Gradle includes a range of plugins, and many, many more are available at[the Gradle plugin portal](http://plugins.gradle.org/). One of the plugins included with the distribution is the`base`plugin. Combined with a core type called[`Zip`](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.bundling.Zip.html), you can create a zip archive of your project with a configured name and location. +Gradle 包含各式各样的插件, 你可以在这里查阅它们 [Gradle 插件汇总](http://plugins.gradle.org/). 其中一个已经包含在发布的 Gradle 中的插件叫做`base`插件. 和另外一种核心类型 [`Zip`](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.bundling.Zip.html) 任务组合使用, 你可以将你的项目打包成一个 Zip 文件. -Add the`base`plugin to your`build.gradle`file using the`plugins`syntax. Be sure to add the`plugins {}`block at the top of the file. +将`base`插件添加到`build.gradle`中. `plugins {}`语句块一定要放在文件的开头. ``` plugins { - id -" -base -" - + id "base" } ... rest of the build file ... ``` -Now add a task that creates a zip archive from the`src`directory. +现在添加一个任务用来打包项目的 `src`文件夹. ``` -task zip( -type -: Zip, -group -: -" -Archive -" -, -description -: -" -Archives sources in a zip file -" -) { - from -" -src -" - +task zip(type: Zip, group: "Archive", description: "Archives sources in a zip file") { + from "src" } ``` -The`base`plugin works with the settings to create an archive file called`basic-demo-1.0.zip`in the`build/distributions`folder. - -In this case, simply run the new`zip`task and see that the generated zip file is where you expect. +执行该任务,`base`插件会在 `build/distributions` 文件夹中生成`basic-demo-1.0.zip` : ``` ❯ ./gradlew zip From 0c0bf8d87638c1da291472620c0547249e1e5463 Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 04:46:37 +0000 Subject: [PATCH 023/102] Updates tan-suo-he-debug-ni-de-gou-jian.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + tan-suo-he-debug-ni-de-gou-jian.md | 77 ++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tan-suo-he-debug-ni-de-gou-jian.md diff --git a/SUMMARY.md b/SUMMARY.md index 992e4cd..1a15e47 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,6 +17,7 @@ * [初始化项目](chu-shi-hua-xiang-mu.md) * [创建 Task](chuang-jian-task.md) * [使用插件](shi-yong-cha-jian.md) + * [探索和DEBUG你的构建](tan-suo-he-debug-ni-de-gou-jian.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) diff --git a/tan-suo-he-debug-ni-de-gou-jian.md b/tan-suo-he-debug-ni-de-gou-jian.md new file mode 100644 index 0000000..8a54d1c --- /dev/null +++ b/tan-suo-he-debug-ni-de-gou-jian.md @@ -0,0 +1,77 @@ +# 探索和DEBUG你的构建 + +让我们来看看我们还能在新的项目里做些什么. 可以查看[reference to the command-line interface](https://docs.gradle.org/4.6/userguide/command_line_interface.html)获得完整的命令行指引. + +### 查看可以使用的任务 + +`tasks`命令会列出我们当前可以调用的 Gradle 任务,包括通过`base`插件添加的任务以及我们刚刚添加的任务. + + + +``` +❯ ./gradlew tasks + +> Task :tasks + +------------------------------------------------------------ +All tasks runnable from root project +------------------------------------------------------------ + +Archive tasks +------------- +zip - Archives sources in a zip file + +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. + +Custom tasks +------------ +copy - Simply copies sources to a the build directory + +Help tasks +---------- +buildEnvironment - Displays all buildscript dependencies declared in root project 'basic-demo'. +components - Displays the components produced by root project 'basic-demo'. [incubating] +dependencies - Displays all dependencies declared in root project 'basic-demo'. +dependencyInsight - Displays the insight into a specific dependency in root project 'basic-demo'. +dependentComponents - Displays the dependent components of components in root project 'basic-demo'. [incubating] +help - Displays a help message. +model - Displays the configuration model of root project 'basic-demo'. [incubating] +projects - Displays the sub-projects of root project 'basic-demo'. +properties - Displays the properties of root project 'basic-demo'. +tasks - Displays the tasks runnable from root project 'basic-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 +``` + +### 分析和DEBUG你的构建 {#analyze_and_debug_your_build} + +Gradle 提供了一个基于网页的分析工具 [build scan](https://scans.gradle.com/) + +. + + + From 91770d5fda04c828868886b35a77c79f1930c8af Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 04:55:22 +0000 Subject: [PATCH 024/102] Updates tan-suo-he-debug-ni-de-gou-jian.md Auto commit by GitBook Editor --- assets/basic-demo-build-scan.png | Bin 0 -> 194989 bytes tan-suo-he-debug-ni-de-gou-jian.md | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 assets/basic-demo-build-scan.png diff --git a/assets/basic-demo-build-scan.png b/assets/basic-demo-build-scan.png new file mode 100644 index 0000000000000000000000000000000000000000..dcb7fb1aef966ca3f363fb3606bb696f6a9ea46c GIT binary patch literal 194989 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%0ALheXZD$sv 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

8q4G28IWM9=+6 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

0S}nDO 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 Date: Sat, 24 Mar 2018 05:03:35 +0000 Subject: [PATCH 025/102] Updates tan-suo-he-debug-ni-de-gou-jian.md Auto commit by GitBook Editor --- tan-suo-he-debug-ni-de-gou-jian.md | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/tan-suo-he-debug-ni-de-gou-jian.md b/tan-suo-he-debug-ni-de-gou-jian.md index b1249f9..394b376 100644 --- a/tan-suo-he-debug-ni-de-gou-jian.md +++ b/tan-suo-he-debug-ni-de-gou-jian.md @@ -85,12 +85,48 @@ Gradle Cloud Services license agreement accepted. Publishing build scan... https://gradle.com/s/repnge6srr5qs +``` + +如果你仔细浏览你的 build scan, 你应该可以直观的发现任务执行的位置以及时长, 以及其他信息. 如果需要学习更多的 build scans 的用法, 请查阅 [Build Scan Plugin User Manual](https://docs.gradle.com/build-scan-plugin/). + +### 查阅项目相关属性 {#discover_available_properties} + +通过`properties`命令来查阅项目的各项属性. +``` +❯ ./gradlew properties ``` +将输出很多内容, 我们只展示其中的一部分显示的属性: +``` +> Task :properties -如果你仔细浏览你的 build scan, 你应该可以直观的发现任务执行的位置以及时长, 以及其他信息. 如果需要学习更多的 build scans 的用法, 请查阅 [Build Scan Plugin User Manual](https://docs.gradle.com/build-scan-plugin/). +------------------------------------------------------------ +Root project +------------------------------------------------------------ + +buildDir: /Users/.../basic-demo/build +buildFile: /Users/.../basic-demo/build.gradle +description: null +group: +name: basic-demo +projectDir: /Users/.../basic-demo +version: unspecified + +BUILD SUCCESSFUL +``` + +`name `默认是文件夹的名称, 你可以设设置`group`和`version`属性, 但现在它们都是显示的默认值. + +`buildFile`属性指出了`build.gradle`的路径,  一般来说, `build`是`projectDir`的子文件夹, 这个文件夹包含`build.gradle`文件. + +你可以改编项目的许多属性. 比如, 你可以尝试加入以下脚本到 `build.gradle`中, 再次执行`gradle properties`. + +``` +description = "A trivial Gradle build" +version = "1.0" +``` From 164f436f54fbdf166d339ca97bd7c726e2a5a626 Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 05:06:09 +0000 Subject: [PATCH 026/102] Updates xia-yi-bu.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + xia-yi-bu.md | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 xia-yi-bu.md diff --git a/SUMMARY.md b/SUMMARY.md index 1a15e47..73aa4ec 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -18,6 +18,7 @@ * [创建 Task](chuang-jian-task.md) * [使用插件](shi-yong-cha-jian.md) * [探索和DEBUG你的构建](tan-suo-he-debug-ni-de-gou-jian.md) + * [下一步](xia-yi-bu.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) diff --git a/xia-yi-bu.md b/xia-yi-bu.md new file mode 100644 index 0000000..8549373 --- /dev/null +++ b/xia-yi-bu.md @@ -0,0 +1,22 @@ +# 下一步 + +如果你想要创意一个library, 一个应用或者是一个特殊的平台, 那你可以查阅下面的教程: + +* [Building Android Apps](https://guides.gradle.org/building-android-apps) + +* [Building C++ Executables](https://guides.gradle.org/building-cpp-executables) + +* [Building Groovy Libraries](https://guides.gradle.org/building-groovy-libraries) + +* [Building Java Libraries](https://guides.gradle.org/building-java-libraries) + +* [Building Kotlin JVM Libraries](https://guides.gradle.org/building-kotlin-jvm-libraries) + +* [Building Scala Libraries](https://guides.gradle.org/building-scala-libraries) + +你可以在 [sample Gradle builds on GitHub](https://github.com/gradle/gradle/tree/master/subprojects/docs/src/samples) 这里找到许多例子来学习 Gradle. + +## [ ](https://guides.gradle.org/creating-new-gradle-builds/?_ga=2.191880558.599696663.1521685504-557532416.1521019880#help_improve_this_guide) {#help_improve_this_guide} + + + From b342bd777a74ce82de6489f439d3761f415755cc Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 05:07:33 +0000 Subject: [PATCH 027/102] Updates README.md Auto commit by GitBook Editor --- README.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 33abee9..5fef7f1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### [阅读地址](http://dongchuan.gitbooks.io/gradle-user-guide-/) -* Gradle User Guide 中文版 目前正在翻译当中, 由于这本 guide 的英文版某些部分非常难以理解, 我们也会加入自己的观点和例子, 并不会完全照搬翻译, 希望大家理解也欢迎大家一起加入和完善 +* Gradle User Guide 中文版目前正在更新到 4.6, 希望大家理解也欢迎大家一起加入和完善 * 如果发现不通顺或者有歧义的地方, 可以在评论里指出来, 我们会及时改正的. @@ -10,34 +10,32 @@ * [原文地址](https://docs.gradle.org/current/userguide/userguide.html) -* 我们会开放权限给每一个加入的伙伴 (翻译或者校对),请提前邮箱联系 dongchuan55@gmail.com ----- +* 我们会开放权限给每一个加入的伙伴 \(翻译或者校对\),请提前邮箱联系 dongchuanyz@163.com + +--- + ### 如何参与 -任何问题都欢迎直接联系我 dongchuan55@gmail.com 或者我们的 QQ群 324020116 +任何问题都欢迎直接联系我 dongchuanyz@163.com或者我们的 QQ群 324020116 Gitbook 提供了非常棒的在线编辑功能, 所以想贡献的同学可以直接联系我申请权限! --- + ### 许可证 -本作品采用 Apache License 2.0 国际许可协议 进行许可. 传播此文档时请注意遵循以上许可协议. 关于本许可证的更多详情可参考 http://www.apache.org/licenses/LICENSE-2.0 +本作品采用 Apache License 2.0 国际许可协议 进行许可. 传播此文档时请注意遵循以上许可协议. 关于本许可证的更多详情可参考 [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) --- -### 贡献者列表 - -成员 | 联系方式 | Github -:------|:------|:------ -dongchuan55 | dongchuan55@gmail.com | [Github](https://github.com/DONGChuan) -UFreedom | sunfreedom@sina.cn | [Github](https://github.com/UFreedom) -张扬 | zhangyang911120@gmail.com | [Github](https://github.com/dreamkidd) -d0048 | d0048@foxmail.com | [Github](https://github.com/D0048) - - - - +### 贡献者列表 +| 成员 | 联系方式 | Github | +| :--- | :--- | :--- | +| dongchuan55 | dongchuan55@gmail.com | [Github](https://github.com/DONGChuan) | +| UFreedom | sunfreedom@sina.cn | [Github](https://github.com/UFreedom) | +| 张扬 | zhangyang911120@gmail.com | [Github](https://github.com/dreamkidd) | +| d0048 | d0048@foxmail.com | [Github](https://github.com/D0048) | From 0b4bd3b49d0e01a0fbfdb6fc29ed9ec2484eace0 Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 05:14:13 +0000 Subject: [PATCH 028/102] Updates README.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + chuang-jian-build-scans.md | 195 +++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 chuang-jian-build-scans.md diff --git a/SUMMARY.md b/SUMMARY.md index 73aa4ec..76c457a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -19,6 +19,7 @@ * [使用插件](shi-yong-cha-jian.md) * [探索和DEBUG你的构建](tan-suo-he-debug-ni-de-gou-jian.md) * [下一步](xia-yi-bu.md) +* [创建 Build Scans](chuang-jian-build-scans.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) diff --git a/chuang-jian-build-scans.md b/chuang-jian-build-scans.md new file mode 100644 index 0000000..54c1218 --- /dev/null +++ b/chuang-jian-build-scans.md @@ -0,0 +1,195 @@ +# 创建 Build Scans + +A build scan is a shareable and centralized record of a build that provides insights into what happened and why. By applying the build scan plugin to your project, you can publish build scans to[https://scans.gradle.com](https://scans.gradle.com/)for free. + +Contents + +* [What you’ll create](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_create) +* [What you’ll need](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_need) +* [Select a sample project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#select_a_sample_project) +* [Auto-apply the build scan plugin](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#auto_apply_the_build_scan_plugin) +* [Enable build scans on all builds of your project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_on_all_builds_of_your_project) +* [Accept the license agreement](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#accept_the_license_agreement) +* [Publish a build scan](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#publish_a_build_scan) +* [Access the build scan online](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#access_the_build_scan_online) +* [Enable build scans for all builds \(optional\)](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_for_all_builds_optional) +* [Summary](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#summary) +* [Next steps](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#next_steps) +* [Help improve this guide](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#help_improve_this_guide) + +## [What you’ll create](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_create) {#what_you_ll_create} + +This guide shows you how to publish build scans ad-hoc without any build script modifications. You will also learn how to modify a build script to enable build scans for all builds of a given project. Optionally, you will also modify an init script to enable build scans for all of your projects. + +## [What you’ll need](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_need) {#what_you_ll_need} + +* Either your own sample project, or you can use the sample project available from Gradle + +* Access to the Internet + +* Access to your email + +* About7 minutes + +## [Select a sample project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#select_a_sample_project) {#select_a_sample_project} + +Gradle makes available a simple Java project that you can use to demonstrate build scan capabilities. If you wish to use it, clone or download the repository located at[https://github.com/gradle/gradle-build-scan-quickstart](https://github.com/gradle/gradle-build-scan-quickstart). If you prefer to use your own project, you can skip this step. + +## [Auto-apply the build scan plugin](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#auto_apply_the_build_scan_plugin) {#auto_apply_the_build_scan_plugin} + +Starting with Gradle 4.3, you can enable build scans without any additional configuration in your build script. When using the command line option`--scan`to publish a build scan, the required build scan plugin is applied automatically. Before the end of the build, you are asked to accept the license agreement on the command line. The following console output demonstrates the behavior. + +``` +$ ./gradlew build --scan + +BUILD SUCCESSFUL in 6s + +Do you accept the Gradle Cloud Services license agreement (https://gradle.com/terms-of-service)? [yes, no] +yes +Gradle Cloud Services license agreement accepted. + +Publishing build scan... +https://gradle.com/s/czajmbyg73t62 +``` + +This mechanism makes it very easy to generate ad-hoc, one-off build scans without having to configure the build scan plugin in your build. If you need finer grained configuration, you can configure the build scan plugin in a build or init script as described in the following sections. + +## [Enable build scans on all builds of your project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_on_all_builds_of_your_project) {#enable_build_scans_on_all_builds_of_your_project} + +Add a`plugins`block to the`build.gradle`file with the following contents: + +``` +plugins { + id +' +com.gradle.build-scan +' + version +' +1.12.1 +' + +} +``` + +| | Use latest plugin version which can be found on the[Gradle Plugin Portal](https://plugins.gradle.org/plugin/com.gradle.build-scan). | +| :--- | :--- | + + +If you already have a`plugins`block, always put the build scan plugin first. Adding it below any existing plugins will still work, but will miss useful information. + +## [Accept the license agreement](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#accept_the_license_agreement) {#accept_the_license_agreement} + +In order to publish build scans to[https://scans.gradle.com](https://scans.gradle.com/), you need to accept the license agreement. This can be done ad-hoc via the command line when publishing, but can also be specified in your Gradle build file, by adding the following section: + +``` +buildScan { + licenseAgreementUrl = +' +https://gradle.com/terms-of-service +' + + licenseAgree = +' +yes +' + +} +``` + +The`buildScan`block allows you to configure the plugin. Here you are setting two properties necessary to accept the license agreement. Other properties are available. See the[Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/)for details. + +## [Publish a build scan](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#publish_a_build_scan) {#publish_a_build_scan} + +A build scan is published using a command-line flag called`--scan`. + +Run a`build`task with the`--scan`option. When the build is completed, after uploading the build data to scans.gradle.com, you will be presented with a link to see your build scan. + +``` +$ ./gradlew build --scan + +BUILD SUCCESSFUL in 5s + +Publishing build scan... +https://gradle.com/s/47i5oe7dhgz2c +``` + +## [Access the build scan online](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#access_the_build_scan_online) {#access_the_build_scan_online} + +The first time you follow the link, you will be asked to activate the created build scan. + +The email you receive to activate your build scan will look similar to: + +![](https://guides.gradle.org/creating-build-scans/images/build_scan_email.png "build scan email") + +Follow the link provided in the email, and you will see the created build scan. + +![](https://guides.gradle.org/creating-build-scans/images/build_scan_page.png "build scan page") + +You can now explore all the information contained in the build scan, including the time taken for tasks to execute, the time required during each stage of the build, the results of any tests, plugins used and other dependencies, any command-line switches used, and more. + +## [Enable build scans for all builds \(optional\)](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_for_all_builds_optional) {#enable_build_scans_for_all_builds_optional} + +You can avoid having to add the plugin and license agreement to every build by using a Gradle init script. Create a file called`buildScan.gradle`in the directory`~/.gradle/init.d`\(where the tilde represents your home directory\) with the following contents: + +``` +initscript { + repositories { + maven { url +' +https://plugins.gradle.org/m2 +' + } + } + + dependencies { + classpath +' +com.gradle:build-scan-plugin:1.12.1 +' + + } +} + +rootProject { + apply +plugin +: com.gradle.scan.plugin.BuildScanPlugin + + buildScan { + licenseAgreementUrl = +' +https://gradle.com/terms-of-service +' + + licenseAgree = +' +yes +' + + } +} +``` + +The init script downloads the build scan plugin if necessary and applies it to every project, and accepts the license agreement. Now you can use the`--scan`flag on any build on your system. + +There are additional capabilities you can add to the script, such as under what conditions to publish the scan information. For details, see the[Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/). + +## [Summary](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#summary) {#summary} + +In this guide, you learned how to: + +* Generate a build scan + +* View the build scan information online + +* Create an init script to enable build scans for all builds + +## [Next steps](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#next_steps) {#next_steps} + +Additional information can be found in the[Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/). + +## [ ](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#help_improve_this_guide) {#help_improve_this_guide} + + + From dc01a2af27d33ad17c226c64b5cdb2d7bf63a16e Mon Sep 17 00:00:00 2001 From: DONG Date: Sat, 24 Mar 2018 05:25:47 +0000 Subject: [PATCH 029/102] Updates chuang-jian-build-scans.md Auto commit by GitBook Editor --- chuang-jian-build-scans.md | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/chuang-jian-build-scans.md b/chuang-jian-build-scans.md index 54c1218..621f7fc 100644 --- a/chuang-jian-build-scans.md +++ b/chuang-jian-build-scans.md @@ -1,35 +1,13 @@ # 创建 Build Scans -A build scan is a shareable and centralized record of a build that provides insights into what happened and why. By applying the build scan plugin to your project, you can publish build scans to[https://scans.gradle.com](https://scans.gradle.com/)for free. +build scan 是一种可分享的, 构建的集中记录. 通过它, 你可以对项目发生了什么以及为什么有一个全局的了解. 通过在项目中加入 build scan 插件, 你可以免费将 build scans 发布到 [https://scans.gradle.com](https://scans.gradle.com/) . -Contents +这篇教程将展示: -* [What you’ll create](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_create) -* [What you’ll need](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_need) -* [Select a sample project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#select_a_sample_project) -* [Auto-apply the build scan plugin](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#auto_apply_the_build_scan_plugin) -* [Enable build scans on all builds of your project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_on_all_builds_of_your_project) -* [Accept the license agreement](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#accept_the_license_agreement) -* [Publish a build scan](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#publish_a_build_scan) -* [Access the build scan online](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#access_the_build_scan_online) -* [Enable build scans for all builds \(optional\)](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_for_all_builds_optional) -* [Summary](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#summary) -* [Next steps](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#next_steps) -* [Help improve this guide](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#help_improve_this_guide) +1. 如何不改编任何构建脚本来发布 build scans ad-hoc. +2. 如何更改构建脚本来使用对整个项目的所有构建使用 build scans 功能. -## [What you’ll create](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_create) {#what_you_ll_create} - -This guide shows you how to publish build scans ad-hoc without any build script modifications. You will also learn how to modify a build script to enable build scans for all builds of a given project. Optionally, you will also modify an init script to enable build scans for all of your projects. - -## [What you’ll need](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#what_you_ll_need) {#what_you_ll_need} - -* Either your own sample project, or you can use the sample project available from Gradle - -* Access to the Internet - -* Access to your email - -* About7 minutes +选择 ## [Select a sample project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#select_a_sample_project) {#select_a_sample_project} From ebfedc0041b5fc7fbd91af5fed8e9821831d95f0 Mon Sep 17 00:00:00 2001 From: DONG Date: Sun, 25 Mar 2018 03:17:45 +0000 Subject: [PATCH 030/102] Updates chuang-jian-build-scans.md Auto commit by GitBook Editor --- chuang-jian-build-scans.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/chuang-jian-build-scans.md b/chuang-jian-build-scans.md index 621f7fc..b13270e 100644 --- a/chuang-jian-build-scans.md +++ b/chuang-jian-build-scans.md @@ -7,15 +7,13 @@ build scan 是一种可分享的, 构建的集中记录. 通过它, 你可以对 1. 如何不改编任何构建脚本来发布 build scans ad-hoc. 2. 如何更改构建脚本来使用对整个项目的所有构建使用 build scans 功能. -选择 +### 选择一个示例项目 -## [Select a sample project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#select_a_sample_project) {#select_a_sample_project} +Gradle 提供了一个简单的 Java 项目给用户来尝试 build scan. 下载地址 [https://github.com/gradle/gradle-build-scan-quickstart](https://github.com/gradle/gradle-build-scan-quickstart). 你可以使用自己的项目. -Gradle makes available a simple Java project that you can use to demonstrate build scan capabilities. If you wish to use it, clone or download the repository located at[https://github.com/gradle/gradle-build-scan-quickstart](https://github.com/gradle/gradle-build-scan-quickstart). If you prefer to use your own project, you can skip this step. +### 自动使用 build scan 插件 -## [Auto-apply the build scan plugin](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#auto_apply_the_build_scan_plugin) {#auto_apply_the_build_scan_plugin} - -Starting with Gradle 4.3, you can enable build scans without any additional configuration in your build script. When using the command line option`--scan`to publish a build scan, the required build scan plugin is applied automatically. Before the end of the build, you are asked to accept the license agreement on the command line. The following console output demonstrates the behavior. +从 Gradle 4.3 开始, 你可以直接使用 build scans, 不再需要添加额外的配置. 当使用命令行选项 `--scan` 来发布一个 build scan, build scan 插件就会自动被运行. 在构建结束之前, 你会被询问是否同意接受 license agreement: ``` $ ./gradlew build --scan From f2a8a6910a5f0b9ec841b59d5bbeb5f27c529ea7 Mon Sep 17 00:00:00 2001 From: DONG Date: Sun, 25 Mar 2018 03:19:34 +0000 Subject: [PATCH 031/102] Updates chuang-jian-build-scans.md Auto commit by GitBook Editor --- chuang-jian-build-scans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chuang-jian-build-scans.md b/chuang-jian-build-scans.md index b13270e..a98c3ce 100644 --- a/chuang-jian-build-scans.md +++ b/chuang-jian-build-scans.md @@ -28,7 +28,7 @@ Publishing build scan... https://gradle.com/s/czajmbyg73t62 ``` -This mechanism makes it very easy to generate ad-hoc, one-off build scans without having to configure the build scan plugin in your build. If you need finer grained configuration, you can configure the build scan plugin in a build or init script as described in the following sections. +这样就可以非常简单的创建 ad-hoc, 一次性的 build scans 而不需要进行额外的配置. If you need finer grained configuration, you can configure the build scan plugin in a build or init script as described in the following sections. ## [Enable build scans on all builds of your project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_on_all_builds_of_your_project) {#enable_build_scans_on_all_builds_of_your_project} From fece2d7c93fc3cd6de09a3647cbdf0e32a177b4b Mon Sep 17 00:00:00 2001 From: DONG Date: Sun, 25 Mar 2018 03:24:44 +0000 Subject: [PATCH 032/102] Updates cong-maven-qian-yi-dao-gradle.md Auto commit by GitBook Editor --- SUMMARY.md | 9 +- cong-maven-qian-yi-dao-gradle.md | 503 +++++++++++++++++++++++++++++++ 2 files changed, 506 insertions(+), 6 deletions(-) create mode 100644 cong-maven-qian-yi-dao-gradle.md diff --git a/SUMMARY.md b/SUMMARY.md index 76c457a..c4e95b6 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -20,6 +20,7 @@ * [探索和DEBUG你的构建](tan-suo-he-debug-ni-de-gou-jian.md) * [下一步](xia-yi-bu.md) * [创建 Build Scans](chuang-jian-build-scans.md) +* [从 Maven 迁移到 Gradle](cong-maven-qian-yi-dao-gradle.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) @@ -77,11 +78,7 @@ * [查看特定依赖](using_the_gradle_command-line/getting_the_insight_into_a_particular_dependency.md) * [获取项目属性列表](using_the_gradle_command-line/listing_project_properties.md) * [构建日志](using_the_gradle_command-line/profiling_a_build.md) -* [使用 Gradle 图形界面](using_the_gradle_graphical_user_interface/README.md) - * [任务树](using_the_gradle_graphical_user_interface/task_tree.md) - * [收藏夹](using_the_gradle_graphical_user_interface/favorities.md) - * [命令行](using_the_gradle_graphical_user_interface/command_line.md) - * [设置](using_the_gradle_graphical_user_interface/setup.md) +* 从 Maven 迁移到 Gradle * [编写构建脚本](writing_build_scripts/README.md) * [Gradle 构建语言](writing_build_scripts/the_gradle_build_language.md) * [项目 API](writing_build_scripts/the_project_api.md) @@ -211,5 +208,5 @@ * [War](the_war_plugin/war.md) * [定制War](the_war_plugin/customizing.md) * 创建一个 Gradle 项目 - * 初始化项目 + * [初始化项目](chu-shi-hua-xiang-mu.md) diff --git a/cong-maven-qian-yi-dao-gradle.md b/cong-maven-qian-yi-dao-gradle.md new file mode 100644 index 0000000..4ea0578 --- /dev/null +++ b/cong-maven-qian-yi-dao-gradle.md @@ -0,0 +1,503 @@ +# 从 Maven 迁移到 Gradle + +"Welcome to the Gradle community!"…​ at least that’s what we hope to say once you’ve completed this guide. + +Converting a build can be scary, but you don’t have to do it alone. You can search docs, forums, and StackOverflow from[help.gradle.org](https://gradle.org/help)or reach out to the[Gradle community on the forums](https://discuss.gradle.org/c/help-discuss)if you get stuck. + +[Apache Maven](https://maven.apache.org/)is a build tool for Java and other JVM-based projects that’s in widespread use, and so people that want to use Gradle often have to migrate an existing Maven build. This guide will help with such a migration by explaining the differences and similarities between the two tools' models and providing steps that you can follow to ease the process. + +Contents + +* [Making a case for migration](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#making_a_case_for_migration) +* [Understanding the functional differences](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#understanding_the_functional_differences) +* [Automated conversion](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#automated_conversion) +* [Bills of Materials \(BOMs\)](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#bills_of_materials_boms) +* [Provided scope and optional dependencies](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#provided_scope_and_optional_dependencies) +* [Maven profiles and properties](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#maven_profiles_and_properties) +* [Resource filtering](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#resource_filtering) +* [Integration tests](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#integration_tests) +* [Common plugins](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#common_plugins) +* [Plugins you don’t need](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#plugins_you_don_t_need) +* [Uncommon and custom plugins](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#uncommon_and_custom_plugins) +* [Next steps](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#next_steps) +* [Help improve this guide](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#help_improve_this_guide) + +## [Making a case for migration](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#making_a_case_for_migration) {#making_a_case_for_migration} + +The primary differences between Gradle and Maven are flexibility, performance, user experience, and dependency management. A visual overview of these aspects is available in the[Maven vs Gradle feature comparison](https://gradle.org/maven-vs-gradle). + +Since Gradle 3.0, Gradle has invested heavily in making Gradle builds much faster, with features such as[build caching](https://blog.gradle.org/introducing-gradle-build-cache),[compile avoidance](https://blog.gradle.org/incremental-compiler-avoidance), and an improved incremental Java compiler. Gradle is now 2-10x faster than Maven for the vast majority of projects, even without using build caching. In-depth performance comparison and business cases for switching from Maven to Gradle can be found[here](https://gradle.org/gradle-vs-maven-performance/). + +## [Understanding the functional differences](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#understanding_the_functional_differences) {#understanding_the_functional_differences} + +Gradle and Maven have fundamentally different views on how to build a project. Gradle is based on a_graph of task dependencies_, where the tasks do the work. Maven uses a model of fixed, linear phases to which you can attach goals \(the things that do the work\). Despite this, migrations can be surprisingly easy because Gradle follows many of the same conventions as Maven and dependency management works in a similar way. + +One especially useful feature for understanding your new Gradle build is[build scans](https://scans.gradle.com/): these are web-based snapshots of a given build that allows collaborative debugging and fine-grained performance analysis. For example, here’s the[build timeline for the Groovy build](https://scans.gradle.com/s/u7uyv3vuyhrig/timeline): + +![](https://guides.gradle.org/migrating-from-maven/images/groovy-build-scan.png "groovy build scan") + +You can use build scans to debug dependency resolution, Gradle task execution, and many other aspects of your build. + +Once you’ve decided to go ahead with the migration, what should you do first? The best starting point is_recording the inputs and outputs_of your Maven build, so that you can verify that your new Gradle build is functionally equivalent. + +## [Automated conversion](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#automated_conversion) {#automated_conversion} + +Not only will the Gradle`init`task allow you to create a new skeleton project, but it will also automatically convert an existing Maven one to Gradle. All you have to do is run the command + +``` +$ gradle init +``` + +from the root project directory and let Gradle do its thing. That basically consists of parsing the existing POMs and generating corresponding Gradle build files plus a`settings.gradle`file if it’s a multi-project build. + +You’ll find that the new Gradle build includes any custom repositories specified in the POM, your external and inter-project dependencies, the appropriate plugins \(any of`maven`,`java`, and`war`\), and more. See the user guide for[a complete list of the automatic conversion features](https://docs.gradle.org/4.6/userguide/build_init_plugin.html#sec:pom_maven_conversion_). + +One thing to bear in mind is that assemblies are not automatically converted. They aren’t necessarily problematic to convert, but you will need to do some manual work. + +If you’re lucky and don’t have many plugins or much in the way of customisation in your Maven build, you can simply run + +``` +$ gradle build +``` + +once the migration has completed. This will run the tests and produce the required artifacts without any extra intervention on your part. + +## [Bills of Materials \(BOMs\)](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#bills_of_materials_boms) {#bills_of_materials_boms} + +Maven enables sharing constraints on dependencies by defining dependencies inside dependencyManagement section in a POM file with`pom`. This special type of POM \(a BOM\) can then be imported into other POMs so that you have consistent library versions across your projects. + +Gradle 4.6 and above supports importing BOMs, though in versions before Gradle 5.0 you must enable this explicitly by adding the following to your`settings.gradle`file: + +settings.gradle + +``` +enableFeaturePreview( +" +IMPROVED_POM_SUPPORT +" +) +``` + +The BOM support in Gradle works similar to using`import`when depending on a BOM in Maven. In Gradle however, it is done via a regular dependency declaration on the BOM. + +build.gradle + +``` +dependencies { + implementation +' +org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE +' + + + implementation +' +com.google.code.gson:gson +' + + implementation +' +dom4j:dom4j +' + +} +``` + +| | Spring Boot Dependencies BOM | +| :--- | :--- | +| | Dependencies without versions can now be resolved | + +More information is available in the user manual section on[importing version recommendations from a Maven BOM](https://docs.gradle.org/4.6/userguide/managing_transitive_dependencies.html#sec:bom_import). + +| | Gradle versions 4.5 and lower do not support BOMs directly, but you can make use of them in your Gradle build files by using the[nebula-dependency-recommender-plugin](https://github.com/nebula-plugins/nebula-dependency-recommender-plugin#1-usage)from Netflix. | +| :--- | :--- | + + +## [Provided scope and optional dependencies](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#provided_scope_and_optional_dependencies) {#provided_scope_and_optional_dependencies} + +Gradle has a lot of flexibility in the way that dependencies are managed, particularly through configurations. However, it doesn’t have a scope named`provided`out of the box unless you use the`war`plugin. The same basic behavior can be had from the[compileOnly](https://blog.gradle.org/introducing-compile-only-dependencies)configuration added in Gradle 2.12. + +Regarding`optional`dependencies, Gradle 4.6+ creates dependency constraints when consuming POM files. For versions before Gradle 5.0, you must add`enableFeaturePreview('IMPROVED_POM_SUPPORT')`to_settings.gradle_. + +Learn more about dependency constraints in the[Gradle user manual on managing transitive dependencies](https://docs.gradle.org/4.6/userguide/managing_transitive_dependencies.html#sec:dependency_constraints). + +| | Gradle 4.5 and lower do not support optional dependencies, but you can make use of them in your Gradle builds by using the[optional-base plugin](https://plugins.gradle.org/plugin/nebula.optional-base)from Netflix. | +| :--- | :--- | + + +## [Maven profiles and properties](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#maven_profiles_and_properties) {#maven_profiles_and_properties} + +Maven allows you parameterize builds using properties of various sorts. Some are read-only properties of the project model, others are user-defined in the POM. It even allows you to treat system properties as project properties. + +Gradle has a similar system of project properties, although it differentiates between those and system properties. You can, for example, define properties in: + +* the build file + +* a`gradle.properties`file in the root project directory + +* a`gradle.properties`file in the`$HOME/.gradle`directory + +Those aren’t the only options, so if you are interested in finding out more about how and where you can define properties,[check out the user guide](https://docs.gradle.org/4.6/userguide/build_environment.html). + +One important piece of behavior you need to be aware of is what happens when the same property is defined in both the build file and one of the external properties files: the build file value takes precedence. Always. Fortunately, you can mimic the concept of profiles to provide overridable default values. + +Which brings us on to Maven profiles. These are a way to enable and disable different configurations based on environment, target platform, or any other similar factor. Logically, they are nothing more than limited ‘if' statements. And since Gradle has much more powerful ways to declare conditions, it does not need to have formal support for profiles \(except in the POMs of dependencies\). You can easily get the same behavior by combining conditions with secondary build files, as you’ll see next. + +Let’s say you have different deployment settings depending on environment: local development \(the default\), a test environment, and production. To add profile-like behavior, first create build files for each environment in the project root:`profile-default.gradle`,`profile-test.gradle`, and`profile-prod.gradle`. Next, add a condition similar to the following to the main build file: + +``` +if + (!hasProperty( +' +buildProfile +' +)) ext.buildProfile = +' +default +' + +apply +from +: +" +profile- +${ +buildProfile +} +.gradle +" +``` + +All you have to do then is put the environment-specific configuration, such as project properties, dependencies, etc., in the corresponding build file. To activate a particular profile, you can just pass in the relevant project property on the command line: + +``` +$ gradle -PbuildProfile=test build +``` + +Or you can set the project property another way. It’s up to you. And those conditions don’t just have to check project properties. You could check environment variables, the JDK version, the OS the build is running on, and anything else you can imagine. + +One thing to bear in mind is that high level ‘if' statements make builds harder to understand and maintain, similar to the way they complicate Object-Oriented code. The same applies to profiles. Gradle offers you many better ways to avoid the extensive use of profiles that Maven often requires, for example by offering variants. + +For a lengthier discussion on working with Maven profiles in Gradle, look no further than[this article](http://gradle.org/feature-spotlight-gradles-support-maven-pom-profiles)by Benjamin Muschko. + +## [Resource filtering](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#resource_filtering) {#resource_filtering} + +Maven has a phase called`process-resources`that has the goal`resources:resources`bound to it by default. This gives the build author an opportunity to perform variable substitution on various files, such as web resources, packaged properties files, etc. + +The Java plugin for Gradle provides a`processResources`task to do the same thing. Here’s an example configuration: + +build.gradle + +``` +processResources { + expand( +version +: version, +buildNumber +: currentBuildNumber) +} +``` + +So the left hand side of each colon is the token name and the right hand side is a project property. This variable substitution will apply to all your resource files \(the ones under`src/main/resources`usually\). + +Gradle has other powerful ways for property processing. You can hook in your own filter via a closure that allows you to process the content line by line, or you can add your own`FilterReader`implementation. For more details, see the documentation for the[ContentFilterable](https://docs.gradle.org/4.6/javadoc/org/gradle/api/file/ContentFilterable.html)interface which all copy and archive tasks implement. + +## [Integration tests](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#integration_tests) {#integration_tests} + +Although unit tests are very useful, they can’t ensure that an application or library works as a whole. It’s easy for bugs to appear in the interactions between objects and their interactions with the environment. That’s why many projects incorporate some form of higher level testing, sometimes termed integration, functional or acceptance testing. + +Maven supports these types of test by providing an extra set of phases:`pre-integration-test`,`integration-test`,`post-integration-test`, and`verify`. It also uses the Failsafe plugin rather than Surefire so that failed integration tests don’t automatically fail the build \(because you may need to clean up resources, such as a running application server\). + +Another factor to consider is where you keep your integration test classes. The default approach is to mix them with your unit test classes, but this is less than ideal. A common alternative is to use profiles so that you can keep the two types of test separate. + +So how should you approach migrating such a setup to Gradle? Forget plugins: source sets are your friends in this situation. A standard Java project already has two source sets for your main classes and your unit tests. Why not add an extra one for integration tests? Or even more than one for different types of integration test? Say low-level tests against a live database and higher level tests with something like FitNesse. + +By declaring a new source set, Gradle automatically sets you up with corresponding configurations \(`[sourceSet]Compile`and`[sourceSet]Runtime`\) as well as compilation tasks \(`compile[SourceSet][Lang]`\) and a resource processing task \(`process[SourceSet]Resources`\). All you need to do is add a task to run the tests and ensure that the classpaths are all set up. You might also want to add tasks for starting/stopping a database or application server if your tests require something like that. + +Let’s now take a look at an example so you can see what’s involved in practice: + +build.gradle + +``` +sourceSets { + integTest { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output + } +} +configurations { + integTestCompile.extendsFrom testCompile + integTestRuntime.extendsFrom testRuntime +} +``` + +In the above example, I create a new source set called`integTest`. I also make sure that the application or library classes, as well as their dependencies, are included on the classpath when compiling the integration tests. + +Your integration tests will probably use some third party libraries of their own, so you’ll want to add those the compilation classpath too. That’s done in the normal way in the`dependencies`block: + +build.gradle + +``` +dependencies { + +// ... + + integTestCompile +' +org.codehaus.groovy:groovy-all:2.4.3 +' + + integTestCompile +' +org.spockframework:spock-core:0.7-groovy-2.0 +' +, { + exclude +module +: +' +groovy-all +' + + } +} +``` + +The integration tests will now compile, but there is currently no way to run them. That’s where the custom`Test`task comes in: + +build.gradle + +``` +task integTest( +type +: Test) { + dependsOn startApp + finalizedBy stopApp + testClassesDirs = files(sourceSets.integTest.output.classesDirs) + classpath = sourceSets.integTest.runtimeClasspath + mustRunAfter test +} +``` + +In the above example, I’m assuming that the integration tests run against an application server that needs to be started and shut down at the appropriate times. You can learn more about how and what to configure on the`Test`task in Gradle’s[DSL Reference](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.testing.Test.html). + +All that’s left to do at this point is incorporate the`integTest`task into your task graph, for example by having`build`depend on it. It’s really up to you how you fit it into the build. If you want to support other test types, just rinse and repeat. + +## [Common plugins](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#common_plugins) {#common_plugins} + +Maven and Gradle share a common approach of extending the build through plugins. Although the plugin systems are very different beneath the surface, they share many feature-based plugins, such as: + +* Shade/Shadow + +* Jetty + +* Checkstyle + +* JaCoCo + +* AntRun \(see further down\) + +Why does this matter? Because many plugins rely on standard Java conventions, so migration is just a matter of replicating the configuration of the Maven plugin in Gradle. As an example, here’s a simple Maven Checkstyle plugin configuration: + +``` +... + +< +plugin +> +< +groupId +> +org.apache.maven.plugins +< +/groupId +> +< +artifactId +> +maven-checkstyle-plugin +< +/artifactId +> +< +version +> +2.17 +< +/version +> +< +executions +> +< +execution +> +< +id +> +validate +< +/id +> +< +phase +> +validate +< +/phase +> +< +configuration +> +< +configLocation +> +checkstyle.xml +< +/configLocation +> +< +encoding +> +UTF-8 +< +/encoding +> +< +consoleOutput +> +true +< +/consoleOutput +> +< +failsOnError +> +true +< +/failsOnError +> +< +linkXRef +> +false +< +/linkXRef +> +< +/configuration +> +< +goals +> +< +goal +> +check +< +/goal +> +< +/goals +> +< +/execution +> +< +/executions +> +< +/plugin +> + +... +``` + +Everything outside of the configuration block can safely be ignored when migrating to Gradle. In this case, the corresponding Gradle configuration looks like the following: + +``` +checkstyle { + config = resources.text.fromFile( +' +checkstyle.xml +' +, +' +UTF-8 +' +) + showViolations = +true + + ignoreFailures = +false + +} +``` + +The Checkstyle tasks are automatically added as dependencies of the`check`task, which also includes`test`. If you want to ensure that Checkstyle runs before the tests, then just specify an ordering with the mustRunAfter\(\) method: + +``` +test.mustRunAfter checkstyleMain, checkstyleTest +``` + +As you can see, the Gradle configuration is often much shorter than the Maven equivalent. You also have a much more flexible execution model since we are not longer constrained by Maven’s fixed phases. + +While migrating a project from Maven, don’t forget about source sets. These often provide a more elegant solution for handling integration tests or generated sources than Maven can provide, so you should factor them into your migration plans. + +### [Ant goals](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#ant_goals) {#ant_goals} + +Many Maven builds rely on the AntRun plugin to customize the build without the overhead of implementing a custom Maven plugin. Gradle has no equivalent plugin because Ant is a first-class citizen in Gradle builds, via the`ant`object. For example, you can use Ant’s Echo task like this: + +``` +task sayHello { + doLast { + ant.echo +message +: +' +Hello! +' + + } +} +``` + +Even Ant properties and filesets are supported natively. To learn more, check out the[Ant chapter](https://docs.gradle.org/4.6/userguide/ant.html)of the user guide. + +## [Plugins you don’t need](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#plugins_you_don_t_need) {#plugins_you_don_t_need} + +It’s worth remembering that Gradle builds are typically easier to extend and customize than Maven. In this context, that means you may not need a Gradle plugin to replace a Maven one. For example, the Maven Enforcer plugin allows you to control dependency versions and environmental factors, but these things can easily be configured in a normal Gradle build script. + +## [Uncommon and custom plugins](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#uncommon_and_custom_plugins) {#uncommon_and_custom_plugins} + +You may come across Maven plugins that have no counterpart in Gradle, particularly if you or someone in your organisation has written a custom plugin. Such cases rely on you understanding how Gradle \(and potentially Maven\) works, because you will usually have to write your own plugin. + +For the purposes of migration, there are two key types of Maven plugin: + +* Those that use the Maven project object. + +* Those that don’t. + +Why is this important? Because if you use one of the latter, you can trivially reimplement it as a Gradle task. Simply define task inputs and outputs to correspond to the mojo parameters and convert the execution logic into a task action. + +If a plugin depends on the Maven project, then you will have to rewrite it. Don’t start by considering how the Maven plugin works, but look at what problem it is trying to solve. Then try to work out how to solve that problem in Gradle. You’ll probably find that the two build models are different enough that "transcribing" Maven plugin code into a Gradle plugin just won’t be effective. On the plus side, the plugin is likely to be much easier to write than the original Maven one because Gradle has a much richer build model. + +If you do need to implement custom logic, either via build files or plugins, then be sure to familiarize yourself with Gradle’s[DSL Reference](https://docs.gradle.org/4.6/dsl/), which provides comprehensive documentation on the API that you’ll be working with. It details the standard configuration blocks \(and the objects that back them\), the core types in the system \(`Project`,`Task`, etc.\), and the standard set of tasks. The main entry point is the`Project`interface as that’s the top-level object that backs the build files. + +## [Next steps](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#next_steps) {#next_steps} + +You did it!**Welcome to the Gradle community!**🎉 + +Once you have your Gradle build working functionally, it is always worth a 2nd pass to ensure that your build is fast and maintainable. See Gradle documentation on[organizing build logic](https://docs.gradle.org/4.6/userguide/organizing_build_logic.html)and[optimizing build performance](https://guides.gradle.org/performance/). It would also be good to document any decisions made for your build, such as how you store and maintain dependency versions. + +If you[email us a build scan of your new Gradle build](mailto:developer-experience@gradle.com), we’ll send you a claim code for some free Gradle swag. + +Finally, don’t be afraid to ask for a build scan if another build user encounters trouble with the Gradle build. + +## [Help improve this guide](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#help_improve_this_guide) {#help_improve_this_guide} + +Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/migrating-from-maven](https://github.com/gradle-guides/migrating-from-maven/)and we’ll get back to you. + + + From 3a59ff8ab3a809b37161b4dadea0a6caa2a6b5e2 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:09:10 +0000 Subject: [PATCH 033/102] Updates README.md Auto commit by GitBook Editor --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5fef7f1..1546c84 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,13 @@ --- -### 如何参与 +### 如何参与&联系我们 -任何问题都欢迎直接联系我 dongchuanyz@163.com或者我们的 QQ群 324020116 +* 邮箱 dongchuanyz@163.com +* 微信 dongchuan55 +* QQ群 324020116 + +任何问题都欢迎直接联系我们 Gitbook 提供了非常棒的在线编辑功能, 所以想贡献的同学可以直接联系我申请权限! @@ -32,7 +36,7 @@ Gitbook 提供了非常棒的在线编辑功能, 所以想贡献的同学可以 | 成员 | 联系方式 | Github | | :--- | :--- | :--- | -| dongchuan55 | dongchuan55@gmail.com | [Github](https://github.com/DONGChuan) | +| dongchuan55 | dongchuanyz@163.com | [Github](https://github.com/DONGChuan) | | UFreedom | sunfreedom@sina.cn | [Github](https://github.com/UFreedom) | | 张扬 | zhangyang911120@gmail.com | [Github](https://github.com/dreamkidd) | | d0048 | d0048@foxmail.com | [Github](https://github.com/D0048) | From 09e61e498b881dbb84b3a174dc166c2f0e4dad82 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:49:09 +0000 Subject: [PATCH 034/102] Updates chuang-jian-build-scans.md Auto commit by GitBook Editor --- chuang-jian-build-scans.md | 106 +++++++++---------------------------- 1 file changed, 26 insertions(+), 80 deletions(-) diff --git a/chuang-jian-build-scans.md b/chuang-jian-build-scans.md index a98c3ce..faebf82 100644 --- a/chuang-jian-build-scans.md +++ b/chuang-jian-build-scans.md @@ -28,58 +28,38 @@ Publishing build scan... https://gradle.com/s/czajmbyg73t62 ``` -这样就可以非常简单的创建 ad-hoc, 一次性的 build scans 而不需要进行额外的配置. If you need finer grained configuration, you can configure the build scan plugin in a build or init script as described in the following sections. +这样就可以非常简单的创建点对点形式的, 一次性的 build scans 而不需要进行额外的配置. 如果你需要更优化的配置方案, 你可以跟随下面的教程. -## [Enable build scans on all builds of your project](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_on_all_builds_of_your_project) {#enable_build_scans_on_all_builds_of_your_project} +### 在你项目的所有构建里都启动 build scans -Add a`plugins`block to the`build.gradle`file with the following contents: +在`build.gradle`文件里加入以下代码: ``` plugins { - id -' -com.gradle.build-scan -' - version -' -1.12.1 -' - + id 'com.gradle.build-scan' version '1.12.1' } ``` -| | Use latest plugin version which can be found on the[Gradle Plugin Portal](https://plugins.gradle.org/plugin/com.gradle.build-scan). | -| :--- | :--- | - - -If you already have a`plugins`block, always put the build scan plugin first. Adding it below any existing plugins will still work, but will miss useful information. +如果你已经有`plugins` 代码块了, 请把 build scan 插件放在第一个. 如果加在其它插件下面, 它任然能工作, 但是许多有用的信息可能就扫描不到了. -## [Accept the license agreement](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#accept_the_license_agreement) {#accept_the_license_agreement} +### 接受 license agreement -In order to publish build scans to[https://scans.gradle.com](https://scans.gradle.com/), you need to accept the license agreement. This can be done ad-hoc via the command line when publishing, but can also be specified in your Gradle build file, by adding the following section: +为了发布扫描结果到 [https://scans.gradle.com](https://scans.gradle.com/), 你需要接受 license 协议. 可以在发布的时候通过命令行接受, 也可以在 Gradle build 文件里提前配置好: ``` buildScan { - licenseAgreementUrl = -' -https://gradle.com/terms-of-service -' - - licenseAgree = -' -yes -' - + licenseAgreementUrl = 'https://gradle.com/terms-of-service' + licenseAgree = 'yes' } ``` -The`buildScan`block allows you to configure the plugin. Here you are setting two properties necessary to accept the license agreement. Other properties are available. See the[Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/)for details. +`buildScan`代码块是专门用来配置这个插件的. 这里仅列举了2个属性, 其余属性可以参见 [Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/). -## [Publish a build scan](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#publish_a_build_scan) {#publish_a_build_scan} +### 发布 build scan -A build scan is published using a command-line flag called`--scan`. +只需要添加在命令行末尾添加`--scan就可以发布` build scan. -Run a`build`task with the`--scan`option. When the build is completed, after uploading the build data to scans.gradle.com, you will be presented with a link to see your build scan. +运行`build --scan`任务. 当构建完成, 你就可以通过产生的链接去查看了 ``` $ ./gradlew build --scan @@ -90,80 +70,46 @@ Publishing build scan... https://gradle.com/s/47i5oe7dhgz2c ``` -## [Access the build scan online](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#access_the_build_scan_online) {#access_the_build_scan_online} - -The first time you follow the link, you will be asked to activate the created build scan. +### 查看网上的 build scan -The email you receive to activate your build scan will look similar to: +你第一次打开链接的时候, 需要通过邮箱激活, 邮件类似下图: ![](https://guides.gradle.org/creating-build-scans/images/build_scan_email.png "build scan email") -Follow the link provided in the email, and you will see the created build scan. +点击邮件内的链接, 就可以查看 build scan 了: ![](https://guides.gradle.org/creating-build-scans/images/build_scan_page.png "build scan page") -You can now explore all the information contained in the build scan, including the time taken for tasks to execute, the time required during each stage of the build, the results of any tests, plugins used and other dependencies, any command-line switches used, and more. +## 对系统上的所有构建都激活 Build Scan {#enable_build_scans_for_all_builds_optional} -## [Enable build scans for all builds \(optional\)](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#enable_build_scans_for_all_builds_optional) {#enable_build_scans_for_all_builds_optional} - -You can avoid having to add the plugin and license agreement to every build by using a Gradle init script. Create a file called`buildScan.gradle`in the directory`~/.gradle/init.d`\(where the tilde represents your home directory\) with the following contents: +你并不需要在项目里的每一个构建里都进行上述的操作. 你可以在HOME下面的`~/.gradle/init.d`创建一个叫做 `buildScan.gradl`的文件: ``` initscript { repositories { - maven { url -' -https://plugins.gradle.org/m2 -' - } + maven { url 'https://plugins.gradle.org/m2'} } dependencies { - classpath -' -com.gradle:build-scan-plugin:1.12.1 -' - + classpath 'com.gradle:build-scan-plugin:1.12.1' } } rootProject { - apply -plugin -: com.gradle.scan.plugin.BuildScanPlugin + apply plugin: com.gradle.scan.plugin.BuildScanPlugin buildScan { - licenseAgreementUrl = -' -https://gradle.com/terms-of-service -' - - licenseAgree = -' -yes -' - + licenseAgreementUrl = 'https://gradle.com/terms-of-service' + licenseAgree = 'yes' } } ``` -The init script downloads the build scan plugin if necessary and applies it to every project, and accepts the license agreement. Now you can use the`--scan`flag on any build on your system. - -There are additional capabilities you can add to the script, such as under what conditions to publish the scan information. For details, see the[Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/). - -## [Summary](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#summary) {#summary} - -In this guide, you learned how to: - -* Generate a build scan - -* View the build scan information online - -* Create an init script to enable build scans for all builds +然后, 在该系统的任何构建里, 你只需要添加`--scan` 就可以直接使用 Build Scan 了. -## [Next steps](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#next_steps) {#next_steps} +### 下一步 -Additional information can be found in the[Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/). +可以查看 [Build Scans User Manual](https://docs.gradle.com/build-scan-plugin/) 获得更多关于该插件的信息 ## [ ](https://guides.gradle.org/creating-build-scans/?_ga=2.115847618.599696663.1521685504-557532416.1521019880#help_improve_this_guide) {#help_improve_this_guide} From a4642ecd311cfe404a0b39a19d2ebb9812140b0b Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:50:39 +0000 Subject: [PATCH 035/102] Updates cong-maven-qian-yi-dao-gradle.md Auto commit by GitBook Editor --- cong-maven-qian-yi-dao-gradle.md | 73 ++++++-------------------------- 1 file changed, 13 insertions(+), 60 deletions(-) diff --git a/cong-maven-qian-yi-dao-gradle.md b/cong-maven-qian-yi-dao-gradle.md index 4ea0578..5cc4c6b 100644 --- a/cong-maven-qian-yi-dao-gradle.md +++ b/cong-maven-qian-yi-dao-gradle.md @@ -38,7 +38,7 @@ One especially useful feature for understanding your new Gradle build is[build s You can use build scans to debug dependency resolution, Gradle task execution, and many other aspects of your build. -Once you’ve decided to go ahead with the migration, what should you do first? The best starting point is_recording the inputs and outputs_of your Maven build, so that you can verify that your new Gradle build is functionally equivalent. +Once you’ve decided to go ahead with the migration, what should you do first? The best starting point is\_recording the inputs and outputs\_of your Maven build, so that you can verify that your new Gradle build is functionally equivalent. ## [Automated conversion](https://guides.gradle.org/migrating-from-maven/?_ga=2.79140304.599696663.1521685504-557532416.1521019880#automated_conversion) {#automated_conversion} @@ -71,11 +71,7 @@ Gradle 4.6 and above supports importing BOMs, though in versions before Gradle 5 settings.gradle ``` -enableFeaturePreview( -" -IMPROVED_POM_SUPPORT -" -) +enableFeaturePreview("IMPROVED_POM_SUPPORT") ``` The BOM support in Gradle works similar to using`import`when depending on a BOM in Maven. In Gradle however, it is done via a regular dependency declaration on the BOM. @@ -84,22 +80,9 @@ build.gradle ``` dependencies { - implementation -' -org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE -' - - - implementation -' -com.google.code.gson:gson -' - - implementation -' -dom4j:dom4j -' - + implementation 'org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE' + implementation 'com.google.code.gson:gson' + implementation 'dom4j:dom4j' } ``` @@ -141,31 +124,16 @@ Those aren’t the only options, so if you are interested in finding out more ab One important piece of behavior you need to be aware of is what happens when the same property is defined in both the build file and one of the external properties files: the build file value takes precedence. Always. Fortunately, you can mimic the concept of profiles to provide overridable default values. -Which brings us on to Maven profiles. These are a way to enable and disable different configurations based on environment, target platform, or any other similar factor. Logically, they are nothing more than limited ‘if' statements. And since Gradle has much more powerful ways to declare conditions, it does not need to have formal support for profiles \(except in the POMs of dependencies\). You can easily get the same behavior by combining conditions with secondary build files, as you’ll see next. +Which brings us on to Maven profiles. These are a way to enable and disable different configurations based on environment, target platform, or any other similar factor. Logically, they are nothing more than limited ‘if' statements. And since Gradle has much more powerful ways to declare conditions, it does not need to have formal support for profiles \(except in the POMs of dependencies\). You can easily get the same behavior by combining conditions with secondary build files, as you’ll see next. Let’s say you have different deployment settings depending on environment: local development \(the default\), a test environment, and production. To add profile-like behavior, first create build files for each environment in the project root:`profile-default.gradle`,`profile-test.gradle`, and`profile-prod.gradle`. Next, add a condition similar to the following to the main build file: ``` if - (!hasProperty( -' -buildProfile -' -)) ext.buildProfile = -' -default -' + (!hasProperty('buildProfile' +)) ext.buildProfile = 'default' -apply -from -: -" -profile- -${ -buildProfile -} -.gradle -" +apply from: "profile-${buildProfile}.gradle" ``` All you have to do then is put the environment-specific configuration, such as project properties, dependencies, etc., in the corresponding build file. To activate a particular profile, you can just pass in the relevant project property on the command line: @@ -239,26 +207,13 @@ build.gradle ``` dependencies { - -// ... - integTestCompile -' -org.codehaus.groovy:groovy-all:2.4.3 -' +// ... - integTestCompile -' -org.spockframework:spock-core:0.7-groovy-2.0 -' + integTestCompile 'org.codehaus.groovy:groovy-all:2.4.3' + integTestCompile 'org.spockframework:spock-core:0.7-groovy-2.0' , { - exclude -module -: -' -groovy-all -' - + exclude module: 'groovy-all' } } ``` @@ -499,5 +454,3 @@ Finally, don’t be afraid to ask for a build scan if another build user encount Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/migrating-from-maven](https://github.com/gradle-guides/migrating-from-maven/)and we’ll get back to you. - - From a10d2b5c722807aa1232ec2e1ab8be827277dcfb Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:55:40 +0000 Subject: [PATCH 036/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- SUMMARY.md | 36 ++++-- cong-maven-qian-yi-dao-gradle.md | 2 - .../ming-ling-xing-jie-mian.md | 36 ++++++ .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 120 ++++++++++++++++++ 4 files changed, 178 insertions(+), 16 deletions(-) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md diff --git a/SUMMARY.md b/SUMMARY.md index c4e95b6..c026be6 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -7,20 +7,6 @@ * [特点](overview/features.md) * [为什么用 Groovy?](overview/why_groovy.md) * [教程](tutorials/README.md) -* [安装Gradle](installing_gradle/README.md) - * [预备知识](installing_gradle/yu-bei-zhi-shi.md) - * [通过 Package Manager 安装](installing_gradle/tong-guo-package-manager-an-zhuang.md) - * [手动安装](installing_gradle/shou-dong-an-zhuang.md) - * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) - * [下一步](installing_gradle/xia-yi-bu.md) -* [创建一个 Gradle 项目](chuangjian-yi-ge-gradle-xiang-mu.md) - * [初始化项目](chu-shi-hua-xiang-mu.md) - * [创建 Task](chuang-jian-task.md) - * [使用插件](shi-yong-cha-jian.md) - * [探索和DEBUG你的构建](tan-suo-he-debug-ni-de-gou-jian.md) - * [下一步](xia-yi-bu.md) -* [创建 Build Scans](chuang-jian-build-scans.md) -* [从 Maven 迁移到 Gradle](cong-maven-qian-yi-dao-gradle.md) * [构建脚本基础](build_script_basics/README.md) * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) * [Hello world](build_script_basics/hello_world.md) @@ -210,3 +196,25 @@ * 创建一个 Gradle 项目 * [初始化项目](chu-shi-hua-xiang-mu.md) +## 开始 + +* [安装Gradle](installing_gradle/README.md) + * [预备知识](installing_gradle/yu-bei-zhi-shi.md) + * [通过 Package Manager 安装](installing_gradle/tong-guo-package-manager-an-zhuang.md) + * [手动安装](installing_gradle/shou-dong-an-zhuang.md) + * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) + * [下一步](installing_gradle/xia-yi-bu.md) +* [创建一个 Gradle 项目](chuangjian-yi-ge-gradle-xiang-mu.md) + * [初始化项目](chu-shi-hua-xiang-mu.md) + * [创建 Task](chuang-jian-task.md) + * [使用插件](shi-yong-cha-jian.md) + * [探索和DEBUG你的构建](tan-suo-he-debug-ni-de-gou-jian.md) + * [下一步](xia-yi-bu.md) +* [创建 Build Scans](chuang-jian-build-scans.md) +* [从 Maven 迁移到 Gradle](cong-maven-qian-yi-dao-gradle.md) + +## 使用 Gradle 构建 + +* [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) + * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md) + diff --git a/cong-maven-qian-yi-dao-gradle.md b/cong-maven-qian-yi-dao-gradle.md index 5cc4c6b..b4767e5 100644 --- a/cong-maven-qian-yi-dao-gradle.md +++ b/cong-maven-qian-yi-dao-gradle.md @@ -1,7 +1,5 @@ # 从 Maven 迁移到 Gradle -"Welcome to the Gradle community!"…​ at least that’s what we hope to say once you’ve completed this guide. - Converting a build can be scary, but you don’t have to do it alone. You can search docs, forums, and StackOverflow from[help.gradle.org](https://gradle.org/help)or reach out to the[Gradle community on the forums](https://discuss.gradle.org/c/help-discuss)if you get stuck. [Apache Maven](https://maven.apache.org/)is a build tool for Java and other JVM-based projects that’s in widespread use, and so people that want to use Gradle often have to migrate an existing Maven build. This guide will help with such a migration by explaining the differences and similarities between the two tools' models and providing steps that you can follow to ease the process. diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md new file mode 100644 index 0000000..2d84c9a --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md @@ -0,0 +1,36 @@ +The command-line interface is one of the primary methods of interacting with Gradle. The following serves as a reference of executing and customizing Gradle use of a command-line or when writing scripts or configuring continuous integration. + +Use of the[Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html)is highly encouraged. You should substitute`./gradlew`or`gradlew.bat`for`gradle`in all following examples when using the Wrapper. + +Executing Gradle on the command-line conforms to the following structure. Options are allowed before and after task names. + +``` +gradle [taskName...] [--option-name...] +``` + +If multiple tasks are specified, they should be separated with a space. + +Options that accept values can be specified with or without`=`between the option and argument; however, use of`=`is recommended. + +``` +--console=plain +``` + +Options that enable behavior have long-form options with inverses specified with`--no-`. The following are opposites. + +``` +--build-cache +--no-build-cache +``` + +Many long-form options, have short option equivalents. The following are equivalent: + +``` +--help +-h +``` + +Many command-line flags can be specified in`gradle.properties`to avoid needing to be typed. See the[configuring build environment guide](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties)for details. + +The following sections describe use of the Gradle command-line interface, grouped roughly by user goal. Some plugins also add their own command line options, for example[`--tests`for Java test filtering](https://docs.gradle.org/current/userguide/java_plugin.html#test_filtering). For more information on exposing command line options for your own tasks, see[the section called “Declaring and Using Command Line Options”](https://docs.gradle.org/current/userguide/custom_tasks.html#sec:declaring_and_using_command_line_options). + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md new file mode 100644 index 0000000..a2fe19f --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -0,0 +1,120 @@ +You can run a task and all of its[dependencies](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:task_dependencies). + +``` +❯ gradle myTask +``` + +You can learn about what projects and tasks are available in the[project reporting section](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_project_reporting). + +### Executing tasks in multi-project builds + +In a[multi-project build](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html), subproject tasks can be executed with ":" separating subproject name and task name. The following are equivalent_when run from the root project_. + +``` +❯ gradle :mySubproject:taskName +❯ gradle mySubproject:taskName +``` + +You can also run a task for all subprojects using the task name only. For example, this will run the "test" task for all subprojects when invoked from the root project directory. + +``` +❯ gradle test +``` + +When invoking Gradle from within a subproject, the project name should be omitted: + +``` +❯ cd mySubproject +❯ gradle taskName +``` + +When executing the Gradle Wrapper from subprojects, one must reference`gradlew`relatively. For example:`../gradlew taskName`. The community[gdub project](http://www.gdub.rocks/)aims to make this more convenient. + +### Executing multiple tasks + +You can also specify multiple tasks. For example, the following will execute the`test`and`deploy`tasks in the order that they are listed on the command-line and will also execute the dependencies for each task. + +``` +❯ gradle test deploy +``` + +### Excluding tasks from execution + +You can exclude a task from being executed using the`-x`or`--exclude-task`command-line option and providing the name of the task to exclude. + + + +**Figure: Example Task Graph** + +![](https://docs.gradle.org/current/userguide/img/commandLineTutorialTasks.png "Example Task Graph") + + + +**Example: Excluding tasks** + +Output of**`gradle dist --exclude-task test`** + +``` +> + gradle dist --exclude-task test +:compile +compiling source +:dist +building the distribution + +BUILD SUCCESSFUL in 0s +2 actionable tasks: 2 executed + +``` + +You can see that the`test`task is not executed, even though it is a dependency of the`dist`task. The`test`task’s dependencies such as`compileTest`are not executed either. Those dependencies of`test`that are required by another task, such as`compile`, are still executed. + +### Forcing tasks to execute + +You can force Gradle to execute all tasks ignoring[up-to-date checks](https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks)using the`--rerun-tasks`option: + +``` +❯ gradle test --rerun-tasks +``` + +This will force`test`and_all_task dependencies of`test`to execute. It’s a little like running`gradle clean test`, but without the build’s generated output being deleted. + +### Continuing the build when a failure occurs + +By default, Gradle will abort execution and fail the build as soon as any task fails. This allows the build to complete sooner, but hides other failures that would have occurred. In order to discover as many failures as possible in a single build execution, you can use the`--continue`option. + +``` +❯ gradle test --continue +``` + +When executed with`--continue`, Gradle will execute_every_task to be executed where all of the dependencies for that task completed without failure, instead of stopping as soon as the first failure is encountered. Each of the encountered failures will be reported at the end of the build. + +If a task fails, any subsequent tasks that were depending on it will not be executed. For example, tests will not run if there is a compilation failure in the code under test; because the test task will depend on the compilation task \(either directly or indirectly\). + +### Task name abbreviation + +When you specify tasks on the command-line, you don’t have to provide the full name of the task. You only need to provide enough of the task name to uniquely identify the task. For example, it’s likely`gradle che`is enough for Gradle to identify the`check`task. + +You can also abbreviate each word in a camel case task name. For example, you can execute task`compileTest`by running`gradle compTest`or even`gradle cT`. + + + +**Example: Abbreviated camel case task name** + +Output of**`gradle cT`** + +``` +> + gradle cT +:compile +compiling source +:compileTest +compiling unit tests + +BUILD SUCCESSFUL in 0s +2 actionable tasks: 2 executed + +``` + +You can also use these abbreviations with the -x command-line option. + From 0d037451ed4c6b99bbeacab835b344108154be00 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:56:39 +0000 Subject: [PATCH 037/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../chang-yong-tasks.md | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md diff --git a/SUMMARY.md b/SUMMARY.md index c026be6..dd0b5a4 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -217,4 +217,5 @@ * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md) + * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md new file mode 100644 index 0000000..3bf9989 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md @@ -0,0 +1,38 @@ +# 常用 Tasks + +The following are task conventions applied by built-in and most major Gradle plugins. + +### Computing all outputs + +It is common in Gradle builds for the`build`task to designate assembling all outputs and running all checks. + +``` +❯ gradle build +``` + +### Running applications + +It is common for applications to be run with the`run`task, which assembles the application and executes some script or binary. + +``` +❯ gradle run +``` + +### Running all checks + +It is common for_all_verification tasks, including tests and linting, to be executed using the`check`task. + +``` +❯ gradle check +``` + +### Cleaning outputs + +You can delete the contents of the build directory using the`clean`task, though doing so will cause pre-computed outputs to be lost, causing significant additional build time for the subsequent task execution. + +``` +❯ gradle clean +``` + + + From 8e771a1e71087fd373fdcd12b73286672d9811c8 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:58:02 +0000 Subject: [PATCH 038/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../xiang-mu-bao-gao.md | 139 ++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md diff --git a/SUMMARY.md b/SUMMARY.md index dd0b5a4..c399ea5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -218,4 +218,5 @@ * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md) + * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md new file mode 100644 index 0000000..28755d9 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md @@ -0,0 +1,139 @@ +# 项目报告 + +Gradle provides several built-in tasks which show particular details of your build. This can be useful for understanding the structure and dependencies of your build, and for debugging problems. + +You can get basic help about available reporting options using`gradle help`. + +### Listing projects + +Running`gradle projects`gives you a list of the sub-projects of the selected project, displayed in a hierarchy. + +``` +❯ gradle projects +``` + +You also get a project report within build scans. Learn more about[creating build scans](https://guides.gradle.org/creating-build-scans/). + +### Listing tasks + +Running`gradle tasks`gives you a list of the main tasks of the selected project. This report shows the default tasks for the project, if any, and a description for each task. + +``` +❯ gradle tasks +``` + +By default, this report shows only those tasks which have been assigned to a task group. You can obtain more information in the task listing using the`--all`option. + +``` +❯ gradle tasks --all +``` + +### Show task usage details + +Running`gradle help --task someTask`gives you detailed information about a specific task. + + + +**Example: Obtaining detailed help for tasks** + +Output of**`gradle -q help --task libs`** + +``` +> + gradle -q help --task libs +Detailed task information for libs + +Paths + :api:libs + :webapp:libs + +Type + Task (org.gradle.api.Task) + +Description + Builds the JAR + +Group + build + +``` + +This information includes the full task path, the task type, possible command line options and the description of the given task. + +### Reporting dependencies + +Build scans give a full, visual report of what dependencies exist on which configurations, transitive dependencies, and dependency version selection. + +``` +❯ gradle myTask --scan +``` + +This will give you a link to a web-based report, where you can find dependency information like this. + +![](https://docs.gradle.org/current/userguide/img/gradle-core-test-build-scan-dependencies.png "Build Scan dependencies report") + +Learn more in[Inspecting Dependencies](https://docs.gradle.org/current/userguide/inspecting_dependencies.html). + +### Listing project dependencies + +Running`gradle dependencies`gives you a list of the dependencies of the selected project, broken down by configuration. For each configuration, the direct and transitive dependencies of that configuration are shown in a tree. Below is an example of this report: + +``` +❯ gradle dependencies +``` + +Concrete examples of build scripts and output available in the[Inspecting Dependencies](https://docs.gradle.org/current/userguide/inspecting_dependencies.html). + +Running`gradle buildEnvironment`visualises the buildscript dependencies of the selected project, similarly to how`gradle dependencies`visualizes the dependencies of the software being built. + +``` +❯ gradle buildEnvironment +``` + +Running`gradle dependencyInsight`gives you an insight into a particular dependency \(or dependencies\) that match specified input. + +``` +❯ gradle dependencyInsight +``` + +Since a dependency report can get large, it can be useful to restrict the report to a particular configuration. This is achieved with the optional`--configuration`parameter: + +### Listing project properties + +Running`gradle properties`gives you a list of the properties of the selected project. + + + +**Example: Information about properties** + +Output of**`gradle -q api:properties`** + +``` +> + gradle -q api:properties + +------------------------------------------------------------ +Project :api - The shared API for the application +------------------------------------------------------------ + +allprojects: [project ':api'] +ant: org.gradle.api.internal.project.DefaultAntBuilder@12345 +antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345 +artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345 +asDynamicObject: DynamicObject for project ':api' +baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345 +buildDir: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build +buildFile: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build.gradle + +``` + +### Software Model reports + +You can get a hierarchical view of elements for[software model](https://docs.gradle.org/current/userguide/software_model.html)projects using the`model`task: + +``` +❯ gradle model +``` + +Learn more about[the model report](https://docs.gradle.org/current/userguide/software_model.html#model-report)in the software model documentation. + From 0e7f3bcf6331ff10cff5aa862c8386d2fd6e21fd Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 13:59:17 +0000 Subject: [PATCH 039/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md diff --git a/SUMMARY.md b/SUMMARY.md index c399ea5..ba5f8dd 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -219,4 +219,5 @@ * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md) * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) + * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md new file mode 100644 index 0000000..7c18b96 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md @@ -0,0 +1,10 @@ +# 命令行补全 + +Gradle provides bash and zsh tab completion support for tasks, options, and Gradle properties through[gradle-completion](https://github.com/gradle/gradle-completion), installed separately. + + + +**Figure: Gradle Completion** + +![](https://docs.gradle.org/current/userguide/img/gradle-completion-4.0.gif "Gradle Completion") + From 22ccb79bffe65f7dc6aed1d4edaa2be931bd6245 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:01:21 +0000 Subject: [PATCH 040/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md Auto commit by GitBook Editor --- SUMMARY.md | 2 + .../debug-xuan-xiang.md | 30 ++++++++ .../performance-xuan-xiang.md | 76 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md diff --git a/SUMMARY.md b/SUMMARY.md index ba5f8dd..d796fdd 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -220,4 +220,6 @@ * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md) * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) + * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md) + * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md new file mode 100644 index 0000000..5e091a8 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md @@ -0,0 +1,30 @@ +# Debug 选项 + +`-?`,`-h`,`--help` + +Shows a help message with all available CLI options. + +`-v`,`--version` + +Prints Gradle, Groovy, Ant, JVM, and operating system version information. + +`-S`,`--full-stacktrace` + +Print out the full \(very verbose\) stacktrace for any exceptions. See also[logging options](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging). + +`-s`,`--stacktrace` + +Print out the stacktrace also for user exceptions \(e.g. compile error\). See also[logging options](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging). + +`--scan` + +Create a[build scan](https://gradle.com/build-scans)with fine-grained information about all aspects of your Gradle build. + +`-Dorg.gradle.debug=true` + +Debug Gradle client \(non-Daemon\) process. Gradle will wait for you to attach a debugger at`localhost:5005`by default. + +`-Dorg.gradle.daemon.debug=true` + +Debug[Gradle Daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html)process. + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md new file mode 100644 index 0000000..a395ccb --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md @@ -0,0 +1,76 @@ +# Performance 选项 + +Try these options when optimizing build performance. Learn more about[improving performance of Gradle builds here](https://guides.gradle.org/performance/). + +Many of these options can be specified in`gradle.properties`so command-line flags are not necessary. See the[configuring build environment guide](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties). + +`--build-cache` + +, + +`--no-build-cache` + +Toggles the[Gradle build cache](https://docs.gradle.org/current/userguide/build_cache.html). Gradle will try to reuse outputs from previous builds._Default is off_. + +`--configure-on-demand` + +, + +`--no-configure-on-demand` + +Toggles[Configure-on-demand](https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:configuration_on_demand). Only relevant projects are configured in this build run._Default is off_. + +`--max-workers` + +Sets maximum number of workers that Gradle may use._Default is number of processors_. + +`--parallel` + +, + +`--no-parallel` + +Build projects in parallel. For limitations of this option please see[the section called “Parallel project execution”](https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:parallel_execution)._Default is off_. + +`--profile` + +Generates a high-level performance report in the`$buildDir/reports/profile`directory.`--scan`is preferred. + +`--scan` + +Generate a build scan with detailed performance diagnostics. + +![](https://docs.gradle.org/current/userguide/img/gradle-core-test-build-scan-performance.png "Build Scan performance report") + +### Gradle daemon options + +You can manage the[Gradle Daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html)through the following command line options. + +`--daemon` + +, + +`--no-daemon` + +Use the[Gradle Daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html)to run the build. Starts the daemon if not running or existing daemon busy._Default is on_. + +`--foreground` + +Starts the Gradle Daemon in a foreground process. + +`--status` + +\(Standalone command\) + +Run`gradle --status`to list running and recently stopped Gradle daemons. Only displays daemons of the same Gradle version. + +`--stop` + +\(Standalone command\) + +Run`gradle --stop`to stop all Gradle Daemons of the same version. + +`-Dorg.gradle.daemon.idletimeout=(number of milliseconds)` + +Gradle Daemon will stop itself after this number of milliseconds of idle time._Default is 10800000_\(3 hours\). + From 612896915a7cdfccc1135beb5c827acebfb95508 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:03:38 +0000 Subject: [PATCH 041/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md Auto commit by GitBook Editor --- SUMMARY.md | 3 + .../environment-xuan-xiang.md | 48 ++++++++ .../execution-xuan-xiang.md | 22 ++++ .../logging-xuan-xiang.md | 104 ++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md diff --git a/SUMMARY.md b/SUMMARY.md index d796fdd..b711c5a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -222,4 +222,7 @@ * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md) * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) + * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) + * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md) + * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md new file mode 100644 index 0000000..8523497 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md @@ -0,0 +1,48 @@ +# Environment 选项 + +You can customize many aspects about where build scripts, settings, caches, and so on through the options below. Learn more about customizing your[build environment](https://docs.gradle.org/current/userguide/build_environment.html). + +`-b`,`--build-file` + +Specifies the build file. For example:`gradle --build-file=foo.gradle`. The default is`build.gradle`, then`build.gradle.kts`, then`myProjectName.gradle`. + +`-c`,`--settings-file` + +Specifies the settings file. For example:`gradle --settings-file=somewhere/else/settings.gradle` + +`-g`,`--gradle-user-home` + +Specifies the Gradle user home directory. The default is the`.gradle`directory in the user’s home directory. + +`-p`,`--project-dir` + +Specifies the start directory for Gradle. Defaults to current directory. + +`--project-cache-dir` + +Specifies the project-specific cache directory. Default value is`.gradle`in the root project directory. + +`-u`,`--no-search-upward`\(deprecated\) + +Don’t search in parent directories for a`settings.gradle`file. + +`-D`,`--system-prop` + +Sets a system property of the JVM, for example`-Dmyprop=myvalue`. See[the section called “System properties”](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_system_properties). + +`-I`,`--init-script` + +Specifies an initialization script. See[Initialization Scripts](https://docs.gradle.org/current/userguide/init_scripts.html). + +`-P`,`--project-prop` + +Sets a project property of the root project, for example`-Pmyprop=myvalue`. See[the section called “Project properties”](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties). + +`-Dorg.gradle.jvmargs` + +Set JVM arguments. + +`-Dorg.gradle.java.home` + +Set JDK home dir. + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md new file mode 100644 index 0000000..bb9926c --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md @@ -0,0 +1,22 @@ +# Execution 选项 + +The following options affect how builds are executed, by changing what is built or how dependencies are resolved. + +`--include-build` + +Run the build as a composite, including the specified build. See[Composite Builds](https://docs.gradle.org/current/userguide/composite_builds.html). + +`--offline` + +Specifies that the build should operate without accessing network resources. Learn more about[options to override dependency caching](https://docs.gradle.org/current/userguide/troubleshooting_dependency_resolution.html#sec:controlling_dependency_caching_command_line). + +`--refresh-dependencies` + +Refresh the state of dependencies. Learn more about how to use this in the[dependency management docs](https://docs.gradle.org/current/userguide/troubleshooting_dependency_resolution.html#sec:controlling_dependency_caching_command_line). + +`--dry-run` + +Run Gradle with all task actions disabled. Use this to show which task would have executed. + + + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md new file mode 100644 index 0000000..20cf4fa --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md @@ -0,0 +1,104 @@ +# Logging 选项 + +### Setting log level + +You can customize the verbosity of Gradle logging with the following options, ordered from least verbose to most verbose. Learn more in the[logging documentation](https://docs.gradle.org/current/userguide/logging.html). + +`-Dorg.gradle.logging.level=(quiet,warn,lifecycle,info,debug)` + +Set logging level via Gradle properties. + +`-q` + +, + +`--quiet` + +Log errors only. + +`-w` + +, + +`--warn` + +Set log level to warn. + +`-i` + +, + +`--info` + +Set log level to info. + +`-d` + +, + +`--debug` + +Log in debug mode \(includes normal stacktrace\). + +Lifecycle is the default log level. + +### Customizing log format + +You can control the use of rich output \(colors and font variants\) by specifying the "console" mode in the following ways: + +`-Dorg.gradle.console=(auto,plain,rich,verbose)` + +Specify console mode via Gradle properties. Different modes described immediately below. + +`--console=(auto,plain,rich,verbose)` + +Specifies which type of console output to generate. + +Set to`plain`to generate plain text only. This option disables all color and other rich output in the console output. This is the default when Gradle is_not_attached to a terminal. + +Set to`auto`\(the default\) to enable color and other rich output in the console output when the build process is attached to a console, or to generate plain text only when not attached to a console._This is the default when Gradle is attached to a terminal._ + +Set to`rich`to enable color and other rich output in the console output, regardless of whether the build process is not attached to a console. When not attached to a console, the build output will use ANSI control characters to generate the rich output. + +Set to`verbose`to enable color and other rich output like the`rich`, but output task names and outcomes at the lifecycle log level, as is done by default in Gradle 3.5 and earlier. + +### Showing or hiding warnings + +By default, Gradle won’t display all warnings \(e.g. deprecation warnings\). Instead, Gradle will collect them and render a summary at the end of the build like: + +``` +Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0. +``` + +You can control the verbosity of warnings on the console with the following options: + +`-Dorg.gradle.warning.mode=(all,none,summary)` + +Specify warning mode via[Gradle properties](https://docs.gradle.org/current/userguide/command_line_interface.html). Different modes described immediately below. + +`--warning-mode=(all,none,summary)` + +Specifies how to log warnings. Default is`summary`. + +Set to`all`to log all warnings. + +Set to`summary`to suppress all warnings and log a summary at the end of the build. + +Set to`none`to suppress all warnings, including the summary at the end of the build. + +### Rich Console + +Gradle’s rich console displays extra information while builds are running. + +![](https://docs.gradle.org/current/userguide/img/rich-cli.png "Gradle Rich Console") + +Features: + +* Logs above grouped by task that generated them + +* Progress bar and timer visually describe overall status + +* Parallel work-in-progress lines below describe what is happening now + + + From ca976318699ebc234c98261ef35d23aea29599b0 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:23:59 +0000 Subject: [PATCH 042/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index b711c5a..cf7e348 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -193,8 +193,6 @@ * [公共配置](the_war_plugin/convention_properties.md) * [War](the_war_plugin/war.md) * [定制War](the_war_plugin/customizing.md) -* 创建一个 Gradle 项目 - * [初始化项目](chu-shi-hua-xiang-mu.md) ## 开始 From 845570984d4ca3299c6219727e7ad2f680cdbb83 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:24:08 +0000 Subject: [PATCH 043/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index cf7e348..7735ef2 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -7,20 +7,6 @@ * [特点](overview/features.md) * [为什么用 Groovy?](overview/why_groovy.md) * [教程](tutorials/README.md) -* [构建脚本基础](build_script_basics/README.md) - * [Projects 和 tasks](build_script_basics/projects_and_tasks.md) - * [Hello world](build_script_basics/hello_world.md) - * [快捷的任务定义](build_script_basics/a_shortcut_task_definition.md) - * [构建脚本代码](build_script_basics/build_scripts_are_code.md) - * [任务依赖](build_script_basics/task_dependencies.md) - * [动态任务](build_script_basics/dynamic_tasks.md) - * [使用已经存在的任务](build_script_basics/manipulating_existing_tasks.md) - * [短标记法](build_script_basics/shortcut_notations.md) - * [自定义任务属性](build_script_basics/extra_task_properties.md) - * [调用 Ant 任务](build_script_basics/using_ant_tasks.md) - * [使用方法](build_script_basics/using_methods.md) - * [默认任务](build_script_basics/default_tasks.md) - * [通过 DAG 配置](build_script_basics/configure_by_dag.md) * [Java 构建入门](java_quickstart/README.md) * [Java 插件](java_quickstart/the_java_plugin.md) * [一个基础的 Java 项目](java_quickstart/a_basic_java_project.md) From 727c6faafb4b2c2aa91b47135e078d16d197bcbe Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:24:19 +0000 Subject: [PATCH 044/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 7735ef2..c5d99f5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -118,21 +118,6 @@ * [工具和集成开发环境](the_gradle_daemon/tools_&_ides.md) * [摇篮守护进程如何使构建速度更快](the_gradle_daemon/how_does_the_gradle_daemon_make_builds_faster.md) * [未来可能的改进](the_gradle_daemon/potential_future_enhancements.md) -* [Gradle Plugins](gradle_plugins/README.md) - * [插件的作用](gradle_plugins/what_plugins_do.md) - * [插件的类型](gradle_plugins/types_of_plugins.md) - * [应用插件](gradle_plugins/applying_plugins.md) - * [脚本插件](gradle_plugins/script_plugins.md) - * [二进制插件](gradle_plugins/binary_plugins.md) - * [二进制插件的位置](gradle_plugins/locations_of_binary_plugins.md) - * [使用构建脚本块应用插件](gradle_plugins/applying_plugins_with_the_buildscript_block.md) - * [使用插件的插件DSL](gradle_plugins/applying_plugins_with_the_plugins_dsl.md) - * [插件DSL的限制](gradle_plugins/limitations_of_the_plugins_dsl.md) - * [约束语法](gradle_plugins/constrained_syntax.md) - * [只能在构建脚本中使用](gradle_plugins/can_only_be_used_in_build_scripts.md) - * [不能与subjects{},allprojects{}等结合使用](gradle_plugins/cannot_be_used_in_conjunction.md) - * [查找社区插件](gradle_plugins/finding_community_plugins.md) - * [更多关于插件](gradle_plugins/more_on_plugins.md) * [Gradle插件规范](standard_gradle_plugins/README.md) * [语言插件](standard_gradle_plugins/language_plugins.md) * [孵化中的语言插件](standard_gradle_plugins/incubating_language_plugins.md) @@ -142,35 +127,6 @@ * [孵化中的软件开发插件](standard_gradle_plugins/incubating_software_development_plugins.md) * [基础插件](standard_gradle_plugins/base_plugins.md) * [第三方插件](standard_gradle_plugins/third_party_plugins.md) -* [Java 插件](the_java_plugin/README.md) - * [使用](the_java_plugin/java_plugin_usage.md) - * [资源集](the_java_plugin/java_plugin_source_sets.md) - * [任务](the_java_plugin/java_plugin_tasks.md) - * [项目布局](the_java_plugin/java_plugin_project_layout.md) - * [依赖管理](the_java_plugin/java_plugin_dependency_management.md) - * [公共配置](the_java_plugin/java_plugin_convention_properties.md) - * [使用资源集工作](the_java_plugin/java_plugin_working_with_source_sets.md) - * [资源集属性](the_java_plugin/java_plugin_source_set_properties.md) - * [定义新的资源集](the_java_plugin/java_plugin_defining_new_source_sets.md) - * [资源集例子](the_java_plugin/java_plugins_some_source_set_examples.md) - * [Javadoc](the_java_plugin/java_plugin_javadoc.md) - * [清除](the_java_plugin/java_plugin_clean.md) - * [资源](the_java_plugin/java_plugin_resources.md) - * [编译 Java](the_java_plugin/java_plugin_compile_java.md) - * [增量 Java 编译](the_java_plugin/java_plugin_incremental_java_compilation.md) - * [测试](the_java_plugin/java_plugin_test.md) - * [测试执行](the_java_plugin/test_execution.md) - * [测试调试](the_java_plugin/test_debugging.md) - * [测试过滤](the_java_plugin/test_filtering.md) - * [通过系统属性执行单独测试](the_java_plugin/test_single_test_execution_via_system_properties.md) - * [测试检测](the_java_plugin/test_detection.md) - * [测试分组](the_java_plugin/test_grouping.md) - * [测试报告](the_java_plugin/test_reporting.md) - * [TestNG 的参数化方法和报告](the_java_plugin/test_testNG_parameterized_methods_and_reporting.md) - * [公共值](the_java_plugin/test_convention_values.md) - * [Jar](the_java_plugin/java_plugin_jar.md) - * [Manifest](the_java_plugin/java_plugin_manifest.md) - * [上传](the_java_plugin/java_plugin_uploading.md) * [War插件](the_war_plugin/the_war_plugin.md) * [使用](the_war_plugin/usage.md) * [任务](the_war_plugin/tasks.md) From 6307ff2edd7be4e04e60b08401914f24b802bed9 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:24:27 +0000 Subject: [PATCH 045/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index c5d99f5..9e03bd3 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -32,24 +32,6 @@ * [Groovy 快速入门](groovy_quickstart/README.md) * [一个基本的 Groovy 项目](groovy_quickstart/a_basic_groovy_project.md) * [总结](groovy_quickstart/summary.md) -* [网页应用快速入门](web_application_quickstart/README.md) - * [构建一个 WAR 文件](web_application_quickstart/building_a_war_file.md) - * [运行 Web 应用](web_application_quickstart/running_your_web_application.md) - * [总结](web_application_quickstart/summary.md) -* [使用 Gradle 命令行](using_the_gradle_command-line/README.md) - * [多任务调用](using_the_gradle_command-line/executing_multiple_tasks.md) - * [排除任务](using_the_gradle_command-line/excluding_tasks.md) - * [失败后继续执行构建](using_the_gradle_command-line/continuing_the_build_when_a_failure_occurs.md) - * [简化任务名](using_the_gradle_command-line/task_name_abbreviation.md) - * [选择文件构建](using_the_gradle_command-line/selecting_which_build_to_execute.md) - * [获取构建信息](using_the_gradle_command-line/listing_tasks.md) - * [项目列表](using_the_gradle_command-line/listing_projects.md) - * [任务列表](using_the_gradle_command-line/listing_taskss.md) - * [获取任务具体信息](using_the_gradle_command-line/show_task_usage_details.md) - * [获取依赖列表](using_the_gradle_command-line/listing_project_dependencies.md) - * [查看特定依赖](using_the_gradle_command-line/getting_the_insight_into_a_particular_dependency.md) - * [获取项目属性列表](using_the_gradle_command-line/listing_project_properties.md) - * [构建日志](using_the_gradle_command-line/profiling_a_build.md) * 从 Maven 迁移到 Gradle * [编写构建脚本](writing_build_scripts/README.md) * [Gradle 构建语言](writing_build_scripts/the_gradle_build_language.md) From 51788d8c8b982001f699c6f14c09801905fef72f Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:24:56 +0000 Subject: [PATCH 046/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 9e03bd3..efb379f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -21,33 +21,7 @@ * [通用配置](java_quickstart/common_configuration.md) * [项目之间的依赖](java_quickstart/dependencies_between_projects.md) * [创建一个发行版本](java_quickstart/creating_a_distribution.md) -* [依赖管理的基础知识](dependency_management_basics/README.md) - * [什么是依赖管理](dependency_management_basics/what_is_dependency_management.md) - * [声明你的依赖](dependency_management_basics/a_basic_java_project.md) - * [依赖配置](dependency_management_basics/dependency_configurations.md) - * [外部的依赖](dependency_management_basics/external_dependencies.md) - * [仓库](dependency_management_basics/repositories.md) - * [发布 artifacts](dependency_management_basics/publishing_artifacts.md) - * [下一步?](dependency_management_basics/where_to_next.md) -* [Groovy 快速入门](groovy_quickstart/README.md) - * [一个基本的 Groovy 项目](groovy_quickstart/a_basic_groovy_project.md) - * [总结](groovy_quickstart/summary.md) -* 从 Maven 迁移到 Gradle -* [编写构建脚本](writing_build_scripts/README.md) - * [Gradle 构建语言](writing_build_scripts/the_gradle_build_language.md) - * [项目 API](writing_build_scripts/the_project_api.md) - * [标准项目属性](writing_build_scripts/standard_project_properties.md) - * [脚本 API](writing_build_scripts/the_script_api.md) - * [声明变量](writing_build_scripts/declaring_variables.md) - * [局部变量](writing_build_scripts/local_variables.md) - * [扩展属性](writing_build_scripts/extra_properties.md) - * [Groovy 基础](writing_build_scripts/some_groovy_basics.md) - * [Groovy JDK](writing_build_scripts/groovy_jdk.md) - * [属性存取器](writing_build_scripts/property_accessors.md) - * [可有可无的圆括号](writing_build_scripts/optional_parentheses_on_method_calls.md) - * [List 和 Map 集合](writing_build_scripts/list_and_map_literals.md) - * [闭合作为方法的最后一个参数](writing_build_scripts/closures_as_the_last_parameter_in_a_method.md) - * [闭合委托对象](writing_build_scripts/closure_delegate.md) +* [从 Maven 迁移到 Gradle](cong-maven-qian-yi-dao-gradle.md) * [深入了解 Tasks](more_about_tasks/README.md) * [定义 tasks](more_about_tasks/defining_tasks.md) * [定位 tasks](more_about_tasks/locating_tasks.md) From 740f0a8aa14d87310c9a18be10c1b0781f87d063 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:25:08 +0000 Subject: [PATCH 047/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/SUMMARY.md b/SUMMARY.md index efb379f..9d08ace 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -21,7 +21,6 @@ * [通用配置](java_quickstart/common_configuration.md) * [项目之间的依赖](java_quickstart/dependencies_between_projects.md) * [创建一个发行版本](java_quickstart/creating_a_distribution.md) -* [从 Maven 迁移到 Gradle](cong-maven-qian-yi-dao-gradle.md) * [深入了解 Tasks](more_about_tasks/README.md) * [定义 tasks](more_about_tasks/defining_tasks.md) * [定位 tasks](more_about_tasks/locating_tasks.md) From b93ede398296979326ee8ce5beebdd53b89d1f03 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:25:21 +0000 Subject: [PATCH 048/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 9d08ace..21ac21c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -54,34 +54,6 @@ * [导入一个 Ant 构建](using_ant_from_gradle/importing_an_ant_build.md) * [Ant 的属性与引用](using_ant_from_gradle/ant_properties_and_references.md) * [API](using_ant_from_gradle/API.md) -* [Logging](logging/logging.md) - * [选择日志等级](logging/choosing_a_log_level.md) - * [编写自己的日志信息](logging/writing_your_own_log_messages.md) - * [外部工具和库的log](logging/logging_from_external_tools_and_libraries.md) - * [改变 Gradle 记录的内容](logging/changing_what_gradle_logs.md) -* [Gradle的守护进程](the_gradle_daemon/README.md) - * [什么是Gradle的守护进程](the_gradle_daemon/what_is_the_gradle_daemon.md) - * [管理和配置](the_gradle_daemon/management_and_configuration.md) - * [如何启用的摇篮守护进程](the_gradle_daemon/how_do_i_enable_the_gradle_daemon.md) - * [如何禁用Gradle的守护进程](the_gradle_daemon/how_do_i_disable_the_gradle_daemon.md) - * [怎样抑制“please consider using the Gradle Daemon”消息](the_gradle_daemon/how_do_i_suppress_the_please_consider_using_the_gradle_daemon_message.md) - * [为什么会在机器上出现不只一个守护进程](the_gradle_daemon/why_is_there_more_than_one_daemon_process_on_my_machine.md) - * [守护进程占用多大内存并且能不能给它更大的内存?](the_gradle_daemon/how_much_memory_does_the_daemon_use_and_can_i_give_it_more.md) - * [如何停止守护进程](the_gradle_daemon/how_can_i_stop_a_daemon.md) - * [守护进程何时会出错](the_gradle_daemon/what_can_go_wrong_with_daemon.md) - * [什么时候使用Gradle守护进程](the_gradle_daemon/when_should_i_not_use_the_gradle_daemon.md) - * [工具和集成开发环境](the_gradle_daemon/tools_&_ides.md) - * [摇篮守护进程如何使构建速度更快](the_gradle_daemon/how_does_the_gradle_daemon_make_builds_faster.md) - * [未来可能的改进](the_gradle_daemon/potential_future_enhancements.md) -* [Gradle插件规范](standard_gradle_plugins/README.md) - * [语言插件](standard_gradle_plugins/language_plugins.md) - * [孵化中的语言插件](standard_gradle_plugins/incubating_language_plugins.md) - * [集成插件](standard_gradle_plugins/integration_plugins.md) - * [孵化中的集成插件](standard_gradle_plugins/incubating_integration_plugins.md) - * [软件开发插件](standard_gradle_plugins/software_development_plugins.md) - * [孵化中的软件开发插件](standard_gradle_plugins/incubating_software_development_plugins.md) - * [基础插件](standard_gradle_plugins/base_plugins.md) - * [第三方插件](standard_gradle_plugins/third_party_plugins.md) * [War插件](the_war_plugin/the_war_plugin.md) * [使用](the_war_plugin/usage.md) * [任务](the_war_plugin/tasks.md) From 5967b60d9ac05f24392217f8acd84f39ce5c2354 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:28:36 +0000 Subject: [PATCH 049/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 55 ------------------------------------------------------ 1 file changed, 55 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 21ac21c..a355eb1 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -7,61 +7,6 @@ * [特点](overview/features.md) * [为什么用 Groovy?](overview/why_groovy.md) * [教程](tutorials/README.md) -* [Java 构建入门](java_quickstart/README.md) - * [Java 插件](java_quickstart/the_java_plugin.md) - * [一个基础的 Java 项目](java_quickstart/a_basic_java_project.md) - * [建立项目](java_quickstart/building_the_project.md) - * [外部的依赖](java_quickstart/external_dependencies.md) - * [定制项目](java_quickstart/customizing_the_project.md) - * [发布 JAR 文件](java_quickstart/publishing_the_jar_file.md) - * [创建 Eclipse 项目](java_quickstart/creating_an_eclipse_project.md) - * [总结](java_quickstart/summary.md) - * [多项目的 Java 构建](java_quickstart/multi-project_java_build.md) - * [定义一个多项目构建](java_quickstart/defining_a_multi-project_build.md) - * [通用配置](java_quickstart/common_configuration.md) - * [项目之间的依赖](java_quickstart/dependencies_between_projects.md) - * [创建一个发行版本](java_quickstart/creating_a_distribution.md) -* [深入了解 Tasks](more_about_tasks/README.md) - * [定义 tasks](more_about_tasks/defining_tasks.md) - * [定位 tasks](more_about_tasks/locating_tasks.md) - * [配置 tasks](more_about_tasks/configuring_tasks.md) - * [给 task 加入依赖](more_about_tasks/adding_dependencies_to_a_task.md) - * [给 tasks 排序](more_about_tasks/ordering_tasks.md) - * [给 task 加入描述](more_about_tasks/adding_a_description_to_a_task.md) - * [替换 tasks](more_about_tasks/replacing_tasks.md) - * [跳过 tasks](more_about_tasks/skipping_tasks.md) - * [跳过 up-to-date 的任务](more_about_tasks/skipping_tasks_that_are_up-to-date.md) - * [Task 规则](more_about_tasks/task_rules.md) - * [终止 tasks](more_about_tasks/finalizer_tasks.md) - * [补充](more_about_tasks/extra.md) - * [Gradle 属性 和 system 属性](more_about_tasks/gradle_properties_and_system_properties.md) - * [使用其他的脚本配置项目](more_about_tasks/use_other_script_to_config_project.md) - * [使用其他的脚本配置任意对象](more_about_tasks/use_other_script_to_config_any_object.md) - * [配置任意对象](more_about_tasks/config_any_object.md) - * [缓存](more_about_tasks/cache.md) -* [文件操作](working_with_files/README.md) - * [定位文件](working_with_files/locating_files.md) - * [文件集合](working_with_files/file_collections.md) - * [文件树](working_with_files/file_trees.md) - * [使用一个归档文件的内容作为文件树](working_with_files/using_the_contents_of_an_archive_as_a_file_tree.md) - * [指定一组输入文件](working_with_files/specifying_a_set_of_input_files.md) - * [复制文件](working_with_files/copying_files.md) - * [使用同步任务](working_with_files/using_the_sync_task.md) - * [创建归档文件](working_with_files/creating_archives.md) -* [使用 Ant 插件](using_ant_from_gradle/using_ant_from_gradle.md) - * [使用 Ant 任务和 Ant 类型的构建](using_ant_from_gradle/using_ant_tasks_and_types_in_your_build.md) - * [在构建中使用自定义 Ant 任务](using_ant_from_gradle/using_custom_ant_tasks_in_your_build.md) - * [导入一个 Ant 构建](using_ant_from_gradle/importing_an_ant_build.md) - * [Ant 的属性与引用](using_ant_from_gradle/ant_properties_and_references.md) - * [API](using_ant_from_gradle/API.md) -* [War插件](the_war_plugin/the_war_plugin.md) - * [使用](the_war_plugin/usage.md) - * [任务](the_war_plugin/tasks.md) - * [项目布局](the_war_plugin/project_layout.md) - * [依赖管理](the_war_plugin/dependency_management.md) - * [公共配置](the_war_plugin/convention_properties.md) - * [War](the_war_plugin/war.md) - * [定制War](the_war_plugin/customizing.md) ## 开始 From 56a9758c1fb11431186876de399851c6e4208a23 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:29:22 +0000 Subject: [PATCH 050/102] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index a355eb1..1872721 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -2,11 +2,6 @@ * [关于本书](README.md) * [介绍](introduction.md) - * [关于这本指南](about_this_user_guide.md) -* [概述](overview/README.md) - * [特点](overview/features.md) - * [为什么用 Groovy?](overview/why_groovy.md) -* [教程](tutorials/README.md) ## 开始 From 41fd70c36ee2ffe6a6c6b445652bf7b757858eb6 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:35:43 +0000 Subject: [PATCH 051/102] Updates introduction.md Auto commit by GitBook Editor --- introduction.md | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/introduction.md b/introduction.md index b946348..fe4a0e9 100644 --- a/introduction.md +++ b/introduction.md @@ -1,18 +1,36 @@ # 介绍 -很高兴能向大家介绍 Gradle, -这是一个构建系统, -我们认为它是 java ( JVM ) 世界中构建技术的一个飞跃. - -Gradle 提供了: - -* 一个像 Ant 一样的非常灵活的通用构建工具 -* 一种可切换的, 像 maven 一样的基于合约构建的框架 -* 支持强大的多工程构建 -* 支持强大的依赖管理(基于 ApacheIvy ) -* 支持已有的 maven 和 ivy 仓库 -* 支持传递性依赖管理, 而不需要远程仓库或者 pom.xml 或者 ivy 配置文件 -* 优先支持 Ant 式的任务和构建 -* 基于 groovy 的构建脚本 -* 有丰富的领域模型来描述你的构建 +Gradle 是一个开源的自动化构建工具. 专注于灵活性和高性能. Gradle 的构建脚本是使用 [Groovy](http://groovy-lang.org/) 或 [Kotlin](https://kotlinlang.org/) DSL 编写的. 可以阅读 [Gradle features](https://gradle.org/features/) 来学习你可以用 Gradle 来做什么. + +* 高度自定义 — Gradle 是可通过绝大多数主流的方法来自定义和扩展的. + +* 快捷 — 通过使用前一个执行的输出作为下一个任务的输入, 只处理其中变化的部分, 来并行的执行任务. + +* 强大— Gradle 是 Android 的官方构建工具, 许多主流语言和技术都可以很好的支持它. + +## New projects with Gradle {#new-projects} + +Getting started with Gradle is easy! First, follow our guide to[download and install Gradle](https://docs.gradle.org/current/userguide/installation.html), then check out Gradle[getting started guides](https://gradle.org/guides/#getting-started)to create your first build. + +If you're currently using Maven, see a visual[Gradle vs Maven comparison](https://gradle.org/maven-vs-gradle/)and follow the guide for[migrating from Maven to Gradle](https://guides.gradle.org/migrating-from-maven/). + +## Using existing Gradle builds {#existing-projects} + +Gradle supports many major IDEs, including**Android Studio, Eclipse, IntelliJ IDEA, Visual Studio 2017, and XCode**. You can also invoke Gradle via its[command line interface](https://docs.gradle.org/current/userguide/command_line_interface.html)in your terminal or through your continuous integration server.[Gradle build scans](https://scans.gradle.com/)help you understand build results, improve build performance, and collaborate to fix problems faster. + +![](data:image/png;base64,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 "gradle project in IDE")![](data:image/png;base64,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 "gradle on command line")![](data:image/png;base64,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 "gradle build scan") + +## Getting help {#getting-help} + +* **Forum**— The fastest way to get help is through the[Gradle Forum](https://discuss.gradle.org/). Community members and core contributors answer your questions. + +* **Training**— Free, web-based Gradle training from Gradle developers happens every month. Head over to the[training page](https://gradle.org/training/)to sign up. + +* **Enterprise Services**— Support and training can be purchased alongside a[Gradle Enterprise](https://gradle.com/enterprise)subscription. + +## Licenses {#licenses} + + + +Gradle build tool source code is open and licensed under the[_Apache License 2.0_](https://github.com/gradle/gradle/blob/master/LICENSE). Gradle user manual and DSL references are licensed under[_Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License_](http://creativecommons.org/licenses/by-nc-sa/4.0/). From ca122fca8e9796009f79936c661bf6e7598d4191 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:39:03 +0000 Subject: [PATCH 052/102] Updates introduction.md Auto commit by GitBook Editor --- introduction.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/introduction.md b/introduction.md index fe4a0e9..f90fba6 100644 --- a/introduction.md +++ b/introduction.md @@ -4,11 +4,11 @@ Gradle 是一个开源的自动化构建工具. 专注于灵活性和高性能. * 高度自定义 — Gradle 是可通过绝大多数主流的方法来自定义和扩展的. -* 快捷 — 通过使用前一个执行的输出作为下一个任务的输入, 只处理其中变化的部分, 来并行的执行任务. +* 快捷 — 通过使用前一个执行的输出作为下一个任务的输入, 只处理其中变化的部分, 来并行的执行任务. * 强大— Gradle 是 Android 的官方构建工具, 许多主流语言和技术都可以很好的支持它. -## New projects with Gradle {#new-projects} +## 使用 Gradle 构建新项目 {#new-projects} Getting started with Gradle is easy! First, follow our guide to[download and install Gradle](https://docs.gradle.org/current/userguide/installation.html), then check out Gradle[getting started guides](https://gradle.org/guides/#getting-started)to create your first build. @@ -20,17 +20,15 @@ Gradle supports many major IDEs, including**Android Studio, Eclipse, IntelliJ ID ![](data:image/png;base64,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 "gradle project in IDE")![](data:image/png;base64,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 "gradle on command line")![](data:image/png;base64,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 "gradle build scan") -## Getting help {#getting-help} +## 帮助 {#getting-help} -* **Forum**— The fastest way to get help is through the[Gradle Forum](https://discuss.gradle.org/). Community members and core contributors answer your questions. +* 论坛** **— 通过 [Gradle Forum](https://discuss.gradle.org/) 来寻求帮助是最快的方式. -* **Training**— Free, web-based Gradle training from Gradle developers happens every month. Head over to the[training page](https://gradle.org/training/)to sign up. +* 培训 — 每个月都有免费的, 基于网页的培训. 查看 [培训](https://gradle.org/training/) 了解更多. -* **Enterprise Services**— Support and training can be purchased alongside a[Gradle Enterprise](https://gradle.com/enterprise)subscription. +* 公司服务 — 通过 [Gradle Enterprise](https://gradle.com/enterprise) 获得技术支持和培训. ## Licenses {#licenses} - - Gradle build tool source code is open and licensed under the[_Apache License 2.0_](https://github.com/gradle/gradle/blob/master/LICENSE). Gradle user manual and DSL references are licensed under[_Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License_](http://creativecommons.org/licenses/by-nc-sa/4.0/). From ed99ff90627987aa9d16bb9bc7e9a0dc9499f6e3 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:42:03 +0000 Subject: [PATCH 053/102] Updates introduction.md Auto commit by GitBook Editor --- introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/introduction.md b/introduction.md index f90fba6..3f05d02 100644 --- a/introduction.md +++ b/introduction.md @@ -14,9 +14,9 @@ Getting started with Gradle is easy! First, follow our guide to[download and ins If you're currently using Maven, see a visual[Gradle vs Maven comparison](https://gradle.org/maven-vs-gradle/)and follow the guide for[migrating from Maven to Gradle](https://guides.gradle.org/migrating-from-maven/). -## Using existing Gradle builds {#existing-projects} +## 使用已经存在的 Gradle 构建 {#existing-projects} -Gradle supports many major IDEs, including**Android Studio, Eclipse, IntelliJ IDEA, Visual Studio 2017, and XCode**. You can also invoke Gradle via its[command line interface](https://docs.gradle.org/current/userguide/command_line_interface.html)in your terminal or through your continuous integration server.[Gradle build scans](https://scans.gradle.com/)help you understand build results, improve build performance, and collaborate to fix problems faster. +Gradle 支持许多主流的 IDEs, 包括 **Android Studio, Eclipse, IntelliJ IDEA, Visual Studio 2017, and XCode**. 你也可以通过[命令行界面](https://docs.gradle.org/current/userguide/command_line_interface.html) 或者持续集成服务器来使用它. [Gradle build scans](https://scans.gradle.com/) 可以帮助你更好的理解构建结果, 提升构建的性能以及更快的修复问题. ![](data:image/png;base64,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 "gradle project in IDE")![](data:image/png;base64,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 "gradle on command line")![](data:image/png;base64,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 "gradle build scan") From 91e33020656b11fc9284b2643dd0d3fa848f320d Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:44:17 +0000 Subject: [PATCH 054/102] Updates introduction.md Auto commit by GitBook Editor --- introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/introduction.md b/introduction.md index 3f05d02..c5814eb 100644 --- a/introduction.md +++ b/introduction.md @@ -10,9 +10,9 @@ Gradle 是一个开源的自动化构建工具. 专注于灵活性和高性能. ## 使用 Gradle 构建新项目 {#new-projects} -Getting started with Gradle is easy! First, follow our guide to[download and install Gradle](https://docs.gradle.org/current/userguide/installation.html), then check out Gradle[getting started guides](https://gradle.org/guides/#getting-started)to create your first build. +开始使用 Gradle 非常简单! 请开始阅读[ 开始](https://gradle.org/guides/#getting-started) 来创建你的第一个构建. -If you're currently using Maven, see a visual[Gradle vs Maven comparison](https://gradle.org/maven-vs-gradle/)and follow the guide for[migrating from Maven to Gradle](https://guides.gradle.org/migrating-from-maven/). +如果你正在使用 Maven, 可以看一看 [Gradle vs Maven 对比](https://gradle.org/maven-vs-gradle/) 以及[ 从 Maven 迁移到 Gradle](https://guides.gradle.org/migrating-from-maven/). ## 使用已经存在的 Gradle 构建 {#existing-projects} From 31340762f2ea02eeef4c4b915247711aba680739 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:49:54 +0000 Subject: [PATCH 055/102] Updates README.md Auto commit by GitBook Editor --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1546c84..48f0073 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,66 @@ # Gradle User Guide 中文版 -### [阅读地址](http://dongchuan.gitbooks.io/gradle-user-guide-/) - * Gradle User Guide 中文版目前正在更新到 4.6, 希望大家理解也欢迎大家一起加入和完善 - * 如果发现不通顺或者有歧义的地方, 可以在评论里指出来, 我们会及时改正的. - * [Github托管地址](https://github.com/DONGChuan/GradleUserGuide) - * [原文地址](https://docs.gradle.org/current/userguide/userguide.html) - -* 我们会开放权限给每一个加入的伙伴 \(翻译或者校对\),请提前邮箱联系 dongchuanyz@163.com +* 我们会开放权限给每一个加入的伙伴 \(翻译或者校对\),请联系我们 + +### 进度 + +##### 开始 + +* [x] [Installing Gradle](https://docs.gradle.org/current/userguide/installation.html) +* [x] [Creating New Gradle Builds](https://guides.gradle.org/creating-new-gradle-builds/) +* [x] [Creating Build Scans](https://guides.gradle.org/creating-build-scans/) +* [ ] [Migrating From Maven](https://guides.gradle.org/migrating-from-maven/) + +##### 使用 Gradle 构建 + +* [ ] [Command-Line Interface](https://docs.gradle.org/current/userguide/command_line_interface.html) +* [ ] [Customizing Execution](https://docs.gradle.org/current/userguide/userguide.html#customizing-execution) +* [ ] [Executing Multi-Project Builds](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html) +* [ ] [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) +* [ ] [Troubleshooting](https://docs.gradle.org/current/userguide/troubleshooting.html) +* [ ] [Using Build Scans](https://docs.gradle.com/build-scan-plugin) + +##### 项目教程 + +* [ ] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) +* [ ] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) +* [ ] [Groovy](https://docs.gradle.org/current/userguide/userguide.html#building-groovy-projects) +* [ ] [Java](https://docs.gradle.org/current/userguide/userguide.html#building-java-projects) +* [ ] [JavaScript](https://docs.gradle.org/current/userguide/userguide.html#building-javascript-projects) +* [ ] [Kotlin](https://docs.gradle.org/current/userguide/userguide.html#building-kotlin-projects) +* [ ] [Scala](https://docs.gradle.org/current/userguide/userguide.html#building-scala-projects) + +##### Authoring Gradle Builds + +* [ ] [Groovy DSL Reference](https://docs.gradle.org/current/dsl/) +* [ ] [Gradle API Javadoc](https://docs.gradle.org/current/javadoc/) +* [ ] [Gradle Feature Lifecycle](https://docs.gradle.org/current/userguide/feature_lifecycle.html) +* [ ] [Best Practices](https://docs.gradle.org/current/userguide/userguide.html#best-practices) +* [ ] [Build Configuration Scripts](https://docs.gradle.org/current/userguide/userguide.html#authoring-build-scripts) +* [ ] [Dependency Management](https://docs.gradle.org/current/userguide/userguide.html#dependency-management) +* [ ] [Publishing Artifacts](https://docs.gradle.org/current/userguide/userguide.html#publishing-artifacts) +* [ ] [Sample Gradle Builds](https://docs.gradle.org/current/userguide/userguide.html#sample-gradle-builds) +* [ ] [C++ Projects](https://docs.gradle.org/current/userguide/userguide.html#cpp-projects) +* [ ] [Groovy Projects](https://docs.gradle.org/current/userguide/userguide.html#groovy-projects) +* [ ] [Java Projects](https://docs.gradle.org/current/userguide/userguide.html#java-projects) +* [ ] [Java Web Projects](https://docs.gradle.org/current/userguide/userguide.html#java-web-projects) +* [ ] [Scala Projects](https://docs.gradle.org/current/userguide/userguide.html#scala-projects) + +##### 集成 Gradle + +* [ ] [IDE Integration](https://docs.gradle.org/current/userguide/userguide.html#ide-integration) + +##### 扩展 Gradle + +* [ ] [Plugin Development Guides](https://docs.gradle.org/current/userguide/userguide.html#plugins-tutorials) +* [ ] [Developing Parallel Tasks](https://guides.gradle.org/using-the-worker-api/) +* [ ] [Lazy Task Configuration](https://docs.gradle.org/current/userguide/lazy_configuration.html) +* [ ] [Plugin Development Plugin](https://docs.gradle.org/current/userguide/java_gradle_plugin.html) +* [ ] [Writing Custom Plugins](https://docs.gradle.org/current/userguide/custom_plugins.html) --- From af0abad85269c4d13ba2ff0ac135ea80f4e96c69 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 14:51:29 +0000 Subject: [PATCH 056/102] Updates README.md Auto commit by GitBook Editor From fc739b7976e57396e6ed14026477fa68a6626fee Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 28 Mar 2018 15:23:38 +0000 Subject: [PATCH 057/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md Auto commit by GitBook Editor --- shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md index 2d84c9a..9a5c43d 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md @@ -1,8 +1,10 @@ -The command-line interface is one of the primary methods of interacting with Gradle. The following serves as a reference of executing and customizing Gradle use of a command-line or when writing scripts or configuring continuous integration. +# 命令行界面 + +直接使用命令行界面是使用 Gradle 的主要方法之一. The following serves as a reference of executing and customizing Gradle use of a command-line or when writing scripts or configuring continuous integration. Use of the[Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html)is highly encouraged. You should substitute`./gradlew`or`gradlew.bat`for`gradle`in all following examples when using the Wrapper. -Executing Gradle on the command-line conforms to the following structure. Options are allowed before and after task names. +执行 Gradle 的命令行遵循以下结构. Options 既可以添加在任务名之前也可以在任务名之后: ``` gradle [taskName...] [--option-name...] @@ -23,7 +25,7 @@ Options that enable behavior have long-form options with inverses specified with --no-build-cache ``` -Many long-form options, have short option equivalents. The following are equivalent: +许多长的 option 都有缩写形式, 比如: ``` --help From 4e57fe363206ce8c28de78b71b8a272d2a9fc792 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:03:19 +0000 Subject: [PATCH 058/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md Auto commit by GitBook Editor --- shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md index 9a5c43d..2e39020 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md @@ -1,8 +1,8 @@ # 命令行界面 -直接使用命令行界面是使用 Gradle 的主要方法之一. The following serves as a reference of executing and customizing Gradle use of a command-line or when writing scripts or configuring continuous integration. +直接使用命令行界面是使用 Gradle 的主要方法之一. 接下来将学习如何使用命令行执行和自定义 Gradle. -Use of the[Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html)is highly encouraged. You should substitute`./gradlew`or`gradlew.bat`for`gradle`in all following examples when using the Wrapper. +强烈建议使用 [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html). 你应该使用`gradle` 来代替`./gradlew` 和 `gradlew.bat`. 执行 Gradle 的命令行遵循以下结构. Options 既可以添加在任务名之前也可以在任务名之后: From 3584961bdcb96c5e8d63b4ba8848d3dadaac731a Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:08:48 +0000 Subject: [PATCH 059/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md Auto commit by GitBook Editor --- shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md index 2e39020..178643a 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md @@ -10,15 +10,15 @@ gradle [taskName...] [--option-name...] ``` -If multiple tasks are specified, they should be separated with a space. +如果需要执行多个任务, 需要在任务名称之间添加空格. -Options that accept values can be specified with or without`=`between the option and argument; however, use of`=`is recommended. +部分需要赋值的 Options 不是强制需要在它和对应的值之间添加`=`; 但是, 还是强烈推荐使用`=`. ``` --console=plain ``` -Options that enable behavior have long-form options with inverses specified with`--no-`. The following are opposites. +部分启动某些行为的 Options, 它的相反的选项就是在之前添加`--no-`. 比如: ``` --build-cache @@ -32,7 +32,5 @@ Options that enable behavior have long-form options with inverses specified with -h ``` -Many command-line flags can be specified in`gradle.properties`to avoid needing to be typed. See the[configuring build environment guide](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties)for details. - -The following sections describe use of the Gradle command-line interface, grouped roughly by user goal. Some plugins also add their own command line options, for example[`--tests`for Java test filtering](https://docs.gradle.org/current/userguide/java_plugin.html#test_filtering). For more information on exposing command line options for your own tasks, see[the section called “Declaring and Using Command Line Options”](https://docs.gradle.org/current/userguide/custom_tasks.html#sec:declaring_and_using_command_line_options). +许多命令行标志都可以在`gradle.properties`中直接指定. 可以查看 [configuring build environment guide](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties) 了解更多. From 3e563f43fbcf92d174e650c693124695d21aac82 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:09:22 +0000 Subject: [PATCH 060/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md index a2fe19f..d775ab6 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -1,3 +1,5 @@ +# 执行 Tasks + You can run a task and all of its[dependencies](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:task_dependencies). ``` @@ -42,17 +44,13 @@ You can also specify multiple tasks. For example, the following will execute the You can exclude a task from being executed using the`-x`or`--exclude-task`command-line option and providing the name of the task to exclude. - - **Figure: Example Task Graph** ![](https://docs.gradle.org/current/userguide/img/commandLineTutorialTasks.png "Example Task Graph") - - **Example: Excluding tasks** -Output of**`gradle dist --exclude-task test`** +Output of`gradle dist --exclude-task test` ``` > @@ -64,7 +62,6 @@ building the distribution BUILD SUCCESSFUL in 0s 2 actionable tasks: 2 executed - ``` You can see that the`test`task is not executed, even though it is a dependency of the`dist`task. The`test`task’s dependencies such as`compileTest`are not executed either. Those dependencies of`test`that are required by another task, such as`compile`, are still executed. @@ -77,7 +74,7 @@ You can force Gradle to execute all tasks ignoring[up-to-date checks](https://do ❯ gradle test --rerun-tasks ``` -This will force`test`and_all_task dependencies of`test`to execute. It’s a little like running`gradle clean test`, but without the build’s generated output being deleted. +This will force`test`and\_all\_task dependencies of`test`to execute. It’s a little like running`gradle clean test`, but without the build’s generated output being deleted. ### Continuing the build when a failure occurs @@ -87,7 +84,7 @@ By default, Gradle will abort execution and fail the build as soon as any task f ❯ gradle test --continue ``` -When executed with`--continue`, Gradle will execute_every_task to be executed where all of the dependencies for that task completed without failure, instead of stopping as soon as the first failure is encountered. Each of the encountered failures will be reported at the end of the build. +When executed with`--continue`, Gradle will execute\_every\_task to be executed where all of the dependencies for that task completed without failure, instead of stopping as soon as the first failure is encountered. Each of the encountered failures will be reported at the end of the build. If a task fails, any subsequent tasks that were depending on it will not be executed. For example, tests will not run if there is a compilation failure in the code under test; because the test task will depend on the compilation task \(either directly or indirectly\). @@ -97,11 +94,9 @@ When you specify tasks on the command-line, you don’t have to provide the full You can also abbreviate each word in a camel case task name. For example, you can execute task`compileTest`by running`gradle compTest`or even`gradle cT`. - - **Example: Abbreviated camel case task name** -Output of**`gradle cT`** +Output of`gradle cT` ``` > @@ -113,7 +108,6 @@ compiling unit tests BUILD SUCCESSFUL in 0s 2 actionable tasks: 2 executed - ``` You can also use these abbreviations with the -x command-line option. From 0a42e3b26eb6d0457f1dfa15aba4d34e47e19da5 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:10:24 +0000 Subject: [PATCH 061/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md index d775ab6..daf93eb 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -1,12 +1,12 @@ # 执行 Tasks -You can run a task and all of its[dependencies](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:task_dependencies). +你可以运行一个 task 和它所有的[依赖](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:task_dependencies). ``` ❯ gradle myTask ``` -You can learn about what projects and tasks are available in the[project reporting section](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_project_reporting). +You can learn about what projects and tasks are available in the [project reporting section](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_project_reporting). ### Executing tasks in multi-project builds From 9e5004753e76e86d94d20deb5e1499b7a0a8213d Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:15:42 +0000 Subject: [PATCH 062/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md index daf93eb..ce363fd 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -10,20 +10,22 @@ You can learn about what projects and tasks are available in the [project report ### Executing tasks in multi-project builds -In a[multi-project build](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html), subproject tasks can be executed with ":" separating subproject name and task name. The following are equivalent_when run from the root project_. +在一个 [多项目构建当中](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html), 子项目的 tasks 可以通过在子项目名后添加 ":" 和 task 名来执行: ``` ❯ gradle :mySubproject:taskName ❯ gradle mySubproject:taskName ``` -You can also run a task for all subprojects using the task name only. For example, this will run the "test" task for all subprojects when invoked from the root project directory. +> 当从根项目执行时, 上面2个是相等的 + +当只使用 task 名时, 这个任务是对所有子项目都执行的. 举个例子, 在项目根目录运行下面的命令将对所有子项目都执行 "test" task. ``` ❯ gradle test ``` -When invoking Gradle from within a subproject, the project name should be omitted: +当在一个子项目中执行命令, 就不需要显式的指定子项目名称, 且该任务只对子项目本身执行: ``` ❯ cd mySubproject From 6d0b25b004178f8fda087b4024ab1fba9c713af6 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:30:41 +0000 Subject: [PATCH 063/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md index ce363fd..1e778e1 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -6,9 +6,7 @@ ❯ gradle myTask ``` -You can learn about what projects and tasks are available in the [project reporting section](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_project_reporting). - -### Executing tasks in multi-project builds +### 在多项目构建中执行 tasks 在一个 [多项目构建当中](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html), 子项目的 tasks 可以通过在子项目名后添加 ":" 和 task 名来执行: @@ -32,19 +30,19 @@ You can learn about what projects and tasks are available in the [project report ❯ gradle taskName ``` -When executing the Gradle Wrapper from subprojects, one must reference`gradlew`relatively. For example:`../gradlew taskName`. The community[gdub project](http://www.gdub.rocks/)aims to make this more convenient. +当在子项目中执行 Gradle Wrapper, 必须引用`gradlew `的相对路径. 举个例子:`../gradlew taskName`. 社区 [gdub project](http://www.gdub.rocks/) 可以提供更多的支持. -### Executing multiple tasks +### 执行多个 tasks -You can also specify multiple tasks. For example, the following will execute the`test`and`deploy`tasks in the order that they are listed on the command-line and will also execute the dependencies for each task. +你也可以同时指定执行多个任务. 举个例子, 下面的命令将按命令行中的顺序执行`test`和`deploy`命令, 当然, 也会执行各个 task 的依赖: ``` ❯ gradle test deploy ``` -### Excluding tasks from execution +### 从执行中排除 tasks -You can exclude a task from being executed using the`-x`or`--exclude-task`command-line option and providing the name of the task to exclude. +你可以通过使用`-x`或`--exclude-task`加上任务名排除某个 task 的执行: **Figure: Example Task Graph** @@ -52,11 +50,10 @@ You can exclude a task from being executed using the`-x`or`--exclude-task`comman **Example: Excluding tasks** -Output of`gradle dist --exclude-task test` +`gradle dist --exclude-task test`的输出: ``` -> - gradle dist --exclude-task test +>gradle dist --exclude-task test :compile compiling source :dist @@ -66,7 +63,7 @@ BUILD SUCCESSFUL in 0s 2 actionable tasks: 2 executed ``` -You can see that the`test`task is not executed, even though it is a dependency of the`dist`task. The`test`task’s dependencies such as`compileTest`are not executed either. Those dependencies of`test`that are required by another task, such as`compile`, are still executed. +你可以看到`test`任务没有被执行, 即使它是`dist`任务的依赖. `test`任务的依赖比如`compileTest`也没有被执行. 但是其他依赖, 比如`compile`, 它仍被其它的任务依赖, 所以仍然会被执行. ### Forcing tasks to execute From a982f8f7b018e0cb83df20939926d1c83bb32e97 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:32:15 +0000 Subject: [PATCH 064/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md index 1e778e1..7be4634 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -30,7 +30,7 @@ ❯ gradle taskName ``` -当在子项目中执行 Gradle Wrapper, 必须引用`gradlew `的相对路径. 举个例子:`../gradlew taskName`. 社区 [gdub project](http://www.gdub.rocks/) 可以提供更多的支持. +当在子项目中执行 Gradle Wrapper, 必须引用`gradlew`的相对路径. 举个例子:`../gradlew taskName`. 社区 [gdub project](http://www.gdub.rocks/) 可以提供更多的支持. ### 执行多个 tasks @@ -63,11 +63,11 @@ BUILD SUCCESSFUL in 0s 2 actionable tasks: 2 executed ``` -你可以看到`test`任务没有被执行, 即使它是`dist`任务的依赖. `test`任务的依赖比如`compileTest`也没有被执行. 但是其他依赖, 比如`compile`, 它仍被其它的任务依赖, 所以仍然会被执行. +你可以看到`test`任务没有被执行, 即使它是`dist`任务的依赖. `test`任务的依赖比如`compileTest`也没有被执行. 但是其他依赖, 比如`compile`, 它仍被其它的任务所依赖, 所以仍然会被执行. -### Forcing tasks to execute +### 强制执行任务 -You can force Gradle to execute all tasks ignoring[up-to-date checks](https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks)using the`--rerun-tasks`option: +你可以强制 Gradle to execute all tasks ignoring[up-to-date checks](https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks)using the`--rerun-tasks`option: ``` ❯ gradle test --rerun-tasks From 837a71642c6ec3b614ca0b0a84d278096afc06e2 Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 29 Mar 2018 04:42:31 +0000 Subject: [PATCH 065/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md Auto commit by GitBook Editor --- .../ming-ling-xing-jie-mian/zhi-xing-tasks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md index 7be4634..7b970d3 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md @@ -67,13 +67,13 @@ BUILD SUCCESSFUL in 0s ### 强制执行任务 -你可以强制 Gradle to execute all tasks ignoring[up-to-date checks](https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks)using the`--rerun-tasks`option: +许多任务, 特别是 Gradle 本身提供的任务都支持增量版本. 这些任务可以根据它们的输入或输出自上次运行以来是否发生变化来确定它们是否需要运行. 当 Gradle 在构建运行期间在其名称旁边显示文本`UP-TO-DATE`时,你就可以轻松识别参与增量构建的任务. 但是有时你可能偶尔想强制 Gradle 运行所有的任务, 不需要判断是否需要运行. 如果是这样, 只要使用`--rerun-tasks`选项即可: ``` ❯ gradle test --rerun-tasks ``` -This will force`test`and\_all\_task dependencies of`test`to execute. It’s a little like running`gradle clean test`, but without the build’s generated output being deleted. +该命令就会强制执行`test`以及它所有的依赖. ### Continuing the build when a failure occurs From e8c3b66830b2e639866ec06998f47dfaeb629898 Mon Sep 17 00:00:00 2001 From: DONG Date: Sun, 1 Apr 2018 21:45:04 +0800 Subject: [PATCH 066/102] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=97=A7=E7=AB=A0=E8=8A=82=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build_script_basics/README.md | 20 -- .../a_shortcut_task_definition.md | 23 -- build_script_basics/build_scripts_are_code.md | 34 --- build_script_basics/configure_by_dag.md | 48 ---- build_script_basics/default_tasks.md | 32 --- build_script_basics/dynamic_tasks.md | 22 -- build_script_basics/extra_task_properties.md | 27 --- build_script_basics/hello_world.md | 63 ------ .../manipulating_existing_tasks.md | 59 ----- build_script_basics/projects_and_tasks.md | 26 --- build_script_basics/shortcut_notations.md | 29 --- build_script_basics/task_dependencies.md | 52 ----- build_script_basics/using_ant_tasks.md | 34 --- build_script_basics/using_methods.md | 37 --- dependency_management_basics/README.md | 14 -- .../a_basic_java_project.md | 22 -- .../dependency_configurations.md | 24 -- .../external_dependencies.md | 29 --- .../publishing_artifacts.md | 45 ---- dependency_management_basics/repositories.md | 56 ----- .../what_is_dependency_management.md | 17 -- dependency_management_basics/where_to_next.md | 7 - gradle_plugins/README.md | 6 - gradle_plugins/applying_plugins.md | 6 - ...ying_plugins_with_the_buildscript_block.md | 22 -- .../applying_plugins_with_the_plugins_dsl.md | 33 --- gradle_plugins/binary_plugins.md | 23 -- .../can_only_be_used_in_build_scripts.md | 5 - .../cannot_be_used_in_conjunction.md | 9 - gradle_plugins/constrained_syntax.md | 16 -- gradle_plugins/finding_community_plugins.md | 3 - .../limitations_of_the_plugins_dsl.md | 11 - gradle_plugins/locations_of_binary_plugins.md | 10 - gradle_plugins/more_on_plugins.md | 3 - gradle_plugins/script_plugins.md | 11 - gradle_plugins/types_of_plugins.md | 5 - gradle_plugins/what_plugins_do.md | 15 -- groovy_quickstart/README.md | 4 - groovy_quickstart/a_basic_groovy_project.md | 47 ---- groovy_quickstart/summary.md | 5 - java_quickstart/README.md | 10 - java_quickstart/a_basic_java_project.md | 24 -- java_quickstart/building_the_project.md | 42 ---- java_quickstart/common_configuration.md | 30 --- java_quickstart/creating_a_distribution.md | 20 -- .../creating_an_eclipse_project.md | 13 -- java_quickstart/customizing_the_project.md | 31 --- .../defining_a_multi-project_build.md | 13 -- .../dependencies_between_projects.md | 14 -- java_quickstart/external_dependencies.md | 34 --- java_quickstart/multi-project_java_build.md | 19 -- java_quickstart/publishing_the_jar_file.md | 19 -- java_quickstart/summary.md | 39 ---- java_quickstart/the_java_plugin.md | 45 ---- logging/changing_what_gradle_logs.md | 52 ----- logging/choosing_a_log_level.md | 23 -- logging/logging.md | 16 -- ...gging_from_external_tools_and_libraries.md | 38 ---- logging/writing_your_own_log_messages.md | 41 ---- more_about_tasks/README.md | 7 - .../adding_a_description_to_a_task.md | 16 -- .../adding_dependencies_to_a_task.md | 95 -------- more_about_tasks/cache.md | 4 - more_about_tasks/config_any_object.md | 23 -- more_about_tasks/configuring_tasks.md | 65 ------ more_about_tasks/defining_tasks.md | 53 ----- more_about_tasks/extra.md | 3 - more_about_tasks/finalizer_tasks.md | 57 ----- ...gradle_properties_and_system_properties.md | 44 ---- more_about_tasks/locating_tasks.md | 65 ------ more_about_tasks/ordering_tasks.md | 121 ---------- more_about_tasks/replacing_tasks.md | 26 --- more_about_tasks/skipping_tasks.md | 88 -------- .../skipping_tasks_that_are_up-to-date.md | 103 --------- more_about_tasks/task_rules.md | 56 ----- .../use_other_script_to_config_any_object.md | 31 --- .../use_other_script_to_config_project.md | 22 -- overview/README.md | 5 - overview/features.md | 78 ------- overview/why_groovy.md | 25 --- standard_gradle_plugins/README.md | 3 - standard_gradle_plugins/base_plugins.md | 31 --- .../incubating_integration_plugins.md | 12 - .../incubating_language_plugins.md | 13 -- ...incubating_software_development_plugins.md | 17 -- .../integration_plugins.md | 14 -- standard_gradle_plugins/language_plugins.md | 14 -- .../software_development_plugins.md | 22 -- .../third_party_plugins.md | 3 - the_gradle_daemon/README.md | 2 - the_gradle_daemon/how_can_i_stop_a_daemon.md | 5 - .../how_do_i_disable_the_gradle_daemon.md | 7 - .../how_do_i_enable_the_gradle_daemon.md | 24 -- ...onsider_using_the_gradle_daemon_message.md | 5 - ...es_the_gradle_daemon_make_builds_faster.md | 9 - ...s_the_daemon_use_and_can_i_give_it_more.md | 7 - .../management_and_configuration.md | 1 - .../potential_future_enhancements.md | 8 - the_gradle_daemon/tools_&_ides.md | 5 - .../what_can_go_wrong_with_daemon.md | 10 - .../what_is_the_gradle_daemon.md | 16 -- ...when_should_i_not_use_the_gradle_daemon.md | 5 - ...e_than_one_daemon_process_on_my_machine.md | 31 --- the_java_plugin/README.md | 5 - the_java_plugin/java_plugin_clean.md | 9 - the_java_plugin/java_plugin_compile_java.md | 12 - the_java_plugin/java_plugin_compilejava.md | 1 - .../java_plugin_convention_properties.md | 34 --- .../java_plugin_defining_new_source_sets.md | 47 ---- .../java_plugin_dependency_management.md | 27 --- ...ava_plugin_incremental_java_compilation.md | 9 - the_java_plugin/java_plugin_jar.md | 3 - the_java_plugin/java_plugin_javadoc.md | 12 - the_java_plugin/java_plugin_manifest.md | 61 ----- the_java_plugin/java_plugin_project_layout.md | 36 --- the_java_plugin/java_plugin_resources.md | 10 - .../java_plugin_source_set_properties.md | 19 -- the_java_plugin/java_plugin_source_sets.md | 13 -- the_java_plugin/java_plugin_tasks.md | 51 ----- the_java_plugin/java_plugin_test.md | 3 - the_java_plugin/java_plugin_uploading.md | 7 - the_java_plugin/java_plugin_usage.md | 12 - .../java_plugin_working_with_source_sets.md | 44 ---- .../java_plugins_some_source_set_examples.md | 38 ---- the_java_plugin/test_convention_values.md | 10 - the_java_plugin/test_debugging.md | 4 - the_java_plugin/test_detection.md | 12 - the_java_plugin/test_execution.md | 12 - the_java_plugin/test_filtering.md | 33 --- the_java_plugin/test_grouping.md | 28 --- the_java_plugin/test_reporting.md | 25 --- ...le_test_execution_via_system_properties.md | 12 - ...tNG_parameterized_methods_and_reporting.md | 3 - the_war_plugin/convention_properties.md | 10 - the_war_plugin/customizing.md | 43 ---- the_war_plugin/dependency_management.md | 3 - the_war_plugin/project_layout.md | 7 - the_war_plugin/tasks.md | 23 -- the_war_plugin/the_war_plugin.md | 106 --------- the_war_plugin/usage.md | 14 -- the_war_plugin/war.md | 8 - troubleshooting/README.md | 20 -- troubleshooting/getting_help.md | 5 - troubleshooting/working_through_problems.md | 7 - tutorial_-_this_and_that/caching.md | 3 - tutorials/README.md | 30 --- tutorials/getting_started.md | 28 --- using_ant_from_gradle/API.md | 3 - .../ant_properties_and_references.md | 61 ----- .../importing_an_ant_build.md | 139 ------------ .../using_ant_from_gradle.md | 11 - ...using_ant_tasks_and_types_in_your_build.md | 62 ----- .../using_custom_ant_tasks_in_your_build.md | 54 ----- using_the_gradle_command-line/README.md | 3 - ...tinuing_the_build_when_a_failure_occurs.md | 11 - .../excluding_tasks.md | 21 -- .../executing_multiple_tasks.md | 50 ----- ...he_insight_into_a_particular_dependency.md | 21 -- .../listing_project_dependencies.md | 55 ----- .../listing_project_properties.md | 24 -- .../listing_projects.md | 28 --- .../listing_tasks.md | 7 - .../listing_taskss.md | 105 --------- .../profiling_a_build.md | 13 -- .../selecting_which_build_to_execute.md | 33 --- .../show_task_usage_details.md | 23 -- .../task_name_abbreviation.md | 47 ---- .../README.md | 23 -- .../command_line.md | 5 - .../favorities.md | 7 - .../setup.md | 17 -- .../task_tree.md | 26 --- web_application_quickstart/README.md | 6 - .../building_a_war_file.md | 13 -- .../running_your_web_application.md | 16 -- web_application_quickstart/summary.md | 5 - working_with_files/README.md | 3 - working_with_files/copying_files.md | 212 ------------------ working_with_files/creating_archives.md | 172 -------------- working_with_files/file_collections.md | 101 --------- working_with_files/file_trees.md | 67 ------ working_with_files/java.md | 1 - working_with_files/locating_files.md | 39 ---- .../specifying_a_set_of_input_files.md | 59 ----- working_with_files/using_a_file_collection.md | 93 -------- ...e_contents_of_an_archive_as_a_file_tree.md | 24 -- working_with_files/using_the_sync_task.md | 17 -- writing_build_scripts/README.md | 2 - writing_build_scripts/closure_delegate.md | 12 - ...sures_as_the_last_parameter_in_a_method.md | 12 - writing_build_scripts/declaring_variables.md | 3 - writing_build_scripts/extra_properties.md | 54 ----- writing_build_scripts/groovy_jdk.md | 11 - .../list_and_map_literals.md | 23 -- writing_build_scripts/local_variables.md | 15 -- .../optional_parentheses_on_method_calls.md | 11 - writing_build_scripts/property_accessors.md | 14 -- writing_build_scripts/some_groovy_basics.md | 2 - .../standard_project_properties.md | 20 -- .../the_gradle_build_language.md | 7 - writing_build_scripts/the_project_api.md | 32 --- writing_build_scripts/the_script_api.md | 2 - 202 files changed, 5524 deletions(-) delete mode 100644 build_script_basics/README.md delete mode 100644 build_script_basics/a_shortcut_task_definition.md delete mode 100644 build_script_basics/build_scripts_are_code.md delete mode 100644 build_script_basics/configure_by_dag.md delete mode 100644 build_script_basics/default_tasks.md delete mode 100644 build_script_basics/dynamic_tasks.md delete mode 100644 build_script_basics/extra_task_properties.md delete mode 100644 build_script_basics/hello_world.md delete mode 100644 build_script_basics/manipulating_existing_tasks.md delete mode 100644 build_script_basics/projects_and_tasks.md delete mode 100644 build_script_basics/shortcut_notations.md delete mode 100644 build_script_basics/task_dependencies.md delete mode 100644 build_script_basics/using_ant_tasks.md delete mode 100644 build_script_basics/using_methods.md delete mode 100644 dependency_management_basics/README.md delete mode 100644 dependency_management_basics/a_basic_java_project.md delete mode 100644 dependency_management_basics/dependency_configurations.md delete mode 100644 dependency_management_basics/external_dependencies.md delete mode 100644 dependency_management_basics/publishing_artifacts.md delete mode 100644 dependency_management_basics/repositories.md delete mode 100644 dependency_management_basics/what_is_dependency_management.md delete mode 100644 dependency_management_basics/where_to_next.md delete mode 100644 gradle_plugins/README.md delete mode 100644 gradle_plugins/applying_plugins.md delete mode 100644 gradle_plugins/applying_plugins_with_the_buildscript_block.md delete mode 100644 gradle_plugins/applying_plugins_with_the_plugins_dsl.md delete mode 100644 gradle_plugins/binary_plugins.md delete mode 100644 gradle_plugins/can_only_be_used_in_build_scripts.md delete mode 100644 gradle_plugins/cannot_be_used_in_conjunction.md delete mode 100644 gradle_plugins/constrained_syntax.md delete mode 100644 gradle_plugins/finding_community_plugins.md delete mode 100644 gradle_plugins/limitations_of_the_plugins_dsl.md delete mode 100644 gradle_plugins/locations_of_binary_plugins.md delete mode 100644 gradle_plugins/more_on_plugins.md delete mode 100644 gradle_plugins/script_plugins.md delete mode 100644 gradle_plugins/types_of_plugins.md delete mode 100644 gradle_plugins/what_plugins_do.md delete mode 100644 groovy_quickstart/README.md delete mode 100644 groovy_quickstart/a_basic_groovy_project.md delete mode 100644 groovy_quickstart/summary.md delete mode 100644 java_quickstart/README.md delete mode 100644 java_quickstart/a_basic_java_project.md delete mode 100644 java_quickstart/building_the_project.md delete mode 100644 java_quickstart/common_configuration.md delete mode 100644 java_quickstart/creating_a_distribution.md delete mode 100644 java_quickstart/creating_an_eclipse_project.md delete mode 100644 java_quickstart/customizing_the_project.md delete mode 100644 java_quickstart/defining_a_multi-project_build.md delete mode 100644 java_quickstart/dependencies_between_projects.md delete mode 100644 java_quickstart/external_dependencies.md delete mode 100644 java_quickstart/multi-project_java_build.md delete mode 100644 java_quickstart/publishing_the_jar_file.md delete mode 100644 java_quickstart/summary.md delete mode 100644 java_quickstart/the_java_plugin.md delete mode 100644 logging/changing_what_gradle_logs.md delete mode 100644 logging/choosing_a_log_level.md delete mode 100644 logging/logging.md delete mode 100644 logging/logging_from_external_tools_and_libraries.md delete mode 100644 logging/writing_your_own_log_messages.md delete mode 100644 more_about_tasks/README.md delete mode 100644 more_about_tasks/adding_a_description_to_a_task.md delete mode 100644 more_about_tasks/adding_dependencies_to_a_task.md delete mode 100644 more_about_tasks/cache.md delete mode 100644 more_about_tasks/config_any_object.md delete mode 100644 more_about_tasks/configuring_tasks.md delete mode 100644 more_about_tasks/defining_tasks.md delete mode 100644 more_about_tasks/extra.md delete mode 100644 more_about_tasks/finalizer_tasks.md delete mode 100644 more_about_tasks/gradle_properties_and_system_properties.md delete mode 100644 more_about_tasks/locating_tasks.md delete mode 100644 more_about_tasks/ordering_tasks.md delete mode 100644 more_about_tasks/replacing_tasks.md delete mode 100644 more_about_tasks/skipping_tasks.md delete mode 100644 more_about_tasks/skipping_tasks_that_are_up-to-date.md delete mode 100644 more_about_tasks/task_rules.md delete mode 100644 more_about_tasks/use_other_script_to_config_any_object.md delete mode 100644 more_about_tasks/use_other_script_to_config_project.md delete mode 100644 overview/README.md delete mode 100644 overview/features.md delete mode 100644 overview/why_groovy.md delete mode 100644 standard_gradle_plugins/README.md delete mode 100644 standard_gradle_plugins/base_plugins.md delete mode 100644 standard_gradle_plugins/incubating_integration_plugins.md delete mode 100644 standard_gradle_plugins/incubating_language_plugins.md delete mode 100644 standard_gradle_plugins/incubating_software_development_plugins.md delete mode 100644 standard_gradle_plugins/integration_plugins.md delete mode 100644 standard_gradle_plugins/language_plugins.md delete mode 100644 standard_gradle_plugins/software_development_plugins.md delete mode 100644 standard_gradle_plugins/third_party_plugins.md delete mode 100644 the_gradle_daemon/README.md delete mode 100644 the_gradle_daemon/how_can_i_stop_a_daemon.md delete mode 100644 the_gradle_daemon/how_do_i_disable_the_gradle_daemon.md delete mode 100644 the_gradle_daemon/how_do_i_enable_the_gradle_daemon.md delete mode 100644 the_gradle_daemon/how_do_i_suppress_the_please_consider_using_the_gradle_daemon_message.md delete mode 100644 the_gradle_daemon/how_does_the_gradle_daemon_make_builds_faster.md delete mode 100644 the_gradle_daemon/how_much_memory_does_the_daemon_use_and_can_i_give_it_more.md delete mode 100644 the_gradle_daemon/management_and_configuration.md delete mode 100644 the_gradle_daemon/potential_future_enhancements.md delete mode 100644 the_gradle_daemon/tools_&_ides.md delete mode 100644 the_gradle_daemon/what_can_go_wrong_with_daemon.md delete mode 100644 the_gradle_daemon/what_is_the_gradle_daemon.md delete mode 100644 the_gradle_daemon/when_should_i_not_use_the_gradle_daemon.md delete mode 100644 the_gradle_daemon/why_is_there_more_than_one_daemon_process_on_my_machine.md delete mode 100644 the_java_plugin/README.md delete mode 100644 the_java_plugin/java_plugin_clean.md delete mode 100644 the_java_plugin/java_plugin_compile_java.md delete mode 100644 the_java_plugin/java_plugin_compilejava.md delete mode 100644 the_java_plugin/java_plugin_convention_properties.md delete mode 100644 the_java_plugin/java_plugin_defining_new_source_sets.md delete mode 100644 the_java_plugin/java_plugin_dependency_management.md delete mode 100644 the_java_plugin/java_plugin_incremental_java_compilation.md delete mode 100644 the_java_plugin/java_plugin_jar.md delete mode 100644 the_java_plugin/java_plugin_javadoc.md delete mode 100644 the_java_plugin/java_plugin_manifest.md delete mode 100644 the_java_plugin/java_plugin_project_layout.md delete mode 100644 the_java_plugin/java_plugin_resources.md delete mode 100644 the_java_plugin/java_plugin_source_set_properties.md delete mode 100644 the_java_plugin/java_plugin_source_sets.md delete mode 100644 the_java_plugin/java_plugin_tasks.md delete mode 100644 the_java_plugin/java_plugin_test.md delete mode 100644 the_java_plugin/java_plugin_uploading.md delete mode 100644 the_java_plugin/java_plugin_usage.md delete mode 100644 the_java_plugin/java_plugin_working_with_source_sets.md delete mode 100644 the_java_plugin/java_plugins_some_source_set_examples.md delete mode 100644 the_java_plugin/test_convention_values.md delete mode 100644 the_java_plugin/test_debugging.md delete mode 100644 the_java_plugin/test_detection.md delete mode 100644 the_java_plugin/test_execution.md delete mode 100644 the_java_plugin/test_filtering.md delete mode 100644 the_java_plugin/test_grouping.md delete mode 100644 the_java_plugin/test_reporting.md delete mode 100644 the_java_plugin/test_single_test_execution_via_system_properties.md delete mode 100644 the_java_plugin/test_testNG_parameterized_methods_and_reporting.md delete mode 100644 the_war_plugin/convention_properties.md delete mode 100644 the_war_plugin/customizing.md delete mode 100644 the_war_plugin/dependency_management.md delete mode 100644 the_war_plugin/project_layout.md delete mode 100644 the_war_plugin/tasks.md delete mode 100644 the_war_plugin/the_war_plugin.md delete mode 100644 the_war_plugin/usage.md delete mode 100644 the_war_plugin/war.md delete mode 100644 troubleshooting/README.md delete mode 100644 troubleshooting/getting_help.md delete mode 100644 troubleshooting/working_through_problems.md delete mode 100644 tutorial_-_this_and_that/caching.md delete mode 100644 tutorials/README.md delete mode 100644 tutorials/getting_started.md delete mode 100644 using_ant_from_gradle/API.md delete mode 100644 using_ant_from_gradle/ant_properties_and_references.md delete mode 100644 using_ant_from_gradle/importing_an_ant_build.md delete mode 100644 using_ant_from_gradle/using_ant_from_gradle.md delete mode 100644 using_ant_from_gradle/using_ant_tasks_and_types_in_your_build.md delete mode 100644 using_ant_from_gradle/using_custom_ant_tasks_in_your_build.md delete mode 100644 using_the_gradle_command-line/README.md delete mode 100644 using_the_gradle_command-line/continuing_the_build_when_a_failure_occurs.md delete mode 100644 using_the_gradle_command-line/excluding_tasks.md delete mode 100644 using_the_gradle_command-line/executing_multiple_tasks.md delete mode 100644 using_the_gradle_command-line/getting_the_insight_into_a_particular_dependency.md delete mode 100644 using_the_gradle_command-line/listing_project_dependencies.md delete mode 100644 using_the_gradle_command-line/listing_project_properties.md delete mode 100644 using_the_gradle_command-line/listing_projects.md delete mode 100644 using_the_gradle_command-line/listing_tasks.md delete mode 100644 using_the_gradle_command-line/listing_taskss.md delete mode 100644 using_the_gradle_command-line/profiling_a_build.md delete mode 100644 using_the_gradle_command-line/selecting_which_build_to_execute.md delete mode 100644 using_the_gradle_command-line/show_task_usage_details.md delete mode 100644 using_the_gradle_command-line/task_name_abbreviation.md delete mode 100644 using_the_gradle_graphical_user_interface/README.md delete mode 100644 using_the_gradle_graphical_user_interface/command_line.md delete mode 100644 using_the_gradle_graphical_user_interface/favorities.md delete mode 100644 using_the_gradle_graphical_user_interface/setup.md delete mode 100644 using_the_gradle_graphical_user_interface/task_tree.md delete mode 100644 web_application_quickstart/README.md delete mode 100644 web_application_quickstart/building_a_war_file.md delete mode 100644 web_application_quickstart/running_your_web_application.md delete mode 100644 web_application_quickstart/summary.md delete mode 100644 working_with_files/README.md delete mode 100644 working_with_files/copying_files.md delete mode 100644 working_with_files/creating_archives.md delete mode 100644 working_with_files/file_collections.md delete mode 100644 working_with_files/file_trees.md delete mode 100644 working_with_files/java.md delete mode 100644 working_with_files/locating_files.md delete mode 100644 working_with_files/specifying_a_set_of_input_files.md delete mode 100644 working_with_files/using_a_file_collection.md delete mode 100644 working_with_files/using_the_contents_of_an_archive_as_a_file_tree.md delete mode 100644 working_with_files/using_the_sync_task.md delete mode 100644 writing_build_scripts/README.md delete mode 100644 writing_build_scripts/closure_delegate.md delete mode 100644 writing_build_scripts/closures_as_the_last_parameter_in_a_method.md delete mode 100644 writing_build_scripts/declaring_variables.md delete mode 100644 writing_build_scripts/extra_properties.md delete mode 100644 writing_build_scripts/groovy_jdk.md delete mode 100644 writing_build_scripts/list_and_map_literals.md delete mode 100644 writing_build_scripts/local_variables.md delete mode 100644 writing_build_scripts/optional_parentheses_on_method_calls.md delete mode 100644 writing_build_scripts/property_accessors.md delete mode 100644 writing_build_scripts/some_groovy_basics.md delete mode 100644 writing_build_scripts/standard_project_properties.md delete mode 100644 writing_build_scripts/the_gradle_build_language.md delete mode 100644 writing_build_scripts/the_project_api.md delete mode 100644 writing_build_scripts/the_script_api.md diff --git a/build_script_basics/README.md b/build_script_basics/README.md deleted file mode 100644 index d635a1f..0000000 --- a/build_script_basics/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# 构建脚本的基础知识 - -这一章主要讲解以下内容 - -* Projects 和 tasks -* Hello world -* 快捷的任务定义 -* 构建脚本代码 -* 任务依赖 -* 动态任务 -* 使用已经存在的任务 -* 快捷注释 -* 附加的 task 属性 -* 使用 Ant 任务 -* 使用方法 -* 默认的任务 -* 通过 DAG 配置 - - - diff --git a/build_script_basics/a_shortcut_task_definition.md b/build_script_basics/a_shortcut_task_definition.md deleted file mode 100644 index 1a0e33e..0000000 --- a/build_script_basics/a_shortcut_task_definition.md +++ /dev/null @@ -1,23 +0,0 @@ -# 快捷的任务定义 - -有一种比我们之前定义的 hello 任务更简明的方法 - -**例子 6.3. 快捷的任务定义** - -*build.gradle* - - task hello << { - println 'Hello world!' - } - -它定义了一个叫做 hello 的任务, -这个任务是一个可以执行的闭包. -我们将使用这种方式来定义这本指南里所有的任务. - -**翻译者补充** - -与前面的例子比较, -doLast 被替换成了 <<. -它们有一样的功能, -但看上去更加简洁了, -会在后续章节 (6.7) 详细讲解它们的功能. diff --git a/build_script_basics/build_scripts_are_code.md b/build_script_basics/build_scripts_are_code.md deleted file mode 100644 index f74f6b5..0000000 --- a/build_script_basics/build_scripts_are_code.md +++ /dev/null @@ -1,34 +0,0 @@ -# 构建脚本代码 - -Gradle 的构建脚本展示了 Groovy 的所有能力. 作为开胃菜, 来看看这个: - -**例子 6.4. 在 Gradle 任务里使用 Groovy** - -*build.gradle* - - task upper << { - String someString = 'mY_nAmE' - println "Original: " + someString - println "Upper case: " + someString.toUpperCase() - } - -**gradle -q upper** 命令的输出 - - > gradle -q upper - Original: mY_nAmE - Upper case: MY_NAME - -或者 - -**例子 6.5. 在 Gradle 任务里使用 Groovy** - -*build.gradle* - - task count << { - 4.times { print "$it " } - } - -**gradle -q count** 命令的输出 - - > gradle -q count - 0 1 2 3 diff --git a/build_script_basics/configure_by_dag.md b/build_script_basics/configure_by_dag.md deleted file mode 100644 index f9903b4..0000000 --- a/build_script_basics/configure_by_dag.md +++ /dev/null @@ -1,48 +0,0 @@ -# 通过 DAG 配置 - -正如我们之后的详细描述 (参见第55章,构建的生命周期), Gradle 有一个配置阶段和执行阶段. -在配置阶段后, -Gradle 将会知道应执行的所有任务. -Gradle 为你提供一个"钩子", -以便利用这些信息. -举个例子, -判断发布的任务是否在要被执行的任务当中. -根据这一点, -你可以给一些变量指定不同的值. - -在接下来的例子中, -distribution 任务和 release 任务将根据变量的版本产生不同的值. - -**例子 6.16. 根据选择的任务产生不同的输出** - -*build.gradle* - - task distribution << { - println "We build the zip with version=$version" - } - - task release(dependsOn: 'distribution') << { - println 'We release now' - } - - gradle.taskGraph.whenReady {taskGraph -> - if (taskGraph.hasTask(release)) { - version = '1.0' - } else { - version = '1.0-SNAPSHOT' - } - } - -**gradle -q distribution** 命令的输出 - - > gradle -q distribution - We build the zip with version=1.0-SNAPSHOT - Output of gradle -q release - > gradle -q release - We build the zip with version=1.0 - We release now - -最重要的是 whenReady 在 release 任务执行之前就已经影响了 release 任务. -甚至 release 任务不是首要任务 (i.e., 首要任务是指通过 gradle 命令的任务). - - diff --git a/build_script_basics/default_tasks.md b/build_script_basics/default_tasks.md deleted file mode 100644 index 32aaace..0000000 --- a/build_script_basics/default_tasks.md +++ /dev/null @@ -1,32 +0,0 @@ -# 默认任务 - -Gradle 允许在脚本中定义一个或多个默认任务. - -**例子 6.15. 定义默认任务** - -*build.gradle* - - defaultTasks 'clean', 'run' - - task clean << { - println 'Default Cleaning!' - } - - task run << { - println 'Default Running!' - } - - task other << { - println "I'm not a default task!" - } - -**gradle -q** 命令的输出 - - > gradle -q - Default Cleaning! - Default Running! - -等价于 **gradle -q clean run**. -在一个多项目构建中, 每一个子项目都可以有它特别的默认任务. 如果一个子项目没有特别的默认任务, 父项目的默认任务将会被执行. - - diff --git a/build_script_basics/dynamic_tasks.md b/build_script_basics/dynamic_tasks.md deleted file mode 100644 index 319dcd7..0000000 --- a/build_script_basics/dynamic_tasks.md +++ /dev/null @@ -1,22 +0,0 @@ -# 动态任务 - -Groovy 不仅仅被用来定义一个任务可以做什么. -举个例子, -你可以使用它来动态的创建任务. - -**例子 6.8. 动态的创建一个任务** - -*build.gradle* - - 4.times { counter -> - task "task$counter" << { - println "I'm task number $counter" - } - } - -这里动态的创建了 task0, task1, task2, task3 - -**gradle -q task1** 命令的输出 - - > gradle -q task1 - I'm task number 1 diff --git a/build_script_basics/extra_task_properties.md b/build_script_basics/extra_task_properties.md deleted file mode 100644 index 1afc7a4..0000000 --- a/build_script_basics/extra_task_properties.md +++ /dev/null @@ -1,27 +0,0 @@ -# 自定义任务属性 - -你可以给任务加入自定义的属性. -列如加入一个叫做 myProperty 属性, -设置一个初始值给 ext.myProperty. -然后, -该属性就可以像一个预定义的任务属性那样被读取和设置了. - -**例子 6.12. 给任务加入自定义属性** - -*build.gradle* - - task myTask { - ext.myProperty = "myValue" - } - - task printTaskProperties << { - println myTask.myProperty - } - -**gradle -q printTaskProperties** 命令的输出 - - > gradle -q printTaskProperties - myValue - -给任务加自定义属性是没有限制的. 你可以在 13.4.2, “自定义属性” 里获得更多的信息. - diff --git a/build_script_basics/hello_world.md b/build_script_basics/hello_world.md deleted file mode 100644 index e258f56..0000000 --- a/build_script_basics/hello_world.md +++ /dev/null @@ -1,63 +0,0 @@ -# Hello world - -你可以通过 **gradle** 命令运行一个 Gradle 构建. - -**gradle** 命令会在当前目录中查找一个叫 **build.gradle** 的文件. -我们称这个 build.gradle 文件为一个构建脚本 (build script), 但是严格来说它是一个构建配置脚本 (build configuration script). 这个脚本定义了一个 project 和它的 tasks. - -让我们来先看一个例子, -创建一个名为build.gradle的构建脚本. - -**例子 6.1 第一个构建脚本** - -*build.gradle* - - task hello { - doLast { - println 'Hello world!' - } - } - -在命令行里, 进入脚本所在的文件夹然后输入 **gradle -q hello** 来执行构建脚本: - -**gradle -q hello** 的输出 - > gradle -q hello - Hello world! - -这里发生了什么? 这个构建脚本定义了一个独立的 task, -叫做 hello, -并且加入了一个 action. -当你运行 **gradle hello**, -Gradle 执行叫做 hello 的 task, -也就是执行了你所提供的 action. -这个 action 是一个包含了一些 Groovy 代码的闭包(closure 这个概念不清楚的同学好好谷歌下). - -如果你认为这些看上去和 Ant 的 targets 很相像, -好吧, -你是对的. -Gradle tasks 和 Ant 的 targets 是对等的. -但是你将会会看到, -Gradle tasks 更加强大. -我们使用一个不同于 Ant 的术语 task, -看上去比 target 更加能直白. -不幸的是这带来了一个术语冲突, -因为 Ant 称它的命令, -比如 javac 或者 copy, -叫 tasks. -所以当我们谈论 tasks, -是指 Gradle 的 tasks. -如果我们讨论 Ant 的 tasks (Ant 命令), 我们会直接称呼 ant task. - -####补充一点命令里的 **-q** 是干什么的? - -这个指南里绝大多说的例子会在命令里加入 **-q**. -代表 quiet 模式. -它不会生成 Gradle 的日志信息 (log messages), -所以用户只能看到 tasks 的输出. -它使得的输出更加清晰. -你并不一定需要加入这个选项. -参考第 18 章, -日志的 Gradle 影响输出的详细信息. - - - diff --git a/build_script_basics/manipulating_existing_tasks.md b/build_script_basics/manipulating_existing_tasks.md deleted file mode 100644 index 91d6c96..0000000 --- a/build_script_basics/manipulating_existing_tasks.md +++ /dev/null @@ -1,59 +0,0 @@ -# 使用已经存在的任务 - -当任务创建之后, -它可以通过API来访问. -这个和 Ant 不一样. -举个例子, -你可以创建额外的依赖. - -**例子 6.9. 通过API访问一个任务 - 加入一个依赖** - -*build.gradle* - - 4.times { counter -> - task "task$counter" << { - println "I'm task number $counter" - } - } - task0.dependsOn task2, task3 - -**gradle -q task0** 命令的输出 - - > gradle -q task0 - I'm task number 2 - I'm task number 3 - I'm task number 0 - -或者你可以给一个已经存在的任务加入行为. - -**例子 6.10. 通过API访问一个任务 - 加入行为** - - -*build.gradle* - - task hello << { - println 'Hello Earth' - } - hello.doFirst { - println 'Hello Venus' - } - hello.doLast { - println 'Hello Mars' - } - hello << { - println 'Hello Jupiter' - } - -**gradle -q hello** 命令的输出 - - > gradle -q hello - Hello Venus - Hello Earth - Hello Mars - Hello Jupiter - -doFirst 和 doLast 可以被执行许多次. 他们分别可以在任务动作列表的开始和结束加入动作. -当任务执行的时候, -在动作列表里的动作将被按顺序执行. -这里第四个行为中 << 操作符是 doLast 的简单别称. - diff --git a/build_script_basics/projects_and_tasks.md b/build_script_basics/projects_and_tasks.md deleted file mode 100644 index 37092a0..0000000 --- a/build_script_basics/projects_and_tasks.md +++ /dev/null @@ -1,26 +0,0 @@ -# Projects 和 tasks - -Gradle 里的任何东西都是基于这两个基础概念: - -* projects ( 项目 ) -* tasks ( 任务 ) - -每一个构建都是由一个或多个 projects 构成的. -一个 project 到底代表什么取决于你想用 Gradle 做什么. 举个例子, -一个 project 可以代表一个 JAR 或者一个网页应用. 它也可能代表一个发布的 ZIP 压缩包, -这个 ZIP 可能是由许多其他项目的 JARs 构成的. -但是一个 project 不一定非要代表被构建的某个东西. 它可以代表一件**要做的事, -比如部署你的应用. - -不要担心现在看不懂这些说明. -Gradle 的合约构建可以让你来具体定义一个 project 到底该做什么. - -每一个 project 是由一个或多个 tasks 构成的. -一个 task 代表一些更加细化的构建. -可能是编译一些 classes, -创建一个 JAR, -生成 javadoc, -或者生成某个目录的压缩文件. - -目前, -我们先来看看定义构建里的一些简单的 task. 以后的章节会讲解多项目构建以及如何通过 projects 和 tasks 工作. diff --git a/build_script_basics/shortcut_notations.md b/build_script_basics/shortcut_notations.md deleted file mode 100644 index ebdecba..0000000 --- a/build_script_basics/shortcut_notations.md +++ /dev/null @@ -1,29 +0,0 @@ -# 短标记法 - -正如同你已经在之前的示例里看到, -有一个短标记 $ 可以访问一个存在的任务. 也就是说每个任务都可以作为构建脚本的属性: - -**例子 6.11. 当成构建脚本的属性来访问一个任务** - -*build.gradle* - - task hello << { - println 'Hello world!' - } - hello.doLast { - println "Greetings from the $hello.name task." - } - -**gradle -q hello** 命令的输出 - - > gradle -q hello - Hello world! - Greetings from the hello task. - -这里的 name 是任务的默认属性, -代表当前任务的名称, -这里是 hello. - -这使得代码易于读取, -特别是当使用了由插件(如编译)提供的任务时尤其如此. - diff --git a/build_script_basics/task_dependencies.md b/build_script_basics/task_dependencies.md deleted file mode 100644 index 77dcaca..0000000 --- a/build_script_basics/task_dependencies.md +++ /dev/null @@ -1,52 +0,0 @@ -# 任务依赖 - -就像你所猜想的那样, -你可以声明任务之间的依赖关系. - -**例子 6.6. 申明任务之间的依赖关系** - -*build.gradle* - - task hello << { - println 'Hello world!' - } - - task intro(dependsOn: hello) << { - println "I'm Gradle" - } - -**gradle -q intro** 命令的输出 - - > gradle -q intro - Hello world! - I'm Gradle - -intro 依赖于 hello, -所以执行 intro 的时候 hello 命令会被优先执行来作为启动 intro 任务的条件. - -在加入一个依赖之前, -这个依赖的任务不需要提前定义, -来看下面的例子. - -**例子 6.7. Lazy dependsOn - 其他的任务还没有存在** - -*build.gradle* - - task taskX(dependsOn: 'taskY') << { - println 'taskX' - } - task taskY << { - println 'taskY' - } - -**gradle -q taskX** 命令的输出 - - > gradle -q taskX - taskY - taskX - -taskX 到 taskY 的依赖在 taskY 被定义之前就已经声明了. 这一点对于我们之后讲到的多任务构建是非常重要的. -任务依赖将会在 14.4 具体讨论. - -请注意你不能使用快捷注释 (参考 6.8, “快捷注释”) 当所关联的任务还没有被定义. - diff --git a/build_script_basics/using_ant_tasks.md b/build_script_basics/using_ant_tasks.md deleted file mode 100644 index 91f18c1..0000000 --- a/build_script_basics/using_ant_tasks.md +++ /dev/null @@ -1,34 +0,0 @@ -# 调用 Ant 任务 - -Ant 任务是 Gradle 的一等公民. -Gradle 通过 Groovy 出色的集成了 Ant 任务. -Groovy 自带了一个 AntBuilder. -相比于从一个 build.xml 文件中使用 Ant 任务, -在 Gradle 里使用 Ant 任务更为方便和强大. 从下面的例子中, -你可以学习如何执行 Ant 任务以及如何访问 ant 属性: - -**例子 6.13. 使用 AntBuilder 来执行 ant.loadfile 任务** - -*build.gradle* - - task loadfile << { - def files = file('../antLoadfileResources').listFiles().sort() - files.each { File file -> - if (file.isFile()) { - ant.loadfile(srcFile: file, property: file.name) - println " *** $file.name ***" - println "${ant.properties[file.name]}" - } - } - } - -**gradle -q loadfile** 命令的输出 - - > gradle -q loadfile - *** agile.manifesto.txt *** - Individuals and interactions over processes and tools - Working software over comprehensive documentation - Customer collaboration over contract negotiation - Responding to change over following a plan - *** gradle.manifesto.txt *** - diff --git a/build_script_basics/using_methods.md b/build_script_basics/using_methods.md deleted file mode 100644 index 180df8b..0000000 --- a/build_script_basics/using_methods.md +++ /dev/null @@ -1,37 +0,0 @@ -# 使用方法 - -Gradle 能很好地衡量你编写脚本的逻辑能力. 首先要做的是如何提取一个方法. - -**例子 6.14. 使用方法组织脚本逻辑** - -*build.gradle* - - task checksum << { - fileList('../antLoadfileResources').each {File file -> - ant.checksum(file: file, property: "cs_$file.name") - println "$file.name Checksum: ${ant.properties["cs_$file.name"]}" - } - } - - task loadfile << { - fileList('../antLoadfileResources').each {File file -> - ant.loadfile(srcFile: file, property: file.name) - println "I'm fond of $file.name" - } - } - - File[] fileList(String dir) { - file(dir).listFiles({file -> file.isFile() } as FileFilter).sort() - } - -**adle -q loadfile** 命令的输出 - - > gradle -q loadfile - I'm fond of agile.manifesto.txt - I'm fond of gradle.manifesto.txt - - -稍后你看到, -这种方法可以在多项目构建的子项目之间共享. 如果你的构建逻辑变得更加复杂, -Gradle 为你提供了其他非常方便的方法. 请参见第59章,组织构建逻辑。 - diff --git a/dependency_management_basics/README.md b/dependency_management_basics/README.md deleted file mode 100644 index 2feb26e..0000000 --- a/dependency_management_basics/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# 依赖管理的基础知识 - -* 什么是依赖管理 - -* 声明你的依赖 - -* 依赖配置 - -* 外部的依赖 - -* 仓库 - -* 发布 artifacts - diff --git a/dependency_management_basics/a_basic_java_project.md b/dependency_management_basics/a_basic_java_project.md deleted file mode 100644 index 72042a6..0000000 --- a/dependency_management_basics/a_basic_java_project.md +++ /dev/null @@ -1,22 +0,0 @@ -# 声明你的依赖 - -让我们看一下一些依赖的声明. 下面是一个基础的构建脚本: - -**例子 8.1. 声明依赖** - -**build.gradle** - - apply plugin: 'java' - - repositories { - mavenCentral() - } - - dependencies { - compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' - testCompile group: 'junit', name: 'junit', version: '4.+' - } - -这里发生了什么? 这个构建脚本声明 Hibernate core 3.6.7.最终 被用来编译项目的源代码. 言外之意是, 在运行阶段同样也需要 Hibernate core 和它的依赖. 构建脚本同样声明了需要 junit >= 4.0 的版本来编译项目测试. 它告诉 Gradle 到 Maven 中央仓库里找任何需要的依赖. 接下来的部分会具体说明. - - diff --git a/dependency_management_basics/dependency_configurations.md b/dependency_management_basics/dependency_configurations.md deleted file mode 100644 index 079d3fd..0000000 --- a/dependency_management_basics/dependency_configurations.md +++ /dev/null @@ -1,24 +0,0 @@ -# 依赖配置 - -在 Gradle 里, 依赖可以组合成*configurations(配置)*. 一个配置简单地说就是一系列的依赖. 我们称它们为*(dependency configuration)依赖配置*. 你可以使用它们声明项目的外部依赖. 正如我们将在后面看到, 它们也被用来声明项目的发布. - -Java 插件定义了许多标准的配置. 下面列出了一些, 你也可以在[Table 23.5, “Java 插件 - 依赖管理”](https://dongchuan.gitbooks.io/gradle-user-guide-/content/the_java_plugin/java_plugin_dependency_management.html)里发现更多具体的信息. - -**compile** - -用来编译项目源代码的依赖. - -**runtime** - -在运行时被生成的类使用的依赖. 默认的, 也包含了编译时的依赖. - -**testCompile** - -编译测试代码的依赖. 默认的, 包含生成的类运行所需的依赖和编译源代码的依赖. - -**testRuntime** - -运行测试所需要的依赖. 默认的, 包含上面三个依赖. - -各种各样的插件加入许多标准的配置. 你也可以定义你自己的配置. 参考 [Section 52.3, “配置依赖”](https://docs.gradle.org/current/userguide/dependency_management.html#sub:configurations)可以找到更加具体的定义和定制一个自己的依赖配置. - diff --git a/dependency_management_basics/external_dependencies.md b/dependency_management_basics/external_dependencies.md deleted file mode 100644 index b139afc..0000000 --- a/dependency_management_basics/external_dependencies.md +++ /dev/null @@ -1,29 +0,0 @@ -# 外部的依赖 - -你可以声明许多种依赖. 其中一种是*external dependency(外部依赖)*. 这是一种在当前构建之外的一种依赖, 它被存放在远程或本地的仓库里, 比如 Maven 的库, 或者 Ivy 库, 甚至是一个本地的目录. - -下面的例子讲展示如何加入外部依赖 - -*例子 8.2. 定义一个外部依赖* - -*build.gradle* - - dependencies { - compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' - } - -引用一个外部依赖需要使用 group, name 和 version 属性. 根据你想要使用的库, group 和 version 可能会有所差别. - -有一种简写形式, 只使用一串字符串 `"group:name:version"`. - -*例子 8.3. 外部依赖的简写形式* - -*build.gradle* - - dependencies { - compile 'org.hibernate:hibernate-core:3.6.7.Final' - } - - -要了解跟多关于定义并使用依赖工作的信息,参见[Section 52.4,"How to declare you dependencies"](https://docs.gradle.org/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies). - diff --git a/dependency_management_basics/publishing_artifacts.md b/dependency_management_basics/publishing_artifacts.md deleted file mode 100644 index 80720d4..0000000 --- a/dependency_management_basics/publishing_artifacts.md +++ /dev/null @@ -1,45 +0,0 @@ -# 发布 artifacts -依赖配置也可以用来发布文件[3]. 我们称这些文件`publication artifacts`, 或者就叫 *artifacts*. - -插件可以很好的定义一个项目的 artifacts, 所以你并不需要做一些特别的工作来让 Gradle 需要发布什么. 你可以通过在 uploadArchives 任务里加入仓库来完成. 下面是一个发布远程 Ivy 库的例子: - -**例子 8.8. 发布一个 Ivy 库** - -**build.gradle** - - uploadArchives { - repositories { - ivy { - credentials { - username "username" - password "pw" - } - url "http://repo.mycompany.com" - } - } - } - -现在, 当你运 `gradle uploadArchives`, Gradle 将构建和上传你的 Jar. Gradle 也会生成和上传 ivy.xml . - -你也可以发布到 Maven 库.语法是稍有不同[4]. 请注意你需要加入 Maven 插件来发布一个 Maven 库. 在下面的例子里, Gradle 将生成和上传 pom.xml. - -*例子 8.9. 发布 Maven 库* - -*build.gradle* - - apply plugin: 'maven' - - uploadArchives { - repositories { - mavenDeployer { - repository(url: "file://localhost/tmp/myRepo/") - } - } - } - -在[Chapter 53, Publishing artifacts](https://docs.gradle.org/current/userguide/artifact_management.html), 发布 artifacts 里有更加具体的介绍. - -> [3] 我们认为这令人困惑,我们正在在Gradle DSL中逐步的区别这两个概念. - -> [4] 我们正在努力解决从Maven仓库发布,获取的语法一致性. - diff --git a/dependency_management_basics/repositories.md b/dependency_management_basics/repositories.md deleted file mode 100644 index a6e05b2..0000000 --- a/dependency_management_basics/repositories.md +++ /dev/null @@ -1,56 +0,0 @@ -# 仓库 - -Gradle 是怎样找到那些外部依赖的文件的呢? Gradle 会在一个*repository(仓库)*里找这些文件. 仓库其实就是文件的集合, 通过 `group`, `name` 和 `version` 整理分类. Gradle 能解析好几种不同的仓库形式, 比如 Maven 和 Ivy, 同时可以理解各种进入仓库的方法, 比如使用本地文件系统或者 HTTP. - -默认地, Gradle 不提前定义任何仓库. 在使用外部依赖之前, 你需要自己至少定义一个库. 比如使用下面例子中的 Maven central 仓库: - -*例子 8.4. Maven central 仓库* - -*build.gradle* - - repositories { - mavenCentral() - } - -或者使用一个远程的 Maven 仓库: - -*例子 8.5. 使用远程的 Maven 仓库* - -*build.gradle* - - repositories { - maven { - url "http://repo.mycompany.com/maven2" - } - } - -或者一个远程的 Ivy 仓库: - -*例子 8.6. 使用远程的 Ivy 仓库* - -*build.gradle* - - repositories { - ivy { - url "http://repo.mycompany.com/repo" - } - } - -你也可以使用本地的文件系统里的库. Maven 和 Ivy 都支持下载的本地. - -*例子 8.7. 使用本地的 Ivy 目录* - -build.gradle - - repositories { - ivy { - // URL can refer to a local directory - url "../local-repo" - } - } - -一个项目可以有好几个库. Gradle 会根据依赖定义的顺序在各个库里寻找它们, 在第一个库里找到了就不会再在第二个库里找它了. - -可以在[Section 50.6 章, “仓库”](https://docs.gradle.org/current/userguide/dependency_management.html#sec:repositories)里找到更详细的信息. - - diff --git a/dependency_management_basics/what_is_dependency_management.md b/dependency_management_basics/what_is_dependency_management.md deleted file mode 100644 index 0fc41e4..0000000 --- a/dependency_management_basics/what_is_dependency_management.md +++ /dev/null @@ -1,17 +0,0 @@ -# 什么是依赖管理? - -粗略的讲, 依赖管理由两部分组成. 首先, Gradle 需要了解你的项目需要构建或运行的东西, 以便找到它们. 我们称这些传入的文件为项目的 *dependencies(依赖项)*. 其次, Gradle 需要构建并上传你的项目产生的东西. 我们称这些传出的项目文件为 *publications(发布项)*. 让我们来看看这两条的详细信息: - -大多数项目都不是完全独立的. 它们需要其它项目进行编译或测试等等. 举个例子, 为了在项目中使用 Hibernate, 在编译的时候需要在 `classpath` 中添加一些 Hibernate 的 jar 路径. 要运行测试的时候, 需要在 `test classpath` 中包含一些额外的 jar, 比如特定的 JDBC 驱动或者 `Ehcache jars`. - -这些传入的文件构成上述项目的依赖. Gradle 允许你告诉它项目的依赖关系, 以便找到这些依赖关系, 并在你的构建中维护它们. 依赖关系可能需要从远程的 Maven 或者 Ivy 仓库中下载, 也可能是在本地文件系统中, 或者是通过多项目构建另一个构建. 我们称这个过程为 *dependency resolution(依赖解析)*. - -这一特性与 Ant 相比效率提高了许多. 使用 Ant, 你只有指定 jar 的绝对路径或相对路径才能读取 jar. 使用 Gradle, 你只需要申明依赖的名称, 然后它会通过其它的设置来决定在哪里获取这些依赖关系, 比如从 Maven 库. 你可以为 Ant 添加 Apache Ivy 库或得类似的方法, 但是 Gradle 做的更好. - -通常, 一个项目本身会具有依赖性. 举个例子, 运行 Hibernate 的核心需要其他几个类库在 classpath 中. 因此, Gradle 在为你的项目运行测试的时候, 它会找到这些依赖关系, 并使其可用. 我们称之为*transitive dependencies(依赖传递)*. - -大部分项目的主要目的是要建立一些文件, 在项目之外使用. 比如, 你的项目产生一个 Java 库,你需要构建一个jar, 可能是一个 jar 和一些文档, 并将它们发布在某处. - -这些传出的文件构成了项目的发布. Gradle 当然会为你负责这个重要的工作. 你声明项目的发布, Gradle 会构建并发布在某处. 究竟什么是"发布"取决于你想做什么. 可能你希望将文件复制到本地目录, 或者将它们上传到一个远程 Maven 或者 Ivy 库.或者你可以使用这些文件在多项目构建中应用在其它的项目中. 我们称这个过程为 *publication(发布)* - - diff --git a/dependency_management_basics/where_to_next.md b/dependency_management_basics/where_to_next.md deleted file mode 100644 index 70169bb..0000000 --- a/dependency_management_basics/where_to_next.md +++ /dev/null @@ -1,7 +0,0 @@ -# 下一步? - -对于依赖关系的所有细节,参见[Chapter 52, 依赖管理](https://docs.gradle.org/current/userguide/dependency_management.html),artifact发布细节,参见[Chapter 53, Publishing artifacts](https://docs.gradle.org/current/userguide/artifact_management.html). - -如果你对这里提及的DSL元素感兴趣,看看[Project.configurations{}](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:configurations(groovy.lang.Closure)),[Project.repositories{}]https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:repositories(groovy.lang.Closure)和[Project.dependencies{}](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:dependencies(groovy.lang.Closure)). - -否则,继续到其他[tutorials](https://docs.gradle.org/current/userguide/tutorials.html). diff --git a/gradle_plugins/README.md b/gradle_plugins/README.md deleted file mode 100644 index f32649f..0000000 --- a/gradle_plugins/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Gradle 插件 - -Gradle 的核心为真实世界提供了很少的自动化. -所有的实用特性,类似编译java源码的能力, 是由*插件*提供的. 插件添加了新的任务(如:[JavaCompile](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html)),域对象(如:[SourceSet](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSet.html)),公约(如:Java资源位置是`src/main/java`)以及来自其他插件延伸核心对象和对象。 - -在本章中,我们将讨论如何使用插件和关于插件的周边概念和术语。 diff --git a/gradle_plugins/applying_plugins.md b/gradle_plugins/applying_plugins.md deleted file mode 100644 index ec56e96..0000000 --- a/gradle_plugins/applying_plugins.md +++ /dev/null @@ -1,6 +0,0 @@ -# 应用插件 - -插件需要声明*被应用*,通过[Project.apply()](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:apply(java.util.Map)方法完成.应用的插件是*idempotent*[注1](),即相同的插件可以应用多次.如果插件先前以被应用,任何后来的应用是安全的,不会有任何影响的. - - -[1]译注:英文直接翻译的意思是幂等(denoting an element of a set that is unchanged in value when multiplied or otherwise operated on by itself.),上下中的大意应该是不会受其他因素的影响. diff --git a/gradle_plugins/applying_plugins_with_the_buildscript_block.md b/gradle_plugins/applying_plugins_with_the_buildscript_block.md deleted file mode 100644 index be57b6e..0000000 --- a/gradle_plugins/applying_plugins_with_the_buildscript_block.md +++ /dev/null @@ -1,22 +0,0 @@ -# 使用构建脚本块应用插件 - -项目可以通过添加向构建脚本中加入插件的类路径然后在应用插件,添加作为外部JAR文件的二进制插件.外部jar可以使用`buildscrip{}`块添加到构建脚本类路径就像[Section 62.6, “External dependencies for the build script”](https://docs.gradle.org/current/userguide/organizing_build_logic.html#sec:external_dependencies)中描述的一样. - -**Example 21.4. Applying a plugin with the buildscript block** - -**build.gradle** - -```gradle -buildscript { - repositories { - jcenter() - } - dependencies { - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:0.4.1" - } -} - -apply plugin: "com.jfrog.bintray" -``` - - diff --git a/gradle_plugins/applying_plugins_with_the_plugins_dsl.md b/gradle_plugins/applying_plugins_with_the_plugins_dsl.md deleted file mode 100644 index 73bba2c..0000000 --- a/gradle_plugins/applying_plugins_with_the_plugins_dsl.md +++ /dev/null @@ -1,33 +0,0 @@ -# 使用插件的插件DSL - -> 插件DSL正在孵化([incubating](https://docs.gradle.org/current/userguide/feature_lifecycle.html))中,请注意,在以后的Gradle版本中,DSL和其它配置可能会改变. - -新的插件DSL提供了更为简洁,方便的方式来声明插件的依赖关系。它的适用于与新的[Gradle Plugin Portal](http://plugins.gradle.org/),同时提供了方便的核心和社区插件.该插件脚本块配置[PluginDependenciesSpec](https://docs.gradle.org/current/dsl/org.gradle.plugin.use.PluginDependenciesSpec.html)的实例. - -要应用的核心插件,可以使用短名称: - -**Example 21.5. Applying a core plugin** - -**build.gradle** - -```gradle -plugins { - id 'java' -} -``` - -要从插件门户应用一个社区插件,必须使用插件的完全限定id: - -**Example 21.6. Applying a community plugin** - -**build.gradle** - -```gradle -plugins { - id "com.jfrog.bintray" version "0.4.1" -} -``` - -不必要进行进一步的配置,就是说没有必要配置buildscript的类路径,Gradle会从插件门户找到该插件,并使构建可用. - -参见[PluginDependenciesSpec](https://docs.gradle.org/current/dsl/org.gradle.plugin.use.PluginDependenciesSpec.html)查看关于使用插件DSL的更多信息。 diff --git a/gradle_plugins/binary_plugins.md b/gradle_plugins/binary_plugins.md deleted file mode 100644 index 3cd3238..0000000 --- a/gradle_plugins/binary_plugins.md +++ /dev/null @@ -1,23 +0,0 @@ -# 二进制插件 - -**Example 21.2. Applying a binary plugin** - -**build.gradle** -```gradle -apply plugin: 'java' -``` - -插件可以使用*插件ID*应用.插件的id作为给定的插件的唯一标识符.核心插件注册一个可以用作插件的id的短名称.在上述情况下,我们可以使用简称`java`的插件以应用[JavaPlugin](https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/JavaPlugin.html).社区插件,一方面会使用一个完全合格的形式的插件id(如`com.github.foo.bar`),但还是有一些传统的插件可能仍然使用很短的,不合格的格式. - -不使用一个插件的id,插件也可以通过简单地指定类来应用插件: - -**Example 21.3. Applying a binary plugin by type** - -**build.gradle** - -```gradle -apply plugin: JavaPlugin -``` - -在上面的例子中,JavaPlugin是指[JavaPlugin](https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/JavaPlugin.html),此类不是严格需要导入org.gradle.api.plugins包中的所有自动导入构建脚本(见:[附录E,现有的IDE支持,以及如何没有它应付](https://docs.gradle.org/current/userguide/ide_support.html)).此外,这是没有必要追加的.class以识别一个类常量在Groovy,因为它是在Java中。 - diff --git a/gradle_plugins/can_only_be_used_in_build_scripts.md b/gradle_plugins/can_only_be_used_in_build_scripts.md deleted file mode 100644 index c9df7fb..0000000 --- a/gradle_plugins/can_only_be_used_in_build_scripts.md +++ /dev/null @@ -1,5 +0,0 @@ -# 只能在构建脚本中使用 - -插件`{}`块目前只能在一个项目的构建脚本中使用.他不能在脚本插件,`settings.gradle`和出书画脚本中使用. - -*Gradle的未来版本将删除此限制.* diff --git a/gradle_plugins/cannot_be_used_in_conjunction.md b/gradle_plugins/cannot_be_used_in_conjunction.md deleted file mode 100644 index c7410fb..0000000 --- a/gradle_plugins/cannot_be_used_in_conjunction.md +++ /dev/null @@ -1,9 +0,0 @@ -# 不能与subjects{},allprojects{}等结合使用 - -目前不能使用一次添加一个插件到多个项目中的模式,如使用`subprojects{}`等方式.目前没有机制可以应用一次插件到多个项目.目前,每个项目都必须在自己的构建脚本中的`plugins{}`块中声明应用的插件. - -*Gradle的未来版本将删除此限制.* - -如果新语法的限制让人望而却步,推荐使用[buildscript{} block](https://docs.gradle.org/current/userguide/plugins.html#sec:applying_plugins_buildscript). - - diff --git a/gradle_plugins/constrained_syntax.md b/gradle_plugins/constrained_syntax.md deleted file mode 100644 index 51a39df..0000000 --- a/gradle_plugins/constrained_syntax.md +++ /dev/null @@ -1,16 +0,0 @@ -# 约束语法 - -新插件`{}`块不支持任意Groovy代码.被限制的原因是为幂等(每次产生相同的结果)和无副作用(为了Gradle随时执行的安全). - - -形式是: - -```Gradle -plugins{ - id «plugin id» version «plugin version» -} -``` - -`«plugin id»`和`«plugin version»`必须是常量,字面量,字符串.其他语句都是不允许的;他们的存在会导致编译错误. - -插件`{}`块也必须在构建脚本的顶部声明.它不能被嵌套在另一个结构(例如,if语句或for循环). diff --git a/gradle_plugins/finding_community_plugins.md b/gradle_plugins/finding_community_plugins.md deleted file mode 100644 index 2a876dc..0000000 --- a/gradle_plugins/finding_community_plugins.md +++ /dev/null @@ -1,3 +0,0 @@ -# 查找社区插件 - -Gradle有一个充满活力的,卡法人员做出不用贡献的插件社区.该Gradle[插件门户](http://plugins.gradle.org/)提供搜索和探索社区插件的接口. diff --git a/gradle_plugins/limitations_of_the_plugins_dsl.md b/gradle_plugins/limitations_of_the_plugins_dsl.md deleted file mode 100644 index 713292b..0000000 --- a/gradle_plugins/limitations_of_the_plugins_dsl.md +++ /dev/null @@ -1,11 +0,0 @@ -# 插件DSL的限制 - -想项目中添加插件的新方法不仅仅是一种更为方便的语法.新的DSL语法处理与老方法有很大的不同.新的机制允许Gradle更早更快的确定插件.这允许做更智能的事,如: - -* 优化插件类的加载和重用. -* 允许不同的插件使用不同版本的依赖关系. -* 为编辑构建脚本提供关于隐含属性和值的详细信息 - -这要求插件被指定使Gradle在执行之前剩下的构建脚本前可以很容易并且很快的提取它.还要求插件使用一些静态的定义。 - -新的插件机制与"传统的"`apply()`方法有一些关键区别.也有一些限制,其中一些限制是临时的,随着机制的成熟会逐渐没有,还有一些是方法固有的. diff --git a/gradle_plugins/locations_of_binary_plugins.md b/gradle_plugins/locations_of_binary_plugins.md deleted file mode 100644 index d430591..0000000 --- a/gradle_plugins/locations_of_binary_plugins.md +++ /dev/null @@ -1,10 +0,0 @@ -# 二进制插件的位置 - -一个插件是一个简单的实现了[插件](https://docs.gradle.org/current/javadoc/org/gradle/api/Plugin.html)接口的类.Gradle提供的核心插件作为其分布的一部分,因此,你需要做的仅仅是应用上述的插件.然而,非核心二进制插件需要到构建类路径才能应用它们.这可以以多种方式,包括以下方式实现: - -* 定义插件作为构建脚本中内嵌类的声明. -* 定义插件为在项目中buildSrc目录下的一个源文件.(参见[Section 62.4, “Build sources in the buildSrc project”](https://docs.gradle.org/current/userguide/organizing_build_logic.html#sec:build_sources)) -* 包含来自外部jar定义的构建脚本依赖插件(参见[Section 21.4, “Applying plugins with the buildscript block”](https://docs.gradle.org/current/userguide/plugins.html#sec:applying_plugins_buildscript)) -* 包含插件DSL语言组成的插件门户网站([Section 21.5, “Applying plugins with the plugins DSL”](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block)) - -欲了解有关自定义插件的跟多信息,参见[Chapter 61, Writing Custom Plugins](https://docs.gradle.org/current/userguide/custom_plugins.html) diff --git a/gradle_plugins/more_on_plugins.md b/gradle_plugins/more_on_plugins.md deleted file mode 100644 index 49e69d8..0000000 --- a/gradle_plugins/more_on_plugins.md +++ /dev/null @@ -1,3 +0,0 @@ -# 更多关于插件 - -本章旨在作为介绍插件和Gradle,以及他们扮演的角色.要了解更过关于插件内部的工作原理,参见[Chapter 61, Writing Custom Plugins](https://docs.gradle.org/current/userguide/custom_plugins.html). diff --git a/gradle_plugins/script_plugins.md b/gradle_plugins/script_plugins.md deleted file mode 100644 index bf04aab..0000000 --- a/gradle_plugins/script_plugins.md +++ /dev/null @@ -1,11 +0,0 @@ -# 脚本插件 - -**Example 21.1. Applying a script plugin** - -**build.gradle** - -```gradle -apply from: 'other.gradle' -``` - -脚本插件可以从本地文件系统或在远程位置的脚本中*应用*.文件系统的位置是相对于项目目录,而远程脚本位置的是由一个`HTTP URL`指定的.多个脚本插件(两种形式之一)可以被*应用*到给定的构建。 diff --git a/gradle_plugins/types_of_plugins.md b/gradle_plugins/types_of_plugins.md deleted file mode 100644 index 89a3903..0000000 --- a/gradle_plugins/types_of_plugins.md +++ /dev/null @@ -1,5 +0,0 @@ -# 插件的类型 - -在Gradle中一般有两种类型的插件,*脚本*插件和*二进制*插件.*脚本*插件是额外的构建脚本,它会进一步配置构建,通常实行声明的方式操纵的构建.尽管他们可以外部化并且从远程位置访问,它们通常还是会在构建内部中使用.*二进制*插件是实现了[Plugin](https://docs.gradle.org/current/javadoc/org/gradle/api/Plugin.html)接口的类,并且采用编程的方式来操纵构建.*二进制*插件可以驻留在构建脚本,项目层级内或外部的插件jar. - - diff --git a/gradle_plugins/what_plugins_do.md b/gradle_plugins/what_plugins_do.md deleted file mode 100644 index f3c970c..0000000 --- a/gradle_plugins/what_plugins_do.md +++ /dev/null @@ -1,15 +0,0 @@ -# 插件的作用是什么 - -应用插件到项目允许插件来扩展项目的能力。它可以做的事情,如: - -* 扩展摇篮模型(如:添加可配置新的DSL元素) -* 按照惯例配置项目(如:添加新的任务或配置合理的默认值) -* 应用特定的配置(如:增加组织库或执行标准) - -通过应用插件,而不是向项目构建脚本添加逻辑,我们可以收获很多好处.应用插件: - -* 促进重用和减少维护在多个项目类似的逻辑的开销 -* 允许更高程度的模块化,提高综合性和组织 -* 封装必要的逻辑,并允许构建脚本尽可能是声明性地 - - diff --git a/groovy_quickstart/README.md b/groovy_quickstart/README.md deleted file mode 100644 index 0bf2206..0000000 --- a/groovy_quickstart/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Groovy 快速入门 - -构建 Groovy 项目时, 你需要使用 `Groovy plugin (Groovy插件)`. 这个插件扩展了 Java 插件, 加入了编译 Groovy 的依赖. 你的项目可以包含 Groovy 的源代码, Java 源代码, 或者它们的混合.在其他方面,一个Groovy项目与Java项目是相同的,就像我们在[Chapter 7, Java Quickstart](https://docs.gradle.org/current/userguide/tutorial_java_projects.html)见到的一样. - diff --git a/groovy_quickstart/a_basic_groovy_project.md b/groovy_quickstart/a_basic_groovy_project.md deleted file mode 100644 index afbf865..0000000 --- a/groovy_quickstart/a_basic_groovy_project.md +++ /dev/null @@ -1,47 +0,0 @@ -# 一个基本的 Groovy 项目 - -让我们看一个例子. 为了使用 Groovy 插件, 加入下面的代码: - -**例子 8.1. Groovy 插件** - -**build.gradle** - - apply plugin: 'groovy' - -> 注意:这个例子的代码可以在 `samples/groovy/quickstart` 在Gradle分布的 `"-all"` 中找到. - -它也会同时把 Java 插件加入到你的项目里. Groovy 插件扩展了编译任务, 这个任务会在 src/main/groovy 目录里寻找源代码文件, 并且加入了编译测试任务来寻找 src/test/groovy 目录里的测试源代码. 编译任务使用 联合编译 (joint compilation) 来编译这些目录, 这里的联合指的是它们混合有 java 和 groovy 的源文件. - -使用 groovy 编译任务, 你必须声明 Groovy 的版本和 Groovy 库的位置. 你可以在配置文件里加入依赖, 编译配置会继承这个依赖, 然后 groovy 库将被包含在 classpath 里. - -*例子 8.2. Groovy 2.2.0* - -*build.gradle* - - repositories { - mavenCentral() - } - - dependencies { - compile 'org.codehaus.groovy:groovy-all:2.3.3' - } - -下面是完整的构建文件: - -*例子 8.3. 完整的构建文件* - -*build.gradle* - - apply plugin: 'eclipse' - apply plugin: 'groovy' - - repositories { - mavenCentral() - } - - dependencies { - compile 'org.codehaus.groovy:groovy-all:2.3.3' - testCompile 'junit:junit:4.11' - } - -运行 **gradle build** 命令将会开始编译, 测试和创建 JAR 文件. diff --git a/groovy_quickstart/summary.md b/groovy_quickstart/summary.md deleted file mode 100644 index e2e9875..0000000 --- a/groovy_quickstart/summary.md +++ /dev/null @@ -1,5 +0,0 @@ -# 总结 - -这一章描述了一个非常简单的 Groovy 项目. 通常, 一个真正的项目要比这个复杂的多. 因为 Groovy 项目是一个 Java 项目, 任何你可以对 Java 项目做的配置也可以对 Groovy 项目做. - -[Chapter 24,The Groovy Plugin](https://docs.gradle.org/current/userguide/groovy_plugin.html)有更加详细的描述, 你也可以在 samples/groovy 目录里找到更多的例子. diff --git a/java_quickstart/README.md b/java_quickstart/README.md deleted file mode 100644 index 08cfe03..0000000 --- a/java_quickstart/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Java 构建入门 - -* Java 插件 -* 一个基础的 Java 项目 -* 多项目的 Java 构建 - - - - - diff --git a/java_quickstart/a_basic_java_project.md b/java_quickstart/a_basic_java_project.md deleted file mode 100644 index 2851928..0000000 --- a/java_quickstart/a_basic_java_project.md +++ /dev/null @@ -1,24 +0,0 @@ -# 一个基础的 Java 项目 {#revision1} - -让我们先来看一个简单的例子. - -我们可以加入下面的代码来使用 Java 插件: - -**例子 7.1. 使用 Java 插件** - -_build.gradle_ - -``` -apply plugin: 'java' -``` - -(注:此例子的代码可以再所有“-all”结尾的发行版的samples/java/quickstart目录下找到) - -它将会把 Java 插件加入到你的项目中, 这意味着许多预定制的任务会被自动加入到你的项目里. - -Gradle 默认在 **src/main/java** 目录下寻找到你的正式(生产)源码, 在 **src/test/java** 目录下寻找到你的测试源码, 并在**src/main/resources**目录下寻找到你准备打包进jar的资源文件。测试代码会被加入到环境变量中设置的目录里运行。所有的输出文件都会被创建在构建目录里, 生成的JAR文件会被存放在 **build/libs** 目录下. - -**都加了什么可以执行的任务呢?** - -请在项目目录下使用 **gradle tasks** 来列出该项目的所有任务。 - diff --git a/java_quickstart/building_the_project.md b/java_quickstart/building_the_project.md deleted file mode 100644 index 6d82171..0000000 --- a/java_quickstart/building_the_project.md +++ /dev/null @@ -1,42 +0,0 @@ -# 建立项目 - -尽管Java 插件在你的项目里加入了许多任务,只有几个会在项目构建中经常用到。 - -最常用的任务是 **build** 任务, 用于完全构建你的项目.运行 **gradle build** 命令执行后,Gradle 将会编译和测试你的代码,并生成一个包含所有类与资源的 JAR 文件: - -**例子 7.2. 建立一个 Java 项目** - -**gradle build** 命令的输出: - - > gradle build - :compileJava - :processResources - :classes - :jar - :assemble - :compileTestJava - :processTestResources - :testClasses - :test - :check - :build - - BUILD SUCCESSFUL - - Total time: 1 secs - -其余一些有用的任务是: - -**clean** - -删除 **build** 目录和所有为build生成的文件. - -**assemble** - -编译并打包你的代码, 但是并不运行单元测试.其他插件会在这个任务里加入更多的步骤.举个例子,如果你使用 War 插件,这个任务还将根据你的项目生成一个 WAR 文件. - -**check** - -编译并测试你的代码. 其他的插件会加入更多的检查步骤.举个例子, 如果你使用 checkstyle 插件, 这个任务将会运行 Checkstyle 来检查你的代码. - - diff --git a/java_quickstart/common_configuration.md b/java_quickstart/common_configuration.md deleted file mode 100644 index 502e806..0000000 --- a/java_quickstart/common_configuration.md +++ /dev/null @@ -1,30 +0,0 @@ -# 通用配置 - -对于绝大多数多项目构建, 有一些配置对所有项目都是常见的或者说是通用的. 在我们的例子里, 我们将在根项目里定义一个这样的通用配置, 使用一种叫做配置注入的技术 (configuration injection). 这里, 根项目就像一个容器, subprojects 方法遍历这个容器的所有元素并且注入指定的配置 . 通过这种方法, 我们可以很容易的定义所有档案和通用依赖的内容清单: - -*Example 7.12. 多项目构建 - 通用配置* - -build.gradle - - subprojects { - apply plugin: 'java' - apply plugin: 'eclipse-wtp' - - repositories { - mavenCentral() - } - - dependencies { - testCompile 'junit:junit:4.11' - } - - version = '1.0' - - jar { - manifest.attributes provider: 'gradle' - } - } - -注意我们例子中, Java 插件被应用到了每一个子项目中plugin to each. 这意味着我们前几章看到的任务和属性都可以在子项目里被调用. 所以, 你可以通过在根目录里运行 **gradle build** 命令编译, 测试, 和 JAR 所有的项目. - - diff --git a/java_quickstart/creating_a_distribution.md b/java_quickstart/creating_a_distribution.md deleted file mode 100644 index 20e03a5..0000000 --- a/java_quickstart/creating_a_distribution.md +++ /dev/null @@ -1,20 +0,0 @@ -# 创建一个发行版本 - -(该章需加入更多内容。。。原稿写的太简单了)我们同时也加入了一个发行版本, 将会送到客户端: - -*Example 7.14. 多项目构建 - 发行文件* - -*api/build.gradle* - - task dist(type: Zip) { - dependsOn spiJar - from 'src/dist' - into('libs') { - from spiJar.archivePath - from configurations.runtime - } - } - - artifacts { - archives dist - } diff --git a/java_quickstart/creating_an_eclipse_project.md b/java_quickstart/creating_an_eclipse_project.md deleted file mode 100644 index 8366e96..0000000 --- a/java_quickstart/creating_an_eclipse_project.md +++ /dev/null @@ -1,13 +0,0 @@ -# 创建 Eclipse 项目 - -为了把你的项目导入到 Eclipse, 你需要加入另外一个插件: - -*Example 7.8. Eclipse 插件* - -*build.gradle* - - apply plugin: 'eclipse' - -现在运行 **gradle eclipse** 命令来生成 Eclipse 的项目文件. Eclipse 任务将在第 38 章, Eclipse 插件里详细讨论. - - diff --git a/java_quickstart/customizing_the_project.md b/java_quickstart/customizing_the_project.md deleted file mode 100644 index 82da725..0000000 --- a/java_quickstart/customizing_the_project.md +++ /dev/null @@ -1,31 +0,0 @@ -# 定制项目 - -Java 插件给项目加入了一些属性 (propertiy).这些属性已经被赋予了默认的值,已经足够来开始构建项目了.如果你认为不合适,改变它们的值也是很简单的.让我们看下这个例子.这里我们将指定 Java 项目的版本号,以及我们所使用的 Java 的版本.我们同样也加入了一些属性在 **jar** 的**manifest**里. - -**例子 7.5. 定制 MANIFEST.MF 文件** - -*build.gradle* - - sourceCompatibility = 1.5 - version = '1.0' - jar { - manifest { - attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version - } - } - -Java 插件加入的任务是常规性的任务,准确地说,就如同它们在构建文件里声明地一样. 这意味着你可以使用任务之前的章节提到的方法来定制这些任务.举个例子,你可以设置一个任务的属性,在任务里加入行为,改变任务的依赖, -或者完全重写一个任务,我们将配置一个测试任务,当测试执行的时候它会加入一个系统属性: - -**例子 7.6. 测试阶段加入一个系统属性** - -*build.gradle* - - test { - systemProperties 'property': 'value' - } - -**哪些属性是可用的?** - -你可以使用 **gradle properties** 命令来列出项目的所有属性. -这样你就可以看到 Java 插件加入的属性以及它们的默认值. diff --git a/java_quickstart/defining_a_multi-project_build.md b/java_quickstart/defining_a_multi-project_build.md deleted file mode 100644 index 5775c64..0000000 --- a/java_quickstart/defining_a_multi-project_build.md +++ /dev/null @@ -1,13 +0,0 @@ -# 定义一个多项目构建 - -为了定义一个多项目构建, 你需要创建一个设置文件 ( settings file). 设置文件放在源代码的根目录, 它指定要包含哪个项目. 它的名字必须叫做 **settings.gradle**. 在这个例子中, 我们使用一个简单的分层布局. 下面是对应的设置文件: - -*Example 7.11. 多项目构建 - settings.gradle file* - -*settings.gradle* - - include "shared", "api", "services:webservice", "services:shared" - -在第56章. 多项目构建, 你可以找到更多关于设置文件的信息. - - diff --git a/java_quickstart/dependencies_between_projects.md b/java_quickstart/dependencies_between_projects.md deleted file mode 100644 index a9597bd..0000000 --- a/java_quickstart/dependencies_between_projects.md +++ /dev/null @@ -1,14 +0,0 @@ -# 项目之间的依赖 - -你可以在同一个构建里加入项目之间的依赖, 举个例子, 一个项目的 JAR 文件被用来编译另外一个项目. 在 api 构建文件里我们将加入一个由 shared 项目产生的 JAR 文件的依赖. 由于这个依赖, Gradle 将确保 shared 项目总是在 api 之前被构建. - -*Example 7.13. 多项目构建 - 项目之间的依赖* - -*api/build.gradle* - - dependencies { - compile project(':shared') - } - - - diff --git a/java_quickstart/external_dependencies.md b/java_quickstart/external_dependencies.md deleted file mode 100644 index 87c8ad3..0000000 --- a/java_quickstart/external_dependencies.md +++ /dev/null @@ -1,34 +0,0 @@ -# 外部的依赖 - -通常, -一个 Java 项目的依赖许多外部的 JAR 文件.为了在项目里引用这些 JAR 文件,你需要告诉 Gradle 去哪里找它们.在 Gradle 中,JAR 文件位于一个仓库中,这里的仓库类似于 MAVEN 的仓库,可以被用来提取依赖,或者放入依赖。 - -举个例子,我们将使用开放的 Maven 仓库: - -**例子 7.3. 加入 Maven 仓库** - -*build.gradle* - - repositories { - mavenCentral() - } - -接下来让我们加入一些依赖. -这里, -我们假设我们的项目在编译阶段有一些依赖: - -*例子 6.4. 加入依赖* - -*build.gradle* - - dependencies { - compile group: 'commons-collections', name: 'commons-collections', version: '3.2' - testCompile group: 'junit', name: 'junit', version: '4.+' - } - -可以看到 commons-collections 被加入到了编译阶段, -junit 也被加入到了测试编译阶段. - -你可以在第 8 章里看到更多这方面的内容. - - diff --git a/java_quickstart/multi-project_java_build.md b/java_quickstart/multi-project_java_build.md deleted file mode 100644 index c7b51b2..0000000 --- a/java_quickstart/multi-project_java_build.md +++ /dev/null @@ -1,19 +0,0 @@ -# 多项目的 Java 构建 - -现在让我们看一个典型的多项目构建. 下面是项目的布局: - -*Example 7.10. 多项目构建 - 分层布局* - -*构建布局* - - multiproject/ - api/ - services/webservice/ - shared/ - - -注意: 这个例子的代码可以在 samples/java/multiproject 里找到. - -现在我们能有三个项目. 项目的应用程序接口 (API) 产生一个 JAR 文件, 这个文件将提供给用户, 给用户提供基于 XML 的网络服务. 项目的网络服务是一个网络应用, 它返回 XML. shared 目录包含被 api 和 webservice 共享的代码. - - diff --git a/java_quickstart/publishing_the_jar_file.md b/java_quickstart/publishing_the_jar_file.md deleted file mode 100644 index 001e9ae..0000000 --- a/java_quickstart/publishing_the_jar_file.md +++ /dev/null @@ -1,19 +0,0 @@ -# 发布 JAR 文件 - -通常 JAR 文件需要在某个地方发布. 为了完成这一步, 你需要告诉 Gradle 哪里发布 JAR 文件. 在 Gradle 里, 生成的文件比如 JAR 文件将被发布到仓库里. 在我们的例子里, 我们将发布到一个本地的目录. 你也可以发布到一个或多个远程的地点. - -*Example 7.7. 发布 JAR 文件* - -*build.gradle* - - uploadArchives { - repositories { - flatDir { - dirs 'repos' - } - } - } - -运行 **gradle uploadArchives** 命令来发布 JAR 文件. - - diff --git a/java_quickstart/summary.md b/java_quickstart/summary.md deleted file mode 100644 index 8a5d585..0000000 --- a/java_quickstart/summary.md +++ /dev/null @@ -1,39 +0,0 @@ -# 总结 - -下面是一个完整的构建文件的样本: - -*Example 7.9. Java 例子 - 完整的构建文件* - -*build.gradle* - - apply plugin: 'java' - apply plugin: 'eclipse' - - sourceCompatibility = 1.5 - version = '1.0' - jar { - manifest { - attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version - } - } - - repositories { - mavenCentral() - } - - dependencies { - compile group: 'commons-collections', name: 'commons-collections', version: '3.2' - testCompile group: 'junit', name: 'junit', version: '4.+' - } - - test { - systemProperties 'property': 'value' - } - - uploadArchives { - repositories { - flatDir { - dirs 'repos' - } - } - } diff --git a/java_quickstart/the_java_plugin.md b/java_quickstart/the_java_plugin.md deleted file mode 100644 index d6c370f..0000000 --- a/java_quickstart/the_java_plugin.md +++ /dev/null @@ -1,45 +0,0 @@ -# Java 插件 - -如你所见, -Gradle 是一种多用途的构建工具. -它可以在你的构建脚本里构建任何你想要实现的东西. -但前提是你必须先在构建脚本里加入代码, -不然它什么都不会执行. - -大多数 Java 项目是非常相似的: -你需要编译你的 Java 源文件, -运行一些单元测试, -同时创建一个包含你类文件的 JAR. -如果你可以不需要为每一个项目重复执行这些步骤, -我想你会非常乐意的. - -幸运的是, 你现在不再需要做这些重复劳动了. -Gradle 通过使用插件解决了这个问题. -插件是 Gradle 的扩展, -它会通过某种方式配置你的项目, -典型的有加入一些预配置任务. -Gradle 自带了许多插件, -你也可以很简单地编写自己的插件并和其他开发者分享它. -Java 插件就是一个这样的插件. -这个插件在你的项目里加入了许多任务, -这些任务会编译和单元测试你的源文件, -并且把它们都集成一个 JAR 文件里. - -Java 插件是基于合约的. -这意味着插件已经给项目的许多方面定义了默认的参数, -比如 Java 源文件的位置. -如果你在项目里遵从这些合约, -你通常不需要在你的构建脚本里加入太多东西. -如果你不想要或者是你不能遵循合约, -Gradle 也允许你自己定制你的项目. -事实上, -因为对 Java 项目的支持是通过插件实现的, -如果你不想要的话, -你一点也不需要使用这个插件来构建你的项目. - -在后面的章节, -我们有许多机会来让你深入了解 Java 插件, 依赖管理和多项目构建. 在本章中,先来初步认识如何使用Java插件来构建一个Java项目. - - - - diff --git a/logging/changing_what_gradle_logs.md b/logging/changing_what_gradle_logs.md deleted file mode 100644 index fde7262..0000000 --- a/logging/changing_what_gradle_logs.md +++ /dev/null @@ -1,52 +0,0 @@ -# 改变Gradle的记录内容 - -你可以用自己的内容取代大部分摇篮的UI记录.你可以这样做,例如,如果你想以某种方式定制UI,如:记录更多或更少的信息,或更改log的格式.你可以使用[Gradle.useLogger()](https://docs.gradle.org/current/dsl/org.gradle.api.invocation.Gradle.html#org.gradle.api.invocation.Gradle:useLogger(java.lang.Object))方法替换日志.可从一个构建脚本或初始化脚本,或通过嵌入API替换.注意,这会完全禁用Gradle的默认输出.下面的初始化脚本改变任务执行和完成构建后日志的输出. - -**例 17.6.定制Gradle logs** - -**init.gradle** - -```gradle -useLogger(new CustomEventLogger()) - -class CustomEventLogger extends BuildAdapter implements TaskExecutionListener { - - public void beforeExecute(Task task) { - println "[$task.name]" - } - - public void afterExecute(Task task, TaskState state) { - println() - } - - public void buildFinished(BuildResult result) { - println 'build completed' - if (result.failure != null) { - result.failure.printStackTrace() - } - } -} -``` -`gradle -I init.gradle build`的输出 - -> \> gradle -I init.gradle build -> [compile] -> compiling source -> -> [testCompile] -> compiling test source -> -> [test] -> running unit tests -> -> [build] -> -> build completed - -你的`logger`可以实现下面列出的任何监听器接口.仅它实现接口被替换,其他接口保持不变。你可以在[Section 56.6, “Responding to the lifecycle in the build script”](https://docs.gradle.org/current/userguide/build_lifecycle.html#build_lifecycle_events)中找到更多相关信息. - -+ [BuildListener](https://docs.gradle.org/current/javadoc/org/gradle/BuildListener.html) -+ [ProjectEvaluationListener](https://docs.gradle.org/current/javadoc/org/gradle/api/ProjectEvaluationListener.html) -+ [TaskExecutionGraphListener](https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskExecutionGraphListener.html) -+ [TaskExecutionListener](https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskExecutionListener.html) -+ [TaskActionListener](https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskActionListener.html) diff --git a/logging/choosing_a_log_level.md b/logging/choosing_a_log_level.md deleted file mode 100644 index cade448..0000000 --- a/logging/choosing_a_log_level.md +++ /dev/null @@ -1,23 +0,0 @@ -# Choosing a log level - -你可以在命令行中选择如[表 17.2.Log 等级命令行选项]()所示的选项选择不同的日志级别.如[表 17.3.堆栈信息选项]()中所示的选项来选择堆栈信息. - -**表17.2.Log 等级命令行选项** - -| 选项 | 输出日志等级 | -| -- | -- | -| no logging options | LIFECYCLE及更高 | -| -q or --quiet | QUIET及更高 | -| -i or --info | INFO及更高 | -| -d or --debug | DEBUG及更高(所有日志信息) | - - -**表 17.3.堆栈信息选项** - -| 选项 | 含义 | -| -- | -- | -| No stacktrace options | 无堆栈踪迹输出到控制台的情况下生成错误信息(如编译错误) ,仅在内部异常时打印堆栈信息.如果选择DEBUG日志等级,总会打印截断堆栈信息| -| -s or --stacktrace | 打印截断堆栈信息,我们推荐这个而不是`full stacktrace` ,Groovy的`full stacktrace`非常详细.(由于底层的动态调用机制。然而,他们通常不包含你的代码出了什么错的相关信息) | -| -S or --full-stacktrace | 打印全部堆栈信息 | - - diff --git a/logging/logging.md b/logging/logging.md deleted file mode 100644 index 5da0085..0000000 --- a/logging/logging.md +++ /dev/null @@ -1,16 +0,0 @@ -# Logging - -Log 是构建的主要"UI"工具. 如果日志太过冗长, 那么真正的警告和问题会隐藏其中, 另一方面, 如果你出错了,你又需要搞清楚相关错误信息. Gradle 提供了6个等级的 log, 如[表17.1.Logs Level]()所示.出了那些你可能经常看到的, 还有两个是 Gradle 特定级别的日志,被称为*QUIET*和*LIFECYCLE*.后者是默认的, 并用于报告生成进度. - -**表17.1.Logs Level** - -| Level | 用途 | -| -- | -- | -| ERROR | 错误信息 | -| QUIET | 重要消息信息 | -| WARNING | 警告信息 | -| LIFECYCLE | 进度消息信息 | -| INFO | 信息消息 | -| DEBUG | 调试信息 | - - diff --git a/logging/logging_from_external_tools_and_libraries.md b/logging/logging_from_external_tools_and_libraries.md deleted file mode 100644 index 165518e..0000000 --- a/logging/logging_from_external_tools_and_libraries.md +++ /dev/null @@ -1,38 +0,0 @@ -# 从外部工具和库记录日志 - -在内部, Gradle 使用 Ant 和 lvy , -都有自己的 log 系统, -Gradle 重定向他们的日志输出到 Gradle 日志系统. -除了Ant/lvy的`TRACE`级别的日志, 映射到Gradle的`DEBUG`级别, 其余的都会有一个1:1的映射从 Ant/lvy 的日志等级到 Gradle 的日志等级. -这意味着默认的 Gradle 日志级别将不会显示任何的 Ant /lvy 的输出, 除非它是一个错误或警告. - -有许多工具仍然使用标准输出记录,默认的,Gradle将标准输出重定向到`QUIET`的日志级别和标准错误的`ERROR`级别.该行为是可配置的.该项目对象提供了一个[LoggerManager](https://docs.gradle.org/current/javadoc/org/gradle/api/logging/LoggingManager.html),当你构建脚本进行评估的时候,允许你改变标准输出或错误重定向的日志级别。 - -**例 17.4.配置标准输出捕获** - -**build.gradle** - -```gradle -logging.captureStandardOutput LogLevel.INFO -println 'A message which is logged at INFO level' -``` - -任务同样提供了[LoggingManager](https://docs.gradle.org/current/javadoc/org/gradle/api/logging/LoggingManager.html)去更改任务执行过程中的标准输出或错误日志级别。 - -**例 17.5.为任务配置标准输出捕获** - -**build.gradle** - -```gradle -task logInfo { - logging.captureStandardOutput LogLevel.INFO - doFirst { - println 'A task message which is logged at INFO level' - } -} -``` - -Gradle同样提供了`Java Util Logging`,`Jakarta Commons Logging`和` Log4j logging`的集成工具. - -使用这些工具包编写的构建的类的记录的任何日志消息都将被重定向到Gradle的日志记录系统。 - diff --git a/logging/writing_your_own_log_messages.md b/logging/writing_your_own_log_messages.md deleted file mode 100644 index 770e49b..0000000 --- a/logging/writing_your_own_log_messages.md +++ /dev/null @@ -1,41 +0,0 @@ -# 编写自己的日志信息 - -用于记录在你的构建文件的简单方法是将消息写入标准输出.Gradle重定向任何东西写入到标准输出到它的log系统作为`QUITE`级别的log. - -**例 17.1.使用标准输出写入log信息** - -**build.gradle** - -```gradle -println 'A message which is logged at QUIET level' -``` - -摇篮还提供了一个`logger`属性来构建脚本,这是[Logger](https://docs.gradle.org/current/javadoc/org/gradle/api/logging/Logger.html)的一个实例.这个接口继承自`SLF4J`接口并且加入了一F些Gradle的具体方法.下面是如何在构建脚本中使用此方法的例子: - -**例 17.2.写入自己的log信息** - -**build.gradle** - -```gradle -logger.quiet('An info log message which is always logged.') -logger.error('An error log message.') -logger.warn('A warning log message.') -logger.lifecycle('A lifecycle info log message.') -logger.info('An info log message.') -logger.debug('A debug log message.') -logger.trace('A trace log message.') -``` - -你还可以在构建中将其他类直接挂接到Gradle的log系统中(例如`buildSrc`目录下的类).只使用`SLF4J logger`,使用这个`logger`的方式与构建脚本提供的`logger`方式相同. - -**例 17.3.使用SLF4J写入log信息** - -**build.gradle** - -```gradle -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -Logger slf4jLogger = LoggerFactory.getLogger('some-logger') -slf4jLogger.info('An info log message logged using SLF4j') -``` diff --git a/more_about_tasks/README.md b/more_about_tasks/README.md deleted file mode 100644 index 5fb09f9..0000000 --- a/more_about_tasks/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# 深入了解 Tasks - -在这本教程的一开始 (第 6 章, 构建脚本基础) 你已经学习了如何创建简单的任务. 然后你也学习了如何给这些任务加入额外的行为, 以及如何在任务之间建立依赖关系. -这些仅仅是用来构建简单的任务. -Gradle 可以创建更为强大复杂的任务. 这些任务可以有它们自己的属性和方法. -这一点正是和 Ant targets 不一样的地方. 这些强大的任务既可以由你自己创建也可以使用 Gradle 内建好的. - diff --git a/more_about_tasks/adding_a_description_to_a_task.md b/more_about_tasks/adding_a_description_to_a_task.md deleted file mode 100644 index 2d81480..0000000 --- a/more_about_tasks/adding_a_description_to_a_task.md +++ /dev/null @@ -1,16 +0,0 @@ -# 给 task 加入描述 - -你可以给你的任务加入一段描述性的文字. 它将会在任务执行的时候显示出来. - -**例子 15.18. 给任务加入描述** - -**build.gradle** - -``` -task copy(type: Copy) { - description 'Copies the resource directory to the target directory.' - from 'resources' - into 'target' - include('**/*.txt', '**/*.xml', '**/*.properties') -} -``` diff --git a/more_about_tasks/adding_dependencies_to_a_task.md b/more_about_tasks/adding_dependencies_to_a_task.md deleted file mode 100644 index 91345ad..0000000 --- a/more_about_tasks/adding_dependencies_to_a_task.md +++ /dev/null @@ -1,95 +0,0 @@ -# 给 task 加入依赖 - -有许多种加入依赖的方式. 在 6.5 小节, “任务依赖”里, 你已经学习了如何使用任务的名称定义依赖. 任务名称可以指向同一个项目里的任务, 或者其他项目里的任务. 为了指向其他项目, 你必须在任务的名称前加入项目的路径. 下面的例子给 projectA:taskX 加入依赖 projectB:taskY : - -**例子 15.11. 从另外一个项目给任务加入依赖** - -**build.gradle** - -``` -project('projectA') { - task taskX(dependsOn: ':projectB:taskY') << { - println 'taskX' - } -} - -project('projectB') { - task taskY << { - println 'taskY' - } -} -``` - -**gradle -q taskX** 的输出 - -``` -> gradle -q taskX -taskY -taskX -``` - -除了使用任务名称, 你也可以定义一个依赖对象y: - -**例子 15.12. 通过任务对象加入依赖** - -**build.gradle** - -``` -task taskX << { - println 'taskX' -} - -task taskY << { - println 'taskY' -} - -taskX.dependsOn taskY -``` - -**gradle -q taskX** 的输出 - -``` -> gradle -q taskX -taskY -taskX -``` - -更加先进的用法, 你可以通过闭包定义一个任务依赖. 闭包只能返回一个单独的 Task 或者 Task 对象的 collection, 这些返回的任务就将被当做依赖. 接下来的例子给 taskX 加入了一个复杂的依赖, 所有以 lib 开头的任务都将在 taskX 之前执行: - -**例子 15.13. 通过闭包加入依赖** - -**build.gradle** -``` - -task taskX << { - println 'taskX' -} - -taskX.dependsOn { - tasks.findAll { task -> task.name.startsWith('lib') } -} - -task lib1 << { - println 'lib1' -} - -task lib2 << { - println 'lib2' -} - -task notALib << { - println 'notALib' -} -``` - -**gradle -q taskX** 的输出 - -``` -> gradle -q taskX -lib1 -lib2 -taskX -``` - - -For more information about task dependencies, see the Task API. diff --git a/more_about_tasks/cache.md b/more_about_tasks/cache.md deleted file mode 100644 index 4c99f6c..0000000 --- a/more_about_tasks/cache.md +++ /dev/null @@ -1,4 +0,0 @@ -# 缓存 - -为了提高响应能力,Gradle 默认缓存了所有编译后的脚本. 包括所有的构建脚本,初始化脚本,还有其他脚本. Gradle 创建了一个 .gradle 目录来存放编译后的脚本,下次您运行构建脚本时,如果这个脚本自从它被编译后就再也没有被改动过,Gradle 会先使用编译后的脚本. 否则 Gradle 会重新编译脚本,然后将新编译后的文件缓存起来. 如果您使用 Gradle --recompile--scripts 运行脚本,缓存的脚本就会被删除,然后新编译后的文件就会再被缓存. 这种方法可以强制 Gradle 重新编译脚本并缓存. - diff --git a/more_about_tasks/config_any_object.md b/more_about_tasks/config_any_object.md deleted file mode 100644 index 498efe6..0000000 --- a/more_about_tasks/config_any_object.md +++ /dev/null @@ -1,23 +0,0 @@ -# 配置任意对象 -您可以使用下面方法配置任意的对象. - -**例子 14.4.配置任意对象** - -**build.gradle** - - task configure << { - def pos = configure(new java.text.FieldPosition(10)) { - beginIndex = 1 - endIndex = 5 - } - - println pos.beginIndex - println pos.endIndex - - } - -**使用 gradle -q configure 输出** - - > gradle -q configure - 1 - 5 diff --git a/more_about_tasks/configuring_tasks.md b/more_about_tasks/configuring_tasks.md deleted file mode 100644 index b2bf1ea..0000000 --- a/more_about_tasks/configuring_tasks.md +++ /dev/null @@ -1,65 +0,0 @@ -# 配置 tasks - -举一个例子, 让我们看一看 Gradle 自带的 Copy task. 为了创建一个 Copy task, 你需要在你的构建脚本里先声明它: - -**例子 15.7. 创建一个 copy task** - -**build.gradle** - -``` -task myCopy(type: Copy) -``` - -它创建了一个没有默认行为的 copy task. 这个 task 可以通过它的 API 来配置(参考 [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html)). 接下来例子展示了不同的实现方法. - -补充说明一下, 这个 task 的名字是 “myCopy”, 但是它是 “Copy” 类(type). 你可以有许多同样 type 不同名字的 tasks. 这个在实现特定类型的所有任务的 cross-cutting concerns 时特别有用. - -**例子 15.8. 配置一个任务 - 不同的方法** - -**build.gradle** - -``` -Copy myCopy = task(myCopy, type: Copy) -myCopy.from 'resources' -myCopy.into 'target' -myCopy.include('**/*.txt', '**/*.xml', '**/*.properties') -``` - -这个我们通过 Java 配置对象是一样的形式. 但是你每次都必须在语句里重复上下文 (myCopy). 这种方式可能读起来并不是那么的漂亮. - -下面一种方式就解决了这个问题. 是公认的最具可读性的方式. - -**例子 15.9. 配置一个任务 - 通过闭包 closure** - -**build.gradle** - -``` -task myCopy(type: Copy) - -myCopy { - from 'resources' - into 'target' - include('**/*.txt', '**/*.xml', '**/*.properties') -} -``` - -上面例子里的第三行是 tasks.getByName() 方法的一个简洁的写法. 特别要注意的是, 如果你通过闭包的形式来实现 getByName() 方法, 这个闭包会在 task 配置的时候执行而不是在 task 运行的时候执行. - -你也可以直接在定义 task 时使用闭包. - -**例子 15.10. 通过定义一个任务** - -``` -build.gradle - -task copy(type: Copy) { - from 'resources' - into 'target' - include('**/*.txt', '**/*.xml', '**/*.properties') -} -``` - -请不要忘了构建的各个阶段. - -一个任务有配置和动作. 当使用 << 时, 你只是简单的使用捷径定义了动作. 定义在配置区域的代码只会在构建的配置阶段执行, 而且不论执行哪个任务. 可以参考第 55 章, The Build Lifecycle for more details about the build lifecycle. - diff --git a/more_about_tasks/defining_tasks.md b/more_about_tasks/defining_tasks.md deleted file mode 100644 index c684386..0000000 --- a/more_about_tasks/defining_tasks.md +++ /dev/null @@ -1,53 +0,0 @@ -# 定义 tasks - -我们已经在第 6 章学习了定义任务的形式 (keyword 形式). 当然也会有一些定义形式的变化来适应某些特殊的情况. 比如下面的例子中任务名被括号括起来了. 这是因为之前定义简单任务的形式 (keyword 形式) 在表达式里是不起作用的. - -**例子 15.1. 定义 tasks** - -**build.gradle** -``` -task(hello) << { - println "hello" -} - -task(copy, type: Copy) { - from(file('srcDir')) - into(buildDir) -} -``` -你也可以使用 strings 来定义任务的名字: - -**例子 15.2. 例子 tasks - 使用 strings 来定义任务的名字** - -**build.gradle** -``` -task('hello') << -{ - println "hello" -} - -task('copy', type: Copy) { - from(file('srcDir')) - into(buildDir) -} -``` - -还有另外一种语法形式来定义任务, 更加直观: - -**例子 15.3. 另外一种语法形式** - -**build.gradle** - -``` -tasks.create(name: 'hello') << { - println "hello" -} - -tasks.create(name: 'copy', type: Copy) { - from(file('srcDir')) - into(buildDir) -} -``` - -这里实际上我们把任务加入到 tasks collection 中. 可以看一看 [TaskContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskContainer.html) 来深入了解下. - diff --git a/more_about_tasks/extra.md b/more_about_tasks/extra.md deleted file mode 100644 index d7b1d77..0000000 --- a/more_about_tasks/extra.md +++ /dev/null @@ -1,3 +0,0 @@ -# 补充 -#### 下面补充的部分原本是第 14 章,最新的 Gradle 文档将其移除,所以将其作为补充放到这一章节。 - diff --git a/more_about_tasks/finalizer_tasks.md b/more_about_tasks/finalizer_tasks.md deleted file mode 100644 index 9c4bf24..0000000 --- a/more_about_tasks/finalizer_tasks.md +++ /dev/null @@ -1,57 +0,0 @@ -# 终止 tasks - ->终止任务是一个正在开发的功能. - -这里的终止任务并不是指终止一个任务, 而是指一个无论运行结果如何最后都会被执行的任务. - -**例子 15.27. 加入一个任务终止器** - -**build.gradle** - -``` -task taskX << { - println 'taskX' -} -task taskY << { - println 'taskY' -} - -taskX.finalizedBy taskY -``` - -**gradle -q taskX** 的输出 - -``` -> gradle -q taskX -taskX -taskY -``` - -即使要终止的任务失败了, 终止任务仍会继续执行. - -**例子 14.28. 当任务失败时k** - -**build.gradle** -``` -task taskX << { - println 'taskX' - throw new RuntimeException() -} -task taskY << { - println 'taskY' -} - -taskX.finalizedBy taskY -``` -**gradle -q taskX** 的输出 -``` -> gradle -q taskX -taskX -taskY -``` - -另外, 如果要终止的任务并没有被执行 (比如上一节讲的 up-to-date) 那么终止任务并不会执行. - -当构建创建了一个资源, 无论构建失败或成功时这个资源必须被清除的时候, 终止任务就非常有用. - -要使用终止任务, 你必须使用 [Task.finalizedBy()](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html#org.gradle.api.Task:finalizedBy(java.lang.Object[])) 方法. 一个任务的实例, 任务的名称, 或者任何 Task.dependsOn() 可以接收的输入都可以作为这个任务的输入. diff --git a/more_about_tasks/gradle_properties_and_system_properties.md b/more_about_tasks/gradle_properties_and_system_properties.md deleted file mode 100644 index 1e32afd..0000000 --- a/more_about_tasks/gradle_properties_and_system_properties.md +++ /dev/null @@ -1,44 +0,0 @@ -# Gradle 属性 和 system 属性 -Gradle 提供了多种的方法让您可以在构建脚本中添加属性. 使用 -D 命令选项,您可以向运行 Gradle 的 JVM 传递一个 system 属性 . **Gradle** 命令的 -D 选项 和 **Java** 命令的 -D 选项有些相同的效果. - -您也可以使用属性文件向您的 Project 对象中添加属性. 您可以在 Gradle 用户目录( 如果您没有在 *USER_HOME*/.gradle 配置默认设置,则由"GRADLE_USER_HOME" 环境变量定义) 或者项目目录放置一个 gradle.properties 文件.如果是多项目的话,您可以在每个子目录里都放置一个 gradle.properties 文件. gradle.properties 文件内容里的属性能够被 Project 对象访问到. 不过有一点,用户目录中的 gradle.properties 文件优先权大于项目目录中的 gradle.properties 文件. - -您也可以通过 -P 命令选项直接向Project 对象中添加属性. - -另外,当 Gradle 看到特别命名的 system 属性或者环境变量时,Gradle 也可以设置项目属性. 比如当您没有管理员权限去持续整合服务,还有您需要设置属性值但是不容易时,这个特性非常有用. 出于安全的原因,在这种情况下,您没法使用 -P 命令选项,您也不能修改系统级别的文件. 确切的策略是改变您持续继承构建工作的配置,增加一个环境变量设置令它匹配一个期望的模式. 对于当前系统来说,这种方法对于普通用户来说是不可见的. [\[6]](#md-anchor) - -如果环境变量的名字是 ORG_GRADLE_PROJECT=somevalue, Gradle 会使用值为 somevalue 在您的 Project 对象中设定一个支持属性. 另外 Gradle 也支持 system 属性,但是使用不同的名字模式,例如 org.gradle.project.prop . - -您也可以在 gradle.properties 文件中设置 system 属性.如果一个属性名的前缀为 “systemProp”,那么这个属性和它的属性值会被设置为 system 属性. 如果没有这个前缀,在多项目构建中,除了根项目会被忽略外,“systemProp.” 属性会在任何项目中设置.也就是说仅仅根项目的 gradle.properties 文件会被检查其属性的前缀是否是 “systemProp”. - -**例子 14.2.通过 gradle.properties 文件设置属性 - -**gradle.properties** - - gradlePropertiesProp=gradlePropertiesValue - sysProp=shouldBeOverWrittenBySysProp - envProjectProp=shouldBeOverWrittenByEnvProp - systemProp.system=systemValue - -**build.gradle** - - task printProps << { - println commandLineProjectProp - println gradlePropertiesProp - println systemProjectProp - println envProjectProp - println System.properties['system'] - - } - -[6]. *Jenkins*, *Teamcity*, or *Bamboo* 都是 提供这个功能的 CI 服务. - -**使用 gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps 输出** - - > gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps - commandLineProjectPropValue - gradlePropertiesValue - systemPropertyValue - envPropertyValue - systemValue - diff --git a/more_about_tasks/locating_tasks.md b/more_about_tasks/locating_tasks.md deleted file mode 100644 index 757c537..0000000 --- a/more_about_tasks/locating_tasks.md +++ /dev/null @@ -1,65 +0,0 @@ -# 定位 tasks - -你经常需要在构建文件里找到你定义的 tasks, -举个例子, -为了配置它们或者使用它们作为依赖. 有许多种方式都可以来实现定位. -首先, -每一个任务都必须是一个 project 的有效属性, -并使用任务名来作为属性名: - -**例子 15.4. 通过属性获取 tasks** - -**build.gradle** -``` -task hello - -println hello.name -println project.hello.name -``` - -Tasks 也可以通过 tasks collection 来得到. - -**例子 15.5. 通过 tasks collection 获取 tasks** - -**build.gradle** - -``` -task hello - -println tasks.hello.name -println tasks['hello'].name -``` - -你也可以使用 tasks.getByPath() 方法通过任务的路径来使用任何 project 里的任务. -你可以通过使用任务的名字, 任务的相对路径或者绝对路径作为 getByPath() 方法的输入. - -**例子 15.6. 通过路径获取 tasks** - -**build.gradle** - -``` -project(':projectA') { - task hello -} - -task hello - -println tasks.getByPath('hello').path -println tasks.getByPath(':hello').path -println tasks.getByPath('projectA:hello').path -println tasks.getByPath(':projectA:hello').path -``` - -**gradle -q hello** 的输出 - -``` -> gradle -q hello -:hello -:hello -:projectA:hello -:projectA:hello -``` -参考 -[TaskContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskContainer.html) 可以知道跟多关于定位 tasks 的选项. - - diff --git a/more_about_tasks/ordering_tasks.md b/more_about_tasks/ordering_tasks.md deleted file mode 100644 index 53032b3..0000000 --- a/more_about_tasks/ordering_tasks.md +++ /dev/null @@ -1,121 +0,0 @@ -# 给 tasks 排序 - ->任务的排序功能正在测试和优化. 请注意, 这项功能在 Gradle 之后的版本里可能会改变. - -在某些情况下, 我们希望能控制任务的的执行顺序, 这种控制并不是向上一张那样去显示地加入依赖关系. 最主要的区别是我们设定的排序规则不会影响那些要被执行的任务, 只是影响执行的顺序本身. 好吧, 我知道可能有点抽象. - -我们来看看以下几种有用的场景: - -* 执行连续的任务: eg. 'build' 从来不会在 'clean' 之前执行. -* 在 build 的一开始先运行构建确认 (build validations): eg. 在正式的发布构建前先确认我的证书是正确的. -* 在运行长时间的检测任务前先运行快速的检测任务来获得更快的反馈: eg. 单元测试总是应该在集成测试之前被执行. -* 一个聚集 (aggregates) 某种特定类型的所有任务结果的任务: eg. 测试报告任务 (test report task) 包含了所有测试任务的运行结果. - -目前, 有 2 种可用的排序规则: **"must run after"** 和 **"should run after"**. - -当你使用 “must run after” 时即意味着 taskB 必须总是在 taskA 之后运行, 无论 taskA 和 taskB 是否将要运行: - -``` -taskB.mustRunAfter(taskA) -``` - -"should run after" 规则其实和 "must run after" 很像, 只是没有那么的严格, 在 2 种情况下它会被忽略: - -1. 使用规则来阐述一个执行的循环. -2. 当并行执行并且一个任务的所有依赖除了 “should run after” 任务其余都满足了, 那么这个任务无论它的 “should run after” 依赖是否执行, 它都可以执行. (编者: 翻译待商榷, 提供具体例子) - -总之, 当要求不是那么严格时, “should run after” 是非常有用的. - -即使有目前的这些规则, 我们仍可以执行 taskA 而不管 taskB, 反之亦然. - -**例子 15.14. 加入 'must run after' ** - -**build.gradle** -``` -task taskX << { - println 'taskX' -} -task taskY << { - println 'taskY' -} -taskY.mustRunAfter taskX -``` - -**gradle -q taskY taskX** 的输出 - -``` -> gradle -q taskY taskX -taskX -taskY -``` - -**例子 15.15. 加入 'should run after'** - -**build.gradle** - -``` -task taskX << { - println 'taskX' -} -task taskY << { - println 'taskY' -} -taskY.shouldRunAfter taskX -``` - -**gradle -q taskY taskX** 的输出 - -``` -> gradle -q taskY taskX -taskX -taskY -``` - -在上面的例子里, 我们仍可以直接执行 taskY 而不去 taskX : - -**例子 15.16. 任务排序不影响任务执行** - -**gradle -q taskY** 的输出 - -``` -> gradle -q taskY -taskY -``` - -为了在 2 个任务间定义 “must run after” 或者 “should run after” 排序, 我们需要使用 Task.mustRunAfter() 和 Task.shouldRunAfter() 方法. 这些方法接收一个任务的实例, 任务的名字或者任何 Task.dependsOn()可以接收的输入. - -注意 “B.mustRunAfter(A)” 或者 “B.shouldRunAfter(A)” 并不影响任何任务间的执行依赖: - -* tasks A 和 B 可以被独立的执行. 排序规则只有当 2 个任务同时执行时才会被应用. -* 在运行时加上 --continue, 当 A 失败时 B 仍然会执行. - -之前提到过, “should run after” 规则在一个执行循环中将被忽略: - -**例子 15.17. 'should run after' 任务的忽略** - -**build.gradle** - -``` -task taskX << { - println 'taskX' -} -task taskY << { - println 'taskY' -} -task taskZ << { - println 'taskZ' -} -taskX.dependsOn taskY -taskY.dependsOn taskZ -taskZ.shouldRunAfter taskX -``` - -**gradle -q taskX** 的输出 - -``` -> gradle -q taskX -taskZ -taskY -taskX -``` - diff --git a/more_about_tasks/replacing_tasks.md b/more_about_tasks/replacing_tasks.md deleted file mode 100644 index 88c02f3..0000000 --- a/more_about_tasks/replacing_tasks.md +++ /dev/null @@ -1,26 +0,0 @@ -# 替换 tasks - -有时候你想要替换一个任务. 举个例子, 如果你想要互换一个通过 java 插件定义的任务和一个自定义的不同类型的任务: - -例子 14.19. 覆写一个任务 - -**build.gradle** - -``` -task copy(type: Copy) - -task copy(overwrite: true) << { - println('I am the new one.') -} -``` - -**gradle -q copy** 的输出 - -``` -> gradle -q copy -I am the new one. -``` - -这种方式将用你自己定义的任务替换一个 Copy 类型的任务, 因为它使用了同样的名字. -但你定义一个新的任务时, 你必须设置 overwrite 属性为 true. 否则的话 Gradle 会抛出一个异常, task with that name already exists. - diff --git a/more_about_tasks/skipping_tasks.md b/more_about_tasks/skipping_tasks.md deleted file mode 100644 index 1f23773..0000000 --- a/more_about_tasks/skipping_tasks.md +++ /dev/null @@ -1,88 +0,0 @@ -# 跳过 tasks - -Gradle 提供了好几种跳过一个任务的方式. - -### 1. 使用判断条件 (predicate) - -你可以使用 onlyIf() 方法来为一个任务加入判断条件. 就和 Java 里的 if 语句一样, 任务只有在条件判断为真时才会执行. 你通过一个闭包来实现判断条件. 闭包像变量一样传递任务, 如果任务应该被执行则返回真, 反之亦然. 判断条件在任务执行之前进行判断. - -**例子 15.20. 使用判断条件跳过一个任务** - -**build.gradle** - -``` -task hello << { - println 'hello world' -} - -hello.onlyIf { !project.hasProperty('skipHello') } -``` - -**gradle hello -PskipHello** 的输出 - -``` -> gradle hello -PskipHello -:hello SKIPPED -BUILD SUCCESSFUL - -Total time: 1 secs -``` - -### 2. 使用 StopExecutionException - -如果想要跳过一个任务的逻辑并不能被判断条件通过表达式表达出来, 你可以使用 StopExecutionException. 如果这个异常是被一个任务要执行的动作抛出的, 这个动作之后的执行以及所有紧跟它的动作都会被跳过. 构建将会继续执行下一个任务. - -**例子 15.21. 通过 StopExecutionException 跳过任务** - -**build.gradle** - -``` -task compile << { - println 'We are doing the compile.' -} - -compile.doFirst { - // Here you would put arbitrary conditions in real life. - // But this is used in an integration test so we want defined behavior. - if (true) { throw new StopExecutionException() } -} -task myTask(dependsOn: 'compile') << { - println 'I am not affected' -} -``` - -**gradle -q myTask** 的输出 - -``` -> gradle -q myTask -I am not affected -``` - -如果你直接使用 Gradle 提供的任务, 这项功能还是十分有用的. 它允许你为内建的任务加入条件来控制执行. [6] - -### 3. 激活和注销 tasks - -每一个任务都有一个已经激活的标记(enabled flag), 这个标记一般默认为真. 将它设置为假, 那它的任何动作都不会被执行. - -**例子 15.22. 激活和注销 tasks** - -**build.gradle** - -``` -task disableMe << { - println 'This should not be printed if the task is disabled.' -} -disableMe.enabled = false -``` - -**gradle disableMe** 的输出 - -``` -> gradle disableMe -:disableMe SKIPPED - -BUILD SUCCESSFUL - -Total time: 1 secs -``` - diff --git a/more_about_tasks/skipping_tasks_that_are_up-to-date.md b/more_about_tasks/skipping_tasks_that_are_up-to-date.md deleted file mode 100644 index 9c00578..0000000 --- a/more_about_tasks/skipping_tasks_that_are_up-to-date.md +++ /dev/null @@ -1,103 +0,0 @@ -# 跳过 up-to-date 的任务 - -如果你正在使用一些附加的任务, 比如通过 Java 插件加入的任务, 你可能会注意到 Gradle 会跳过一些任务, 这些任务后面会标注 **up-to-date**. 代表这个任务已经运行过了或者说是最新的状态, 不再需要产生一次相同的输出. 不仅仅是这些内建任务, 其实你在运行自己的任务时, 也会碰到这种情况. - -### 1. 声明一个任务的输入和输出 - -让我们先看一个例子. 这里我们的任务会根据一个 XML 文件生成好几个输出文件. 让我们运行这个任务 2 次. - -**例子 15.23. A generator task** - -**build.gradle** - -``` -task transform { - ext.srcFile = file('mountains.xml') - ext.destDir = new File(buildDir, 'generated') - doLast { - println "Transforming source file." - destDir.mkdirs() - def mountains = new XmlParser().parse(srcFile) - mountains.mountain.each { mountain -> - def name = mountain.name[0].text() - def height = mountain.height[0].text() - def destFile = new File(destDir, "${name}.txt") - destFile.text = "$name -> ${height}\n" - } - } -} -``` - -**gradle transform** 的输出 - -``` -> gradle transform -:transform -Transforming source file. -``` - -**gradle transform** 的输出 - -``` -> gradle transform -:transform -Transforming source file. -``` - -这里 Gradle 执行了这个任务两次, 即使什么都没有改变, 它也没有跳过这个任务. 这个例子里的任务, 它的行为是通过闭包定义的. Gradle 并不知道闭包会做什么, 也并不能自动指出是否这个任务是 up-to-date. 为了使用 Gradle 的 up-to-date 检测, 你需要**定义任务的输入和输出**. - -每个任务都有输入和输出属性, 你需要使用这些属性来声明任务的输入和输出. 下面的例子中, 我们将声明 XML 文件作为输入, 并且把输出放在一个指定的目录. 让我们运行这个任务 2 次. - -**例子 15.24. 声明任务的输入和输出** - -**build.gradle** - -``` -task transform { - ext.srcFile = file('mountains.xml') - ext.destDir = new File(buildDir, 'generated') - inputs.file srcFile - outputs.dir destDir - doLast { - println "Transforming source file." - destDir.mkdirs() - def mountains = new XmlParser().parse(srcFile) - mountains.mountain.each { mountain -> - def name = mountain.name[0].text() - def height = mountain.height[0].text() - def destFile = new File(destDir, "${name}.txt") - destFile.text = "$name -> ${height}\n" - } - } -} -``` - -**gradle transform** 的输出 -``` -> gradle transform -:transform -Transforming source file. -``` -**gradle transform** 的输出 -``` -> gradle transform -:transform UP-TO-DATE -``` - -现在, Gradle 就能够检测出任务是否是 up-to-date 状态. - -任务的输入属性是 [TaskInputs 类型](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskInputs.html). 任务的输出属性是 [TaskOutputs 类型](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskOutputs.html). - -一个任务如果没有定义输出的话, 那么它永远都没用办法判断 up-to-date. 对于某些场景, 比如一个任务的输出不是文件, 或者更复杂的场景, [TaskOutputs.upToDateWhen()](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskOutputs.html#upToDateWhen(groovy.lang.Closure)) 方法会计算任务的输出是否应被视为最新. - -总而言之, **如果一个任务只定义了输出, 如果输出不变的话, 它就会被视为 up-to-date.** - -### 2. 它是如何工作的? - -当一个任务是首次执行时, Gradle 会取一个输入的快照 (snapshot). 该快照包含组输入文件和每个文件的内容的散列. 然后当 Gradle 执行任务时, 如果任务成功完成,Gradle 会获得一个输出的快照. 该快照包含输出文件和每个文件的内容的散列. Gradle 会保留这两个快照用来在该任务的下一次执行时进行判断. - -之后, 每次在任务执行之前, Gradle 都会为输入和输出取一个新的快照, 如果这个快照和之前的快照一样, Gradle 就会假定这个任务已经是最新的 (up-to-date) 并且跳过任务, 反之亦然. - -需要注意的是, 如果一个任务有指定的输出目录, 自从该任务上次执行以来被加入到该目录的任务文件都会被忽略, 并且不会引起任务过时 (out of date). 这是因为不相关任务也许会共用同一个输出目录. 如果这并不是你所想要的情况, 可以考虑使用 [TaskOutputs.upToDateWhen()](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskOutputs.html#upToDateWhen(groovy.lang.Closure)) - - diff --git a/more_about_tasks/task_rules.md b/more_about_tasks/task_rules.md deleted file mode 100644 index 3423f4f..0000000 --- a/more_about_tasks/task_rules.md +++ /dev/null @@ -1,56 +0,0 @@ -# Task 规则 - -有时候也想要一个任务的行为是基于已经定义好的取值范围或者特定规则, 下面的例子就提供了一种很直观漂亮的方式: - -**例子 15.25. 任务规则** - -**build.gradle** - -``` -tasks.addRule("Pattern: ping") { String taskName -> - if (taskName.startsWith("ping")) { - task(taskName) << { - println "Pinging: " + (taskName - 'ping') - } - } -} -``` - -**gradle -q pingServer1** 的输出 - -``` -> gradle -q pingServer1 -Pinging: Server1 -``` - -这里的 String 参数就是用来定义规则的. - -规则并不只是在通过命令行使用任务的时候执行. 你也可以基于规则来创建依赖关系: - -**例子 15.26. 基于规则的任务依赖** - -**build.gradle** - -``` -tasks.addRule("Pattern: ping") { String taskName -> - if (taskName.startsWith("ping")) { - task(taskName) << { - println "Pinging: " + (taskName - 'ping') - } - } -} - -task groupPing { - dependsOn pingServer1, pingServer2 -} -``` - -**gradle -q groupPing** 的输出 - -``` -> gradle -q groupPing -Pinging: Server1 -Pinging: Server2 -``` - -如果你运行 “gradle -q tasks”, 你并不能找到名叫 “pingServer1” 或者 “pingServer2” 的任务, 但是这个脚本仍然会执行这些任务. diff --git a/more_about_tasks/use_other_script_to_config_any_object.md b/more_about_tasks/use_other_script_to_config_any_object.md deleted file mode 100644 index 8173fec..0000000 --- a/more_about_tasks/use_other_script_to_config_any_object.md +++ /dev/null @@ -1,31 +0,0 @@ -# 使用其他的脚本配置任意对象 - -您也可以使用其他的构建脚本配置任意的对象. - -**例子: 14.5.使用别的脚本配置配置对象** - -**build.gradle** - - task config << { - def pos = new java.text.FieldPosition(10) - - // 使用另一个脚本 - apply from: 'other.gradle', to: pos - println pos.beginIndex - println pos.endIndex - - } - -**other.gradle** - - beginIndex = 1 - endIndex = 5 - - -**使用 gradle -q configure 输出** - - > gradle -q configure - 1 - 5 - - diff --git a/more_about_tasks/use_other_script_to_config_project.md b/more_about_tasks/use_other_script_to_config_project.md deleted file mode 100644 index 293090d..0000000 --- a/more_about_tasks/use_other_script_to_config_project.md +++ /dev/null @@ -1,22 +0,0 @@ -# 使用其他的脚本配置项目 -您还可以使用其他的构建脚本来配置当前的项目,Gradle 构建语言的所有的内容对于其他的脚本都是可以使用的. 您甚至可以在别的脚本中再使用其他的脚本. - -**例子 14.3.使用其他的构建脚本配置项目** - -**build.gradle** - - apply from: 'other.gradle' - -**other.gradle** - - println "configuring $project" - task hello << { - println' 'hello form other srcipt' - } - -**使用 gradle -q hello 输出** - - > gradle -q hello - configuring root project 'configureProjectUsingScript' - hello from other script - diff --git a/overview/README.md b/overview/README.md deleted file mode 100644 index 08bff6e..0000000 --- a/overview/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 概述 - -* 特点 -* 为什么用 Groovy? - diff --git a/overview/features.md b/overview/features.md deleted file mode 100644 index 4eebfb7..0000000 --- a/overview/features.md +++ /dev/null @@ -1,78 +0,0 @@ -# 特点 - -这里简述下 Gradle 的特点. - -**1. 声明式构建和合约构建** - -Gradle 的核心是基于 Groovy 的 -领域特定语言 (DSL), 具有十分优秀的扩展性. Gradle 通过提供可以随意集成的声明式语言元素将声明性构建推到了一个新的高度. 这些元素也为 Java, Groovy, OSGi, Web 和Scala 等项目提供基于合约构建的支持. 而且, 这种声明式语言是可扩展的. 你可以添加自己的语言元素或加强现有的语言元素, 从而提供简洁, 易于维护和易于理解的构建. - - -**2. 基于依赖的编程语言** - -声明式语言位于通用任务图 ( general purpose task graph ) 的顶端,它可以被充分利用在你的构建中. 它具有强大的灵活性, 可以满足使用者对 Gradle 的一些特别的需求. - - -**3. 让构建结构化** - -Gradle 的易适应性和丰富性可让你在构建里直接套用通用的设计原则. 例如, 你可以非常容易地使用一些可重用的组件来构成你的构建. 但是不必要的间接内联内容是不合适的. 不要强行拆分已经结合在一起的部分 (例如, 在你的项目层次结构中). 避免使构建难以维护. 总之, 你可以创建一个结构良好,易于维护和易于理解的构建. - -**4. API深化** - -你会非常乐意在整个构建执行的生命周期中使用 Gradle, 因为Gradle 允许你管理和定制它的配置和执行行为. - -**5. Gradle 扩展** - -Gradle 扩展得非常好. 不管是简单的独立项目还是大型的多项目构建, 它都能显著的提高效率. -这是真正的结构构建. 顶尖水平的构建功能,还可以解决许多大公司碰到的构建 性能低下的问题. - - -**6. 多项目构建** - -Gradle 对多项目的支持是非常出色的. 项目依赖是很重要的部分. 它允许你模拟在多项目构建中项目的关系,这正是你所要关注的地方. Gradle 可以适应你的项目的结构, 而不是反过来. - -Gradle 提供了局部构建的功能. 如果你构建一个单独的子项目, Gradle 会构建这个子项目依赖的所有子项目. 你也可以选择依赖于另一个特别的子项目重新构建这些子项目. 这样在一些大型项目里就可以节省非常多的时间. - -**7. 多种方式来管理你的依赖** - -不同的团队有不同的管理外部依赖的方法. Gradle 对于任何管理策略都提供了合适的支持. 从远程 Maven 和 Ivy 库的依赖管理到本地文件系统的 jars 或者 dirs. - -**8. Gradle 是第一个构建整合工具** - -Ant 的 tasks是 Gradle 中很重要的部分, 更有趣是 Ant 的 projects 也是十分重要的部分. Gradle 可以直接引入Ant 项目, 并在运行时直接将 Ant targets 转换成 Gradle tasks. -你可以从 Gradle 中依赖它们, 并增强它们的功能, 甚至可以在 build.xml 文件中声明 Gradle tasks 的依赖. 并且properties, paths 等也可以通过同样的方法集成进来. - -Gradle 完全支持你已有的 Maven 或者 lvy 仓库来构造发布或者提取依赖. Gradle 也提供了一个转化器, 用来将 maven 的 pom.xml 文件转换成 Gradle 脚本. 在运行时引入 Maven 项目也会在稍后推出. - -**9. 易于迁移** - -Gradle 可以兼容任何结构. 因此你可以直接在你的产品构建的分支上开发你的 Gradle 构建, 并且二者可以并行. 我们通常建议编写一些测试代码来确保它们的功能是相同的. -通过这种方式, -在迁移的时候就不会显得那么混乱和不可靠, -这是通过婴儿学步的方式来获得最佳的实践. - -**10. Groovy** - -Gradle 的构建脚本是通过 Groovy 编写的而不是 XML. -但是并不像其他方式, -这并不是为了简单的展示用动态语言编写的原始脚本有多么强大. -不然的话, -只会导致维护构建变得非常困难. -Gradle 的整个设计是朝着一种语言的方向开发的, -并不是一种死板的框架. -Groovy 就像胶水一样, 把你想实现的构想和抽象的 Gradle 粘在一起. Gradle提供了一些标准的构想, 但是他们并不享有任何形式的特权. 相比于其他声明式构建系统,对我们来说这是一个比较突出的特点. - -**10. Gradle 包装器** - -Gradle 包装器允许你在没有安装 Gradle 的机器上运行 Gradle 构建. -在一些持续集成的服务器上, -这个功能将非常有用. -它同样也能降低使用一个开源项目的门槛, -也就是说构建它将会非常简单. -这个包装器对于公司来说也是很有吸引力的. -它并不需要为客户机提供相应的管理防范. -这种方式同样也能强制某一个版本 Gradle 的使用从而最小化某些支持问题. - -**11. 免费和开源** - -Gradle 是一个开源项目, 遵循 ASL 许可. diff --git a/overview/why_groovy.md b/overview/why_groovy.md deleted file mode 100644 index f125e01..0000000 --- a/overview/why_groovy.md +++ /dev/null @@ -1,25 +0,0 @@ -# 为什么用 Groovy? - -我们认为在脚本构建时, -一个内部的 DSL(基于一个动态语言)相对于 XML 的优势是巨大的. 有这么多的动态语言, -为什么选择 Groovy? -答案在于 Gradle 的运行环境. -虽然 Gradle 以一个通用构建工具为核心, 但是它的重点是Java项目. -在这样的项目中, -显然团队每个成员都对 Java 非常熟悉. 我们认为构建应尽可能对所有团队成员都是透明的, 所以选择了 Groovy. - -你可能会说,为什么不直接使用 Java 作为构建脚本的语言. 我们认为这是一个很有用的问题. -对于你的团队, -它要有最高的透明度和最低的学习曲线, -也就是说容易掌握. -但由于 Java 的限制, -这样的构建语言不会那么完美和强大. -而像 Python,Groovy 或 Ruby 语言用来作为构建语言会更好. -我们选择了 Groovy 是因为它给 Java 开发人员提供了迄今为止最大的透明度. 其基本的符号和类型与 Java 是一样的,其封装结构和许多其他的地方也是如此. -Groovy 在这基础上提供了更多的功能, -而且与 java 有共同的基础. - -对于那些同时是或者即将是 Python 或 Ruby 开发者的 Java 开发人员来说, -上述的讨论并不适用. -Gradle 的设计非常适合在 JRuby 和 Jython 中创建另一个构建脚本引擎. 它对于我们来说只是目前开发中没有最高优先级. 我们十分支持任何人来做贡献, -创建额外的构建脚本引擎. diff --git a/standard_gradle_plugins/README.md b/standard_gradle_plugins/README.md deleted file mode 100644 index a892e81..0000000 --- a/standard_gradle_plugins/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Standard Gradle plugins - -许多包括在Gradle分布的插件。这些在下面列出。 diff --git a/standard_gradle_plugins/base_plugins.md b/standard_gradle_plugins/base_plugins.md deleted file mode 100644 index c6598e7..0000000 --- a/standard_gradle_plugins/base_plugins.md +++ /dev/null @@ -1,31 +0,0 @@ -# 基础插件 - -这些插件是形成其他插件的基本构建模块.你可以在你的构建文件中使用它们,在下面李处完整地列表,然而,注意它们还不是Gradle的公用API的一部分.因此,这些插件未记录在用户指南中.你可能会参考他们的API文档,详细了解它们. - -**Table 22.7. Base plugins** - -#### base - -添加标准的生命周期任务和配置合理的默认归档任务: -+ 增加*ConfigurationName*任务.这些任务组装指定配置的工件。 -+ 增加了上传*ConfigurationName*任务,这些任务组装并上传指定配置的工件。 -+ 对所有归档任务配置合理的默认值(如继承[AbstractArchiveTask](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.AbstractArchiveTask.html)的任务).如归档类型的任务:[Jar](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html),[Tar](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Tar.html),[Zip](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Zip.html).特别的,归档的`destinationDir`,`baseName`和`version`属性是预先配置的默认值.这是非常有用的,因为它推动了跨项目的一致性;关于档案的命名规则和完成构建后的位置的一致性。 - -#### java-base - -+ 增加资源集的概念到项目中.不添加特定的资源. - -#### groovy-base - -+ 增加了Groovy的源集理念到项目中. - -#### scala-base - -+ 添加scala源集合概念到项目中. - -#### reporting-base - -+ 为项目增加了一些涉及到生产报告的公约性质的属性, - - -> 译者注:实在不会使用MarkDown在表格中加入列表,好在只表格只有两列,故本节不能按照官网的User Guide表格给出.而是以列表形式完成 diff --git a/standard_gradle_plugins/incubating_integration_plugins.md b/standard_gradle_plugins/incubating_integration_plugins.md deleted file mode 100644 index b3c62cc..0000000 --- a/standard_gradle_plugins/incubating_integration_plugins.md +++ /dev/null @@ -1,12 +0,0 @@ -# 孵化中的集成插件 - -这些插件提供的各种运行时的技术的集成. - -**Table 22.4. Incubating integration plugins** - -| Plugin Id | 自动应用 | 协同工作 | 描述 | -| -- | -- | -- | -- | -| [distribution](https://docs.gradle.org/current/userguide/distribution_plugin.html) | - | - | 对构建增加对ZIP和TAR的支持 | -| [java-library-distribution](https://docs.gradle.org/current/userguide/javaLibraryDistribution_plugin.html) | java, distribution | - | 增加了对建筑ZIP和TAR的一个Java库的支持. | -| [ivy-publish](https://docs.gradle.org/current/userguide/publishing_ivy.html) | - | java, war | 这个插件提供了一个新的DSL支持发布artifacts ivy存储库,它改善了现有的DSL. | -| [maven-publish](https://docs.gradle.org/current/userguide/publishing_maven.html) | - | java, war | 这个插件提供了一个新的DSL支持发布artifacts Maven仓库,它改善了现有的DSL。 | diff --git a/standard_gradle_plugins/incubating_language_plugins.md b/standard_gradle_plugins/incubating_language_plugins.md deleted file mode 100644 index 20866ee..0000000 --- a/standard_gradle_plugins/incubating_language_plugins.md +++ /dev/null @@ -1,13 +0,0 @@ -# 孵化中的语言插件 - -这些插件增加对各种语言的支持: - -**Table 22.2. Language plugins** - -| Plugin Id | 自动应用 | 协同工作 | 描述 | -| -- | -- | -- | -- | -| [assembler](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 增加了原生的汇编语言能力的项目。 | -| [c](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 添加C源代码编译能力的项目. | -| [cpp](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 增加C ++源代码编译能力的项目. | -| [objective-c](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 添加的Objective-C ++源代码编译能力的项目. | -| [windows-resources](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 增加了对包括Windows资源的本机二进制文件的支持. | diff --git a/standard_gradle_plugins/incubating_software_development_plugins.md b/standard_gradle_plugins/incubating_software_development_plugins.md deleted file mode 100644 index 14bf731..0000000 --- a/standard_gradle_plugins/incubating_software_development_plugins.md +++ /dev/null @@ -1,17 +0,0 @@ -# 孵化中的软件开发插件 - -这些插件在您的软件开发过程中提供帮助. - -**Table 22.6. Software development plugins** - -| Plugin Id | 自动应用 | 协同工作 | 描述 | -| -- | -- | -- | -- | -| [build-dashboard](https://docs.gradle.org/current/userguide/buildDashboard_plugin.html) | reporting-base | - | 生成构建仪表板报告. | -| [build-init](https://docs.gradle.org/current/userguide/build_init_plugin.html) | wrapper | - | 对Gradle初始化一个新构建提供支持.将一个Maven构建转换为Gradle构建 | -| [cnuit](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 提供运行[CUnit](http://cunit.sourceforge.net/)测试支持 | -| [jacoco](https://docs.gradle.org/current/userguide/jacoco_plugin.html) | reporting-base | java | 对面向Java的[JaCoCo](http://www.eclemma.org/jacoco/)代码库整合 | -| [sonar-runner](https://docs.gradle.org/current/userguide/sonar_runner_plugin.html) | -| java-base, java, jacoco | 提供与[Sonar](http://www.sonarsource.org/)代码质量平台的整合.取代[sonar](https://docs.gradle.org/current/userguide/sonar_plugin.html)插件 | -| [visual-studio](https://docs.gradle.org/current/userguide/nativeBinaries.html) | - | - | 增加了与Visual Studio集成. | -| [wrapper](https://docs.gradle.org/current/userguide/wrapper_plugin.html) | - | - | 增加一个[Wrapper](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html)任务来生成Gradle打包文件. | -| [java-gradle-plugin](https://docs.gradle.org/current/userguide/javaGradle_plugin.html) | java | - | 通过提供标准的插件生成配置和验证,协助Gradle发展. | - diff --git a/standard_gradle_plugins/integration_plugins.md b/standard_gradle_plugins/integration_plugins.md deleted file mode 100644 index bef8bd3..0000000 --- a/standard_gradle_plugins/integration_plugins.md +++ /dev/null @@ -1,14 +0,0 @@ -# 集成插件 - -这些插件提供的各种运行时的技术的集成. - -**Table 22.3. Integration plugins** - -| Plugin Id | 自动应用 | 协同工作 | 描述 | -| -- | -- | -- | -- | -| [application](https://docs.gradle.org/current/userguide/application_plugin.html) | java, distribution | - | 增加了对运行绑定Java项目作为命令行应用的任务. | -| [ear](https://docs.gradle.org/current/userguide/ear_plugin.html) | - | java | 增加了对构建J2EE应用程序的支持. | -| [jetty](https://docs.gradle.org/current/userguide/jetty_plugin.html) | war | - | 在构建中嵌入Jetty web容器可以部署web应用.参见[Chapter 10, Web Application Quickstart](https://docs.gradle.org/current/userguide/web_project_tutorial.html) | -| maven | - | java, war | 增加了对发布artifacts到Maven仓库的支持. | -| [sogi](https://docs.gradle.org/current/userguide/osgi_plugin.html) | java-base | java | 增加了对构建OSGi支持 | -| [war](https://docs.gradle.org/current/userguide/war_plugin.html) | java | - | 增加了对组装Web应用程序WAR文件的支持.参见[Chapter 10, Web Application Quickstart](https://docs.gradle.org/current/userguide/web_project_tutorial.html) | diff --git a/standard_gradle_plugins/language_plugins.md b/standard_gradle_plugins/language_plugins.md deleted file mode 100644 index b929538..0000000 --- a/standard_gradle_plugins/language_plugins.md +++ /dev/null @@ -1,14 +0,0 @@ -# 语言插件 - -这些插件添加了可以被编译并在JVM中执行的各种语言的支持 - -**Table 22.1. Language plugins** - -| Plugin Id | 自动应用 | 协同工作 | 描述 | -| -- | -- | -- | -- | -| [java](https://docs.gradle.org/current/userguide/java_plugin.html) | java-base | - | 为项目添加java编译,测试及绑定能力,作为许多Gradle插件的基础.参见[Chapter 7, Java Quickstart](https://docs.gradle.org/current/userguide/tutorial_java_projects.html) | -| [groovy](https://docs.gradle.org/current/userguide/groovy_plugin.html) | java, groovy-base | - | 为Groovy项目构建增加支持,参见[Chapter 9, Groovy Quickstart](https://docs.gradle.org/current/userguide/tutorial_groovy_projects.html) | -| [scala](https://docs.gradle.org/current/userguide/scala_plugin.html) | java, scala-base | - | 增加了对Scala项目构建的支持 | -| [antlr](https://docs.gradle.org/current/userguide/antlr_plugin.html) | java | - | 增加了对使用ANTLR的生成解析器的支持. | - - diff --git a/standard_gradle_plugins/software_development_plugins.md b/standard_gradle_plugins/software_development_plugins.md deleted file mode 100644 index 44955cc..0000000 --- a/standard_gradle_plugins/software_development_plugins.md +++ /dev/null @@ -1,22 +0,0 @@ -# 软件开发插件 - -这些插件在您的软件开发过程中提供帮助. - -**Table 22.5. Software development plugins** - -| Plugin Id | 自动应用 | 协同工作 | 描述 | -| -- | -- | -- | -- | -| [announce](https://docs.gradle.org/current/userguide/announce_plugin.html) | - | - | 消息发布到自己喜欢的平台,如Twitter或Growl. | -| [build-announcements](https://docs.gradle.org/current/userguide/build_announcements_plugin.html) | announce | - | 发送本地通知关于有趣的事件在构建生命周期到你的桌面. | -| [checkstyle](https://docs.gradle.org/current/userguide/checkstyle_plugin.html) | java-base | - | 使用[Checksytle](http://checkstyle.sourceforge.net/index.html)对项目的Java源码执行质量检测,并生成报告. | -| [codenarc](https://docs.gradle.org/current/userguide/codenarc_plugin.html) | groovy-base | - | 使用[CodeNarc](http://codenarc.sourceforge.net/index.html)对项目的Groovy的源文件进行质量检测,并生成检测报告 | -| [eclipse](https://docs.gradle.org/current/userguide/eclipse_plugin.html) | - | java,groovy, scala | 生成Eclipse IDE的文件,从而能够以导入项目到Eclipse.参见[Chapter 7, Java Quickstart](https://docs.gradle.org/current/userguide/tutorial_java_projects.html) | -| [eclipse-wtp](https://docs.gradle.org/current/userguide/eclipse_plugin.html) | - | ear, war | 与eclipse插件一样,生成eclipse WPT(Web Tools Platform)配置文件, 导入到Eclipse中war/ear项目应配置与WTP工作.参见参见[Chapter 7, Java Quickstart](https://docs.gradle.org/current/userguide/tutorial_java_projects.html)| -| [findbugs](https://docs.gradle.org/current/userguide/findbugs_plugin.html) | java-base | - | 使用[FindBugs](http://findbugs.sourceforge.net/)执行项目的Java源文件质量检测,并生成检测报告 | -| [idea](https://docs.gradle.org/current/userguide/idea_plugin.html) | - | java | 生成[Intellij IDEA IDE](http://www.jetbrains.com/idea/index.html)配置文件,从而可以将项目导入IDEA。 | -| [jdepend](https://docs.gradle.org/current/userguide/jdepend_plugin.html) | java-base | - | 使用[JDepend](http://clarkware.com/software/JDepend.html)执行项目的源文件质量检测,并生成检测报告 | -| [pmd](https://docs.gradle.org/current/userguide/pmd_plugin.html) | java-base | - | 使用[PMD](http://pmd.sourceforge.net/)执行项目的源文件质量检测,并生成检测报告 | -| [project-report](https://docs.gradle.org/current/userguide/project_reports_plugin.html) | reporting-base | - | 生成一个包含关于您的Gradle构建有用信息的报告。 | -| [signing](https://docs.gradle.org/current/userguide/signing_plugin.html) | base | - | 添加数字签名档案和artifacts的能力。 | -| [sonar](https://docs.gradle.org/current/userguide/sonar_plugin.html) | - | java-base, java, jacoco | 与[Sonar](http://www.sonarsource.org/)代码质量平台整合.由[sonar-runner](https://docs.gradle.org/current/userguide/sonar_runner_plugin.html)插件提供 | - diff --git a/standard_gradle_plugins/third_party_plugins.md b/standard_gradle_plugins/third_party_plugins.md deleted file mode 100644 index 513e045..0000000 --- a/standard_gradle_plugins/third_party_plugins.md +++ /dev/null @@ -1,3 +0,0 @@ -# 第三方插件 - -你可以在[Gradle Plugins site]()找到外部插件. diff --git a/the_gradle_daemon/README.md b/the_gradle_daemon/README.md deleted file mode 100644 index ab23482..0000000 --- a/the_gradle_daemon/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# The Gradle Daemon - diff --git a/the_gradle_daemon/how_can_i_stop_a_daemon.md b/the_gradle_daemon/how_can_i_stop_a_daemon.md deleted file mode 100644 index a36ce79..0000000 --- a/the_gradle_daemon/how_can_i_stop_a_daemon.md +++ /dev/null @@ -1,5 +0,0 @@ -# 如何停止守护进程 - -守护进程会在闲置3小时后自动终止.如果想在这之前停止守护进程,也可以通过操作系统运行`gradle --stop`命令终止后台进程.`--stop`选项会要求*所有*运行*相同版本*的守护进程终止. - - diff --git a/the_gradle_daemon/how_do_i_disable_the_gradle_daemon.md b/the_gradle_daemon/how_do_i_disable_the_gradle_daemon.md deleted file mode 100644 index 570aab3..0000000 --- a/the_gradle_daemon/how_do_i_disable_the_gradle_daemon.md +++ /dev/null @@ -1,7 +0,0 @@ -# 如何禁用Gradle的守护进程 - -一般Gradle守护进程默认不启用.然而,一旦它被启用,有事希望对某些项目或某些构建禁用守护进程. - -`--no-daemon`命令行选项可用于强制守护进程不能用于该构建.这很少使用,但是在调试具有一定的构建或Gradle插件问题时,有时会很有用.在构建环境中,此命令行选项具有*最高*优先级. - - diff --git a/the_gradle_daemon/how_do_i_enable_the_gradle_daemon.md b/the_gradle_daemon/how_do_i_enable_the_gradle_daemon.md deleted file mode 100644 index df2fbb1..0000000 --- a/the_gradle_daemon/how_do_i_enable_the_gradle_daemon.md +++ /dev/null @@ -1,24 +0,0 @@ -# 如何启动Gradle的守护进程 - -在使用Gradle命令行接口时,`--daemon`和`--no-daemon`命令行选项调用在单个构建时选择启用或禁用后台守护进程.通常,允许后台守护进程在一个环境中(例如一个用户账户)更为方便,可以使所有构建使用守护进程,而不需要记住`--daemon`开关. - - -有两种推荐的方式使守护进程持续与环境: - -1. 通过环境变量 - 给`GRADLE_OPTS`环境变量添加`-Dorg.gradle.daemon=true`标识 -2. 通过属性文件 - 给`<>/gradle.properties`文件添加`org.gradle.daemon=true` - -> 注意:`<>`默认为`<>/.gradle`,`<>为当前用户home目录`,这个位置可以通过`-g`和`-gradle-user-home`命令行选项,以及由`GRADLE_USER_HOME`环境变量`org.gradle.user.home` JVM系统属性配置。 - -这两种方法有同样的效果,使用哪一个是由个人喜好.大多数Gradle用户选择第二个方式,给gradle.properties并添加条目. - -在Windows中,该命令将使当前用户启用守护: - -`(if not exist "%HOMEPATH%/.gradle" mkdir "%HOMEPATH%/.gradle") && (echo foo >> "%HOMEPATH%/.gradle/gradle.properties")` - -在类Unix操作系统,以下的Bash shell命令将使当前用户启用守护进程: - -`touch ~/.gradle/gradle.properties && echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties` - -一旦以这种方式在构建环境中启用了守护进程,所有的构建将隐含一个守护进程. - diff --git a/the_gradle_daemon/how_do_i_suppress_the_please_consider_using_the_gradle_daemon_message.md b/the_gradle_daemon/how_do_i_suppress_the_please_consider_using_the_gradle_daemon_message.md deleted file mode 100644 index 90c121d..0000000 --- a/the_gradle_daemon/how_do_i_suppress_the_please_consider_using_the_gradle_daemon_message.md +++ /dev/null @@ -1,5 +0,0 @@ -# 怎样抑制“please consider using the Gradle Daemon”消息 - -Gradle可能会在构建结束时发出建议您使用Gradle守护进程的末尾警告.为了避免这个警告,您可以通过上述的这些方法使用守护进程,或者明确禁用守护进程.您可以通过上述的`--no daemon`的命令行选项明确禁用守护进程,或使用上述的`org.gradle.deamon`的值设置为`false`代替`trie`. - -因为不建议在持续集成构建中使用守护进程,如果`CI`环境变量已存在,Gradle不会发出此消息. diff --git a/the_gradle_daemon/how_does_the_gradle_daemon_make_builds_faster.md b/the_gradle_daemon/how_does_the_gradle_daemon_make_builds_faster.md deleted file mode 100644 index 1c4f3e2..0000000 --- a/the_gradle_daemon/how_does_the_gradle_daemon_make_builds_faster.md +++ /dev/null @@ -1,9 +0,0 @@ -# 摇篮守护进程如何使构建速度更快 - -Gradle守护进程是一个*常驻*构建进程.在两个构建之间的空闲期间会等待着下次构建.与每个构建加载Gradle到内存相比,对于多个构建只需要加载一次Gradle到内存具有明显的好处.这本身就是对性能的显著优化,但是不止这些. - -现代JVM的显著优化是运行时代码优化.例如,热点(HotSpot)(由Oracle提供并作为OpenJDK的基础的JVM实现)适用于优化运行时代码.优化是渐进的,而不是瞬间的。也就是说,代码在运行期间逐步优化,这意味着后续版本纯粹是基于这个优化过程变得更快.HotSpot实验表明,它需要5至10某处构建以优化至稳定.在一个守护进程的第一个构建和第十之间感知的编译时间的差异可以说是相当巨大的. - -守护程序还允许更有效地在内存中缓存整个构建。例如,需要构建(如插件,构建脚本)的类可以在内存中举行的构建。同样,摇篮可保持在内存中缓存的构建数据的诸如的任务输入和输出的哈希值,用于增量构建。 - - diff --git a/the_gradle_daemon/how_much_memory_does_the_daemon_use_and_can_i_give_it_more.md b/the_gradle_daemon/how_much_memory_does_the_daemon_use_and_can_i_give_it_more.md deleted file mode 100644 index 0d29f67..0000000 --- a/the_gradle_daemon/how_much_memory_does_the_daemon_use_and_can_i_give_it_more.md +++ /dev/null @@ -1,7 +0,0 @@ -# 守护进程占用多大内存并且能不能给它更大的内存? - -如果需求构建环境没有指定最大堆内存,守护进程会使用多达1G的堆内存.它将会使用默认的JVM的最小堆内存.1G内存足够应付大多数构建.有数百个子项的构建,大量配置或者源码需求,或者要求有更好的表现,则需要更多地内存 - -为了提高守护进程可以使用的内存,指定相应的标志作为需求构建环境的一部分,请参见[Chapter 20. The Build Environment](https://docs.gradle.org/current/userguide/build_environment.html)的详细信息. - - diff --git a/the_gradle_daemon/management_and_configuration.md b/the_gradle_daemon/management_and_configuration.md deleted file mode 100644 index f557e61..0000000 --- a/the_gradle_daemon/management_and_configuration.md +++ /dev/null @@ -1 +0,0 @@ -# 管理和配置 diff --git a/the_gradle_daemon/potential_future_enhancements.md b/the_gradle_daemon/potential_future_enhancements.md deleted file mode 100644 index c7d62fb..0000000 --- a/the_gradle_daemon/potential_future_enhancements.md +++ /dev/null @@ -1,8 +0,0 @@ -# 未来可能的改进 - -目前,守护使构建速度更快有效地支持在内存中缓存和由JVM优化使代码更快。在未来的Gradle版本中,守护进程将变得更加聪明,预先完成工作。它可能,例如,在编辑完构建脚本后就开始下载依赖生成是将要运行的假设下后立即和新改变或添加的依赖性是必需的。 - -有许多方式使得在未来的版本的gradle的gradle守护进程。 - - - diff --git a/the_gradle_daemon/tools_&_ides.md b/the_gradle_daemon/tools_&_ides.md deleted file mode 100644 index 4ba1f2b..0000000 --- a/the_gradle_daemon/tools_&_ides.md +++ /dev/null @@ -1,5 +0,0 @@ -# 工具和集成开发环境 - -Gradle工具API(参见[Chapter.65.Embedding Gradle](https://docs.gradle.org/current/userguide/embedding.html)),用于IDEs和其他工具整合Gradle,*总*是使用Gradle守护进程执行构建.如果你是从IDE内部执行构建,那么你是在使用守护进程,而且不需要在你的环境中允许Gradle守护进程. - -但是,除非您已明确启用的Gradle守护进程在你的环境的,你在命令行中的构建不会使用摇篮守护进程。 diff --git a/the_gradle_daemon/what_can_go_wrong_with_daemon.md b/the_gradle_daemon/what_can_go_wrong_with_daemon.md deleted file mode 100644 index 3908b56..0000000 --- a/the_gradle_daemon/what_can_go_wrong_with_daemon.md +++ /dev/null @@ -1,10 +0,0 @@ -# 守护进程何时会出错 - -许多工程设计已经加入守护进程使得守护进程在日常的开发中变得更加健壮,透明和不起眼.无论如何,守护进程偶尔也会损坏或者枯竭.一个Gradle构建执行源自多个来源的任意代码.即使Gradle本身与守护进程的设计是经过严格的测试的,但是用户的构建脚本,或第三方插件可以通过诸如内存泄露,或腐化全局声明等缺陷来动摇守护进程. - -另外,也可以通过构建时进行不正确的资源释放,也可能会动摇守护进程(构建环境正常).在在Microsoft Windows下是一个特别尖锐的问题,在程序读写文件后关闭失败的处理是非常随意的. - -如果出现守护进程不稳定情况,可以简单的终止.回顾一下`--no-daemon`的选项可以用于构建阻止使用守护进程,这对于检验一个问题的罪魁祸首是不是守护进程很有帮助. - - - diff --git a/the_gradle_daemon/what_is_the_gradle_daemon.md b/the_gradle_daemon/what_is_the_gradle_daemon.md deleted file mode 100644 index 8146aa5..0000000 --- a/the_gradle_daemon/what_is_the_gradle_daemon.md +++ /dev/null @@ -1,16 +0,0 @@ -# 什么是 Gradle 的守护进程 - -维基百科中守护进程的解释 - -> *守护进程是一个运行后台进程, 非交互式用户直接控制的在计算机程序* - -Gradle 守护进程是一个后台进程, -它运行着繁重的构建, 然后在构建等待下一次构建的之间保持自身存在. 这使得数据和代码在下一次构建前已经准备好,并存入内存中. 这*显著*的提高了后续构建的性能. 启用Gradle守护进程是一种节约构建时间的廉价方式. - -*强烈建议在所有开发机器上启用Gradle的守护进程*.但是*不推荐*在持续集成和构建服务器环境下启用守护进程(参见 [Section 18.3, “When should I not use the Gradle Daemon?”](https://docs.gradle.org/current/userguide/gradle_daemon.html#when_should_i_not_use_the_gradle_daemon)). - -Gradle自动管理守护进程.如果构建环境配置为利用后台程序,如果在没有可用守护进程,就会自动启动一个守护进程,或者使用现有的空闲的*兼容*守护进程.如果一个守护进程在3个小时内没有使用,它将会自我终结.一旦配置开发环境为使用的守护进程,守护进程通常是隐形的,容易被遗忘的. - - - - diff --git a/the_gradle_daemon/when_should_i_not_use_the_gradle_daemon.md b/the_gradle_daemon/when_should_i_not_use_the_gradle_daemon.md deleted file mode 100644 index f7ee0e2..0000000 --- a/the_gradle_daemon/when_should_i_not_use_the_gradle_daemon.md +++ /dev/null @@ -1,5 +0,0 @@ -# 什么时候不使用Gradle守护进程 - -建议在开发环境中使用Gradle的守护进程,*不建议*在持续集成环境和构建服务器环境中使用守护进程. - -守护进程可以更快的构建,这对于一个正坐在椅子前构建项目的人来说非常重要.对于CI构建来说,稳定性和可预见性是最重要的.为每个构建运行时用一个新的,完全孤立于以前的版本的程序,更加可靠。 diff --git a/the_gradle_daemon/why_is_there_more_than_one_daemon_process_on_my_machine.md b/the_gradle_daemon/why_is_there_more_than_one_daemon_process_on_my_machine.md deleted file mode 100644 index ae5cb8b..0000000 --- a/the_gradle_daemon/why_is_there_more_than_one_daemon_process_on_my_machine.md +++ /dev/null @@ -1,31 +0,0 @@ -# 为什么会在机器上出现不只一个守护进程 - -有几个原因Gradle会创建一个新的守护进程代替使用一个已存在的守护进程.如果守护进程没有*闲置*,*兼容*,则会启动一个新的守护进程. - -*空闲*的守护进程是当前未执行构建或做其他有用的工作. - -*兼容*的守护进程是一个可以(或者可以达到)满足要求的编译环境的要求。Java安装程序运行的构建是构建环境方面的一个例子。构建运行时所需的JVM系统属性是另一个例子。 - -一个已经运行的Java进程可能不能满足所需的构建环境的某些方面。如果守护进程由Java7启动,但要求的环境要求为Java8,则守护进程是不兼容的,必须另外启动。再者,在运行的JVM不能改变一个运行时的某些性能。如内存分配(如-Xmx1024m),默认文本编码运行的JVM中,默认的语言环境,等等一个JVM不能改变的运行环境。 - -"Required build environment"通常在构建客户端(如Gradle命令行,IDE等)方面隐含构建环境,并明确通过命令行选项设置.参见[Chapter 20,The Build Environment](https://docs.gradle.org/current/userguide/build_environment.html)有关如何指定和控制构建环境的详细信息. - -一下JVM系统属性是有效不变的.如果需求编译环境需要这些属性,不同的守护进程JVM在下列属性中有不同的值时,守护进程不兼容. - -+ file.encoding -+ user.language -+ user.country -+ user.variant -+ com.sun.management.jmxremote - -下列JVM属性,通过启动参数控制,也是有效不变的.在需求构建环境和守护进程环境的对应属性必须按顺序完全匹配,才可兼容. - -+ 最大堆大小(即 -Xmx JVM参数) -+ 最小堆大小(即 -Xms JVM参数) -+ 引导类路径(即 -Xbootclasspath JVM参数) -+ "assertion"状态(即 -ea 参数) - -所需的Gradle版本是需求构建环境的另一个方面.守护进程被耦合到特定Gradle运行时,多个正在运行的守护进程产生的原因是使用使用不同版本的Gradle会在会话过程中处理多个项目. - - - diff --git a/the_java_plugin/README.md b/the_java_plugin/README.md deleted file mode 100644 index e34318b..0000000 --- a/the_java_plugin/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 第 22 章 Java 插件 - -Java 插件给项目增加了编译, -测试以及打包的能力, -Gradle 的许多其他插件都需要以 Java 插件为基础. diff --git a/the_java_plugin/java_plugin_clean.md b/the_java_plugin/java_plugin_clean.md deleted file mode 100644 index 79d02ae..0000000 --- a/the_java_plugin/java_plugin_clean.md +++ /dev/null @@ -1,9 +0,0 @@ -## 22.9.Clean - -clean 任务是一个 [Delete](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Delete.html) 的实例. 它只是删除 dir 属性指定的目录. - -**表22.11.java 插件 - Clean 的属性** - -任务属性 | 类型 | 默认值 ----- | ---- | -------- -dir | File | buildDir diff --git a/the_java_plugin/java_plugin_compile_java.md b/the_java_plugin/java_plugin_compile_java.md deleted file mode 100644 index ab52559..0000000 --- a/the_java_plugin/java_plugin_compile_java.md +++ /dev/null @@ -1,12 +0,0 @@ -## 22.11.编译 java -java 插件为项目的每一个 source set 增加了一个 [JavaCompile](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html) 实例, 最常见的配置选项如下所示: - -**表22.13.java 插件-编译配置** - -任务属性 | 类型 | 默认值 --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- -classpath | [FileCollection](https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileCollection.html) | sourceSet.compileClasspath -source | [FileTree](https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileTree.html),可以在[Section 15.6, “Copying files”](https://docs.gradle.org/current/userguide/working_with_files.html#sec:copying_files)中查看可以设置什么. | sourceSet.java -destinationDir | File.| sourceSet.output.classesDir - -默认情况下 java 的编译运行在 Gradle 中的进程. 设置 option.fork 为 true 会使编译在一个单独的进程中运行,在Ant中运行 javac任务意味着一个新进程将被拆封为多个编译任务,这会减慢编译。相反的,Gradle的直接编译集成(见上文)在编译过程中将尽可能地重复使用相同的进程.在所有情况下由options.forkOptions指定的选项会被实现. diff --git a/the_java_plugin/java_plugin_compilejava.md b/the_java_plugin/java_plugin_compilejava.md deleted file mode 100644 index 3b87fe8..0000000 --- a/the_java_plugin/java_plugin_compilejava.md +++ /dev/null @@ -1 +0,0 @@ -# Java Plugin CompileJava diff --git a/the_java_plugin/java_plugin_convention_properties.md b/the_java_plugin/java_plugin_convention_properties.md deleted file mode 100644 index db13759..0000000 --- a/the_java_plugin/java_plugin_convention_properties.md +++ /dev/null @@ -1,34 +0,0 @@ -# 公共属性 - -Java 插件会为项目添加一系列的公共属性, 如下所示, 你可以在构建脚本中像项目属性那样直接使用它们 (see [???](https://docs.gradle.org/current/userguide/java_plugin.html)). - -**表22.7.Java插件-目录属性** - -属性名称 | 类型 | 默认值 | 描述 - ----- | ---- | ---- | ---- - reportsDirName | String | reports | 在构建目录的生成报告的文件夹名 - reportsDir | File (read-only) | buildDir/reportsDirName | 该目录下会生成报告 - testResultsDirName | String | test-results | 在构建目录的测试结果的result.xml的存放目录名 - testResultsDir | File (read-only) | buildDir/testResultsDirName | 测试结果的 result.xml 文件会存放在该文件夹中 - testReportDirName | String |tests | 在构建目录的测试报告的文件夹名 - testReportDir | File (read-only) | reportsDir/testReportDirName | 测试的测试报告会存放在该目录下 - libsDirName | String | libs | 在构建目录下的类库文件夹名 - libsDir | File (read-only) | buildDir/libsDirName | 该目录下存放类库 - distsDirName | String | distributions | 在构建目录下的distributions文件夹名 - distsDir | File (read-only) | buildDir/distsDirName | 该目录下存放生成的distributions - docsDirName | String | 在构建目录下的doc文件夹名 - docsDir | File (read-only) | buildDir/docsDirName | 该目录下存放生成的文档 - dependencyCacheDirName | String | dependency-cache | 在构建目录下的依赖缓存文件夹名 - dependencyCacheDir | File (read-only) | buildDir/dependencyCacheDirName | 该目录用来缓存源依赖信息。 - - **表22.8.Java插件-其他配置** - - 属性名称 | 类型 | 默认值 | 描述 - ----- | ---- | ---- | ---- - sourceSets | [SourceSetContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SourceSetContainer.html) | Not null | 包含项目的资源设置 - sourceCompatibility | [JavaVersion](https://docs.gradle.org/current/javadoc/org/gradle/api/JavaVersion.html).也可以使用String类型或Number类型,如'1.5' 或 1.5 | 当前使用的JVM版本 | 编译Java源码时所使用的Java兼容版本 - targetCompatibility | [JavaVersion](https://docs.gradle.org/current/javadoc/org/gradle/api/JavaVersion.html).也可以使用String类型或Number类型,如'1.5' 或 1.5 | sourceCompatibility | 生成class文件的Java版本 - archivesBaseName | String | projectName | 用于.jar文件或者.zip存档的基本名称 - manifest | [Mainfest](https://docs.gradle.org/current/javadoc/org/gradle/api/java/archives/Manifest.html) | an empty manifest | 该清单中包括所有的JAR文件 - - 按照[JavaPluginConvention](https://docs.gradle.org/current/dsl/org.gradle.api.plugins.JavaPluginConvention.html)和[BasePluginConvention](https://docs.gradle.org/current/dsl/org.gradle.api.plugins.BasePluginConvention.html)类型提供这些属性. diff --git a/the_java_plugin/java_plugin_defining_new_source_sets.md b/the_java_plugin/java_plugin_defining_new_source_sets.md deleted file mode 100644 index 7c5c0e2..0000000 --- a/the_java_plugin/java_plugin_defining_new_source_sets.md +++ /dev/null @@ -1,47 +0,0 @@ -### 22.7.2.定义一个新的 source set - -要定义一个新的源组, sourceSets {} 块中引用它.下面是一个例子: - -**例22.5.定义一个新的 source set** - -**build.gradle** - -``` -sourceSets { - intTest -} -``` - -当你定义一个新的 source set, java 插件会为该 source set 添加一些如[Table 22.6, "Java plugin - source set dependency configurations"](https://docs.gradle.org/current/userguide/java_plugin.html#java_source_set_configurations)中所示的依赖配置关系.可以使用这些配置来定义source set的编译和运行时依赖。 - -**例22.6.定义 source set 的依赖** - -**build.gradle** - -``` -sourceSets { - intTest -} - -dependencies { - intTestCompile 'junit:junit:4.12' - intTestRuntime 'org.ow2.asm:asm-all:4.0' -} -``` - -java 插件增加了一些如[Table 22.2, "Java plugin - source set tasks"](https://docs.gradle.org/current/userguide/java_plugin.html#java_source_set_tasks)为该source set组装classes文件的任务,例如,对于一个叫intTest的source set,为此source set编译classes任务运行`gradle intTestClasses`完成。 - -**例22.7.编译一个 source set** - -`gradle intTestClasses`命令的输出 - -``` -> gradle intTestClasses -:compileIntTestJava -:processIntTestResources -:intTestClasses - -BUILD SUCCESSFUL - -Total time: 1 secs -``` diff --git a/the_java_plugin/java_plugin_dependency_management.md b/the_java_plugin/java_plugin_dependency_management.md deleted file mode 100644 index b8488c8..0000000 --- a/the_java_plugin/java_plugin_dependency_management.md +++ /dev/null @@ -1,27 +0,0 @@ -# 依赖管理 - -Java 插件给项目增加了许多关于依赖的配置, 如下所示, 这些配置被分配给许多任务, 比如 compileJava 和 test 等配置 - -**表22.5.Java插件-依赖配置** - -名称 | 扩展 | 被使用时运行的任务 | 含义 ---------- | ---------- | ---- | ----------- -compile | - | compileJava | 编译时的依赖 -runtime | compile | - | 运行时的依赖 -testCompile | compile | compileTestJava | 编译测试所需的额外依赖 -testRuntime | runtime | test | 仅供运行测试的额外依赖 -archives | - | uploadArchives | 项目产生的信息单元(如:jar包) -default | runtime | - | 使用其他项目的默认依赖项,包括该项目产生的信息单元以及依赖 - -**图22.2.Java插件-依赖配置** -![java plugin-dependency configurations](https://docs.gradle.org/current/userguide/img/javaPluginConfigurations.png) - -对于每个添加到该项目的资源设置,java 插件会添加以下的依赖配置 - -**表22.6.Java插件-资源设置依赖关系配置** - -名称 | 扩展 | 被使用时运行的任务 | 含义 ---------- | ---------- | ---- | ----------- -sourceSetCompile | - | compileSourceSetJava | 编译时给定资源设置的依赖 -sourceSetRuntime | - | - |运行时给定资源设置的依赖 - diff --git a/the_java_plugin/java_plugin_incremental_java_compilation.md b/the_java_plugin/java_plugin_incremental_java_compilation.md deleted file mode 100644 index 3060619..0000000 --- a/the_java_plugin/java_plugin_incremental_java_compilation.md +++ /dev/null @@ -1,9 +0,0 @@ -## 22.12.增量Java编译 - -从Gradle2.1开始,可以使用Java增量编译,此功能正在孵化,参见[JavaCompile](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html)如何启用这个功能. 增量编译的主要目标如下: -- 避免在没必要编译的java编译资源上浪费时间.这意味着更快构建,尤其是在改变一些class与jar的时候,不需要再次编译那些不依赖这些class与jar的文件. -- 尽可能地少输出class.类不需要重新编译意味着保持输出目录不变。一个示例场景中,真正使用JRebel的真正有用的是 - 越少的输出类被改变,JVM可以使用越快刷新。 - -更高级的增量编译: -- 检测陈旧类的设置是否正确是以牺牲速度为代价的,该算法分析字节码并与编译器直接交互(非私有常量内联),依赖传递等.举个例子:当一个类的公共常量改变后,我们希望避免由编译器编译内联常数产生的问题,我们将调整算法和缓存以便增量Java编译可以是每编译任务的默认设置。 -- 为了使增量编译快,我们缓存会分析class的结果和jar快照。最初的增量编译应该会慢于cold caches. diff --git a/the_java_plugin/java_plugin_jar.md b/the_java_plugin/java_plugin_jar.md deleted file mode 100644 index bcaec2f..0000000 --- a/the_java_plugin/java_plugin_jar.md +++ /dev/null @@ -1,3 +0,0 @@ -## 22.14.Jar - -jar 任务创建包含项目的类文件和资源的 JAR 文件. JAR 文件在 archives 的依赖配置中是作为一个 artifact 的声明. 这意味着, JAR 是相关项目一个可用的 classpath. 如果您上传您的项目到存储库, 这个 JAR 会被声明为依赖描述符的一部分. 可以再[Section 15.8, “Creating archives”](https://docs.gradle.org/2.4/userguide/working_with_files.html#sec:archives)与[Chapter 51, Publishing artifacts](https://docs.gradle.org/2.4/userguide/artifact_management.html)中了解更多关于 JAR 与 archives 与 artifact configurations 协同工作的更多细节. diff --git a/the_java_plugin/java_plugin_javadoc.md b/the_java_plugin/java_plugin_javadoc.md deleted file mode 100644 index eb91a55..0000000 --- a/the_java_plugin/java_plugin_javadoc.md +++ /dev/null @@ -1,12 +0,0 @@ -## 22.8.Javadoc - -Javadoc task 是 [Javadoc](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html) 的一个实例. 它支持 Javadoc 的核心选项和可执行的 Javadoc 的 [reference documentation](http://download.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html#referenceguide) 中描述的标准 J avaTOC 的选项. 有关支持 Javadoc 选项的完整列表, 请参阅以下类的API文档:[CoreJavadocOptions](https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/CoreJavadocOptions.html) 和 [StandardJavadocDocletOptions](https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html). - -**表22.10.java 插件- javadoc 配置** - -任务属性 | 类型 | 默认值 --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- -classpath | [FileCollection](https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileCollection.html) | sourceSets.main.output + sourceSets.main.compileClasspath -source | [FileTree](https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileTree.html).可以设置为在[Section 15.5, “Specifying a set of input files”](https://docs.gradle.org/current/userguide/working_with_files.html#sec:specifying_multiple_files)中描述的任何值 | sourceSets.main.allJava -destinationDir | File | docsDir/javadoc -title | String | project 的 name 和 version diff --git a/the_java_plugin/java_plugin_manifest.md b/the_java_plugin/java_plugin_manifest.md deleted file mode 100644 index e0934ac..0000000 --- a/the_java_plugin/java_plugin_manifest.md +++ /dev/null @@ -1,61 +0,0 @@ -### 22.14.1.Manifest - -每个 jar 或 war 对象有一个 manifest 属性做为[Manifest](https://docs.gradle.org/2.4/javadoc/org/gradle/api/java/archives/Manifest.html)单独的实例, -当生成存档, 一个对应MANIFEST.MF文件被写入到档案中. - -**例22.15.MANIFEST.MF的定​​制** -**build.gradle** -``` -jar { - manifest { - attributes("Implementation-Title": "Gradle", - "Implementation-Version": version) - } -} -``` -你可以创建一个 manifest 的独立实例. -您可以使用如共享 jar 之间的 manifest 的信息. - -**例22.16.创建一个manifest对象** -**build.gradle** -``` -ext.sharedManifest = manifest { - attributes("Implementation-Title": "Gradle", - "Implementation-Version": version) -} -task fooJar(type: Jar) { - manifest = project.manifest { - from sharedManifest - } -} -``` -您可以合并其他 manifest 到任何 Manifest 对象. 其它清单可能是通过文件路径描述或着像上所述, 引用另一个Manifest对象. - -**例22.17.独立的MANIFEST.MF一个特定的归档** -**build.gradle** -``` -task barJar(type: Jar) { - manifest { - attributes key1: 'value1' - from sharedManifest, 'src/config/basemanifest.txt' - from('src/config/javabasemanifest.txt', - 'src/config/libbasemanifest.txt') { - eachEntry { details -> - if (details.baseValue != details.mergeValue) { - details.value = baseValue - } - if (details.key == 'foo') { - details.exclude() - } - } - } - } -} -``` -清单合并的顺序与声明语句的顺序相同,如果基本清单和合并的清单都为相同的密钥定义值,那么那么合并清单将会被合并,您可以通过添加在其中您可以使用一个[ManifestMergeDetails](https://docs.gradle.org/2.4/javadoc/org/gradle/api/java/archives/ManifestMergeDetails.html)实例为每个条目实体完全自定义的合并行为。声明不会立即被来自触发合并。这是延迟执行的,要么产生jar时,或要求写入effectiveManifest时. -你可以很容易地写一个清单到磁盘。 -**例22.17.独立的MANIFEST.MF一个特定的存档** -**build.gradle** -``` -jar.manifest.writeTo("$buildDir/mymanifest.mf") -``` diff --git a/the_java_plugin/java_plugin_project_layout.md b/the_java_plugin/java_plugin_project_layout.md deleted file mode 100644 index 12d5104..0000000 --- a/the_java_plugin/java_plugin_project_layout.md +++ /dev/null @@ -1,36 +0,0 @@ -# 项目布局 - -Java 插件的默认布局如下图所示, 无论这些文件夹中有没有内容, Java 插件都会编译里面的内容, 并处理任何缺失的内容. - -**表22.4.java 插件-默认布局** - -目录 | 含义 ---— | --- -src/main/java | 主要 Java 源码 -src/main/resources | 主要资源 -src/test/java | 测试 Java 源码 -src/test/resources | 测试资源 -src/sourceSet/java | 指定资源设置的 Java 源码 -src/sourceSet/resources | 指定资源设置的资源 - -### 1. 改变项目布局 - -可以通过配置适当的资源设置来配置项目布局, 更多细节会在后面的章节中讨论, 下面是一个配置了 java 和 resource 的简单的例子 - - -**例22.2.自定义 Java 源码布局** - -**build.gradle** - -``` -sourceSet{ - main{ - java{ - srcDir 'src/java' - } - resources{ - srcDir 'src/resources' - } - } -} -``` diff --git a/the_java_plugin/java_plugin_resources.md b/the_java_plugin/java_plugin_resources.md deleted file mode 100644 index 61f39cc..0000000 --- a/the_java_plugin/java_plugin_resources.md +++ /dev/null @@ -1,10 +0,0 @@ -## 22.10.资源 - -Java 插件使用 [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html) 任务处理资源. 它为项目每个 source set 都增加了一个实例. 可以参考[Section 15.6, "Copying files"](https://docs.gradle.org/current/userguide/working_with_files.html#sec:copying_files) 获取关于copy任务的信息. - -**表22.12.java 插件- ProcessResources 的属性** - -任务属性 | 类型 | 默认值 --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- -srcDirs | Object.可以在[Section 15.5, “Specifying a set of input files”](https://docs.gradle.org/current/userguide/working_with_files.html#sec:specifying_multiple_files)中查看使用什么 | sourceSet.resources -destinationDir | File.可以再[Section 15.1, “Locating files”](https://docs.gradle.org/current/userguide/working_with_files.html#sec:locating_files)查看使用什么 | sourceSet.output.resourcesDir diff --git a/the_java_plugin/java_plugin_source_set_properties.md b/the_java_plugin/java_plugin_source_set_properties.md deleted file mode 100644 index 01253cb..0000000 --- a/the_java_plugin/java_plugin_source_set_properties.md +++ /dev/null @@ -1,19 +0,0 @@ -### 22.7.1.Source Set 属性 -下表列出了 Source Set 的一些重要属性, 更多细节请查看 [SourceSet](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSet.html) 的 API 文档. - -**表22.9.java 插件- Source Set 属性** - -配置名称 | 类型 | 默认值 | 描述 -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------- -name | String (read-only) | Not null | 用来识别source set的名称 -output | [SourceSetOutput](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSetOutput.html)(read-only) | Not null | source set的输出文件,包含其编译的classes和resources -output.classesDir | File | buildDir/classes/name | 在该目录下生成存放这个source set的classes文件 -output.resourcesDir | File | buildDir/resources/name | 在该目录下生成存放这个source set的resources文件 -compileClasspath | [FileCollection](https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileCollection.html) | compileSourceSet configuration | 这个source set编译时使用的classpath -runtimeClasspath | [FileCollection](https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileCollection.html) | output + runtimeSourceSet configuration | 执行当前source set的classes文件时的classpath -java | [SourceDirectorySet](https://docs.gradle.org/current/javadoc/org/gradle/api/file/SourceDirectorySet.html)(read-only) | Not null | 当前source set的java源文件,仅包含存在于java目录下的所有.java文件,排除其他任何文件. -java.srcDirs | Set.可以设置为在[Section 15.5, “Specifying a set of input files”](https://docs.gradle.org/current/userguide/working_with_files.html#sec:specifying_multiple_files)中描述的任何值 | [projectDir/src/name/java] | 该source set的包含java源文件的目录 -resources | [SourceDirectorySet](https://docs.gradle.org/current/javadoc/org/gradle/api/file/SourceDirectorySet.html)(read-only) | Not null | 该source set的资源,只包含存在于resource目录吓得资源文件,会排除在resource下的所有.java文件,其他插件,如Groovy插件会在该集合中排除一些其他的文件. -resources.srcDirs | Set.可以设置为在[Section 15.5, “Specifying a set of input files”](https://docs.gradle.org/current/userguide/working_with_files.html#sec:specifying_multiple_files)中描述的任何值 | [projectDir/src/name/resources] | 该source set的包含资源文件的目录 -allJava | [SourceDirectorySet](https://docs.gradle.org/current/javadoc/org/gradle/api/file/SourceDirectorySet.html)(read-only) | java | 该source set的所有.java文件。一些插件,如Groovy插件,添加额外的Java源文件到这个集合。 -allSource | [SourceDirectorySet](https://docs.gradle.org/current/javadoc/org/gradle/api/file/SourceDirectorySet.html)(read-only) | resources + java | 该source set的所有源文件。这包括所有的资源文件和所有Java源文件。一些插件,如Groovy插件,添加额外的源文件到这个集合。 diff --git a/the_java_plugin/java_plugin_source_sets.md b/the_java_plugin/java_plugin_source_sets.md deleted file mode 100644 index bb75fc4..0000000 --- a/the_java_plugin/java_plugin_source_sets.md +++ /dev/null @@ -1,13 +0,0 @@ -# 资源设置 - -Java 插件引入了资源设置 (Source Set) 的概念, 资源设置就是一组被编译和执行在一起的源文件. -这些源文件可能包含 Java 的源文件以及一些资源文件. -其他的插件可能还会在资源设置中包含 Groovy 和 Scala 的源文件. 资源设置有一个与之关联的关于编译的 classpath 和有关运行的 classpath. - -资源设置的用法之一就是将源文件归档到描述它们目的的各个逻辑组, -举个例子, -你可以使用一个资源设置来定义一个集成测试套件 -也可以使用另外的资源设来定义你项目的 API 和实现类. - -Java 插件定义了两个标准资源设置, 分别称为`main`和`test`, `main`资源设置中包含最终面向客户的代码, 也就是编译和集成为一个 Jar 文件. -`test`资源设置包括了测试阶段的代码, 也就是使用 JUnit 或者 TestNG 编译和执行的代码. 它们可以是单元测试, 集成测试, 验收测试或者任何对你有用的测试集. diff --git a/the_java_plugin/java_plugin_tasks.md b/the_java_plugin/java_plugin_tasks.md deleted file mode 100644 index 2bca5ff..0000000 --- a/the_java_plugin/java_plugin_tasks.md +++ /dev/null @@ -1,51 +0,0 @@ -# 任务 - -Java 插件引入了许多任务到项目当中, 具体如下表所示 - -**表22.1 java 插件-任务** - -任务名 | 依赖 | 类型 | 描述 ---------- | ---------- | ---- | ----------- -compileJava | 所有产生编译 classpath 的任务,包括编译配置项目的所依赖的 jar 文件 | [JavaCompile](https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html) | 使用 javac 命令编译产生 java源文件 -processResources | - | [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html) | 复制生产资源到生产 class 文件目录 -classes | compileJava任务和processResources任务。有一些插件添加额外的编译任务 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 组装生产class文件目录 -compileTestJava | compile任务加上所有产生测试编译的classpath的任务 | [JavaCompile](https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html) | 使用 javac编译产生 java 测试源文件 -processTestResources | - | [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html) | 复制测试资源到测试 class 文件目录 -testClasses | compileTestJava 和 processTestResources 任务。一些插件会添加额外的测试编译任务 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 组装测试class文件目录 -jar | compile | [Jar](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html) | 组装 Jar 文件 -javadoc | compile | [javadoc](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html) | 使用 javadoc 命令为 Java 源码生产 API 文档 -test | compile,compileTest,加上所有产生 test runtime classp 的任务 | [Test](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html) | 使用 JUnit或者TestNG 进行单元测试 -uploadArchives | 在archives配置中产生信息单元的文件,包括了 jar | [Upload](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Upload.html) | 上传信息单元在archives配置中,包括 Jar 文件 -clean | - | [Delete](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Delete.html) | 删除项目构建目录 -clean*TaskName* | - | [Delete](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Delete.html) | 删除指定任务名所产生的项目构建目录,CleanJar会删除jar任务创建的jar 文件,cleanTest将会删除由 test 任务创建的测试结果 - -对于添加到项目中的每个资源设置, java 插件将会加入以下编译任务 - -**表22.2.java 插件-资源设置任务** - -任务名 | 依赖 | 类型 | 描述 ---------- | ---------- | ---- | ----------- -compile*SourceSet*Java | 产生资源设置编译 classpath 的所有任务 | [JavaCompile](https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html) | 使用 javac 命令编译给定资源设置的 Java 源文件 -processSourceSetResources | - | [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html) | 复制给定资源设置的资源到classes目录下。 -sourceSetClasses | compileSourceSetJava任务和processSourceSetResources任务。一些插件给资源设置添加额外的编译工作。 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 组装资源设置的class目录 - -Java 插件同时也增加了一些为项目生命周期服务的任务 - -**表22.3.java 插件-生命周期任务** - -任务名 | 依赖 | 类型 | 描述 ---------- | ---------- | ---- | ----------- -assemble | 项目中的所有归档任务,包括 jar 任务。一些插件给项目增加的额外归档任务 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 组装项目的所有档案 -check | 项目中的所有验证任务,包括 test 任务。一些插件给项目增加的额外验证任务 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 执行项目中的所有验证任务 -build | assemble任务和 check 任务 | | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 构建完整地项目 -buildNeeded | build 任务和buildNeeded 任务的testRuntime任务配置的所有项目的依赖库 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 构建完整地项目并且构建该项目依赖的所有项目 -buildDependents | build and buildDependents tasks in all projects with a project lib dependency on this project in a testRuntime configuration. | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 构建完整项目并且构建所有依赖该项目的项目 -buildConfigName | 产生由ConfigName配置的信息单元的任务。 | [Task](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html) | 根据指定的配置组装信息单元。这个任务是由 Java 插件隐式添加的基础插件添加的。 -uploadConfigName | 上传由ConfigName配置的信息单元的任务。 | [Upload](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Upload.html) | 根据指定的配置组装并上传信息单元。 -。这个任务是由 Java 插件隐式添加的基础插件添加的。 - -下图显示了这些任务之间的关系 - -**图22.1.java 插件-任务** - -![java plugin-tasks](https://docs.gradle.org/current/userguide/img/javaPluginTasks.png) diff --git a/the_java_plugin/java_plugin_test.md b/the_java_plugin/java_plugin_test.md deleted file mode 100644 index 49daff0..0000000 --- a/the_java_plugin/java_plugin_test.md +++ /dev/null @@ -1,3 +0,0 @@ -## 22.13.测试 - -test任务是[Test](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html)的一个实例.它会在测试source set自动检测并执行所有的单元测试,并且在测试执行完成后会生成一份测试报告.task任务支持JUnit和TestNG.在[Test](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html)查看完整地API. diff --git a/the_java_plugin/java_plugin_uploading.md b/the_java_plugin/java_plugin_uploading.md deleted file mode 100644 index 12f7ed7..0000000 --- a/the_java_plugin/java_plugin_uploading.md +++ /dev/null @@ -1,7 +0,0 @@ -## 22.15.上传 - -如何上传archives在[Chapter 51, Publishing artifacts](https://docs.gradle.org/2.4/userguide/artifact_management.html) -------- -[[9](https://docs.gradle.org/2.4/userguide/java_plugin.html#N12A26)]JUnit的维基包含有关如何使用JUnit类工作的详细说明:https://github.com/junit-team/junit/wiki/Categories. - -[[10](https://docs.gradle.org/2.4/userguide/java_plugin.html#N12A26)]TestNG的文档包含关于测试组的更多详细信息:http://testng.org/doc/documentation-main.html#test-groups. diff --git a/the_java_plugin/java_plugin_usage.md b/the_java_plugin/java_plugin_usage.md deleted file mode 100644 index 16d529f..0000000 --- a/the_java_plugin/java_plugin_usage.md +++ /dev/null @@ -1,12 +0,0 @@ -# 用法 - -要使用 Java 插件, -需要在构建脚本中加入如下内容 - -**例子 22.1.使用 Java 插件** - -**bulid.gradle** - -``` -apply plugin: 'java' -``` diff --git a/the_java_plugin/java_plugin_working_with_source_sets.md b/the_java_plugin/java_plugin_working_with_source_sets.md deleted file mode 100644 index 86503de..0000000 --- a/the_java_plugin/java_plugin_working_with_source_sets.md +++ /dev/null @@ -1,44 +0,0 @@ -# 使用资源设置 - -你可以通过 sourceSets 属性来使用资源设置. 它其实是一个项目资源设置的容器, 它的类型是 [SourceSetContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SourceSetContainer.html). 同时也有 sourceSets { } 脚本模块, 在这个模块里, 你可以通过闭包配置资源设置容器. 资源设置容器的工作方式和其余容器几乎一模一样, 比如 tasks. - -**例 22.3. 进入资源设置** - -**build.gradle** - -``` -// Various ways to access the main source set -println sourceSets.main.output.classesDir -println sourceSets['main'].output.classesDir -sourceSets { - println main.output.classesDir -} -sourceSets { - main { - println output.classesDir - } -} - -// Iterate over the source sets -sourceSets.all { - println name -} -``` - -为了配置一个已经存在的资源集, 你只需要使用上面提及的访问方法来设置资源集的属性. 下面就是一个配置 Java 资源目录的例子: - -**例 22.4. 配置资源集的源目录** - -**build.gradle** -``` -sourceSets { - main { - java { - srcDir 'src/java' - } - resources { - srcDir 'src/resources' - } - } -} -``` \ No newline at end of file diff --git a/the_java_plugin/java_plugins_some_source_set_examples.md b/the_java_plugin/java_plugins_some_source_set_examples.md deleted file mode 100644 index a237a4d..0000000 --- a/the_java_plugin/java_plugins_some_source_set_examples.md +++ /dev/null @@ -1,38 +0,0 @@ -### 22.7.3.一些 source set 的例子 - -加入含有类文件的 sorce set 的 JAR: - -**例22.8.为 source set 组装 JAR** - -**build.gradle** - -``` -task intTestJar(type: Jar) { - from sourceSets.intTest.output -} -``` - -为 source set 生成 javadoc: - -**例22.9.为 source set 生成 javadoc** - -**build.gradle** - -``` -task intTestJavadoc(type: Javadoc) { - source sourceSets.intTest.allJava -} -``` - -为 source set 添加一个测试套件运行测试: - -**例22.8.source set 运行测试** - -**build.gradle** - -```gradle -task intTest(type: Test) { - testClassesDir = sourceSets.intTest.output.classesDir - classpath = sourceSets.intTest.runtimeClasspath -} -``` diff --git a/the_java_plugin/test_convention_values.md b/the_java_plugin/test_convention_values.md deleted file mode 100644 index 7f61d84..0000000 --- a/the_java_plugin/test_convention_values.md +++ /dev/null @@ -1,10 +0,0 @@ -### 22.13.8.公共值 -**表22.14.Java插件-测试属性** - -任务属性 | 类型 | 默认值 --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- -testClassesDir | File | sourceSets.test.output.classesDir -classpath | [FileCollection](https://docs.gradle.org/2.4/javadoc/org/gradle/api/file/FileCollection.html) | sourceSets.test.runtimeClasspath -testResultsDir | File | testResultsDir -testReportDir | File | testReportDir -testSrcDirs | List | sourceSets.test.java.srcDirs diff --git a/the_java_plugin/test_debugging.md b/the_java_plugin/test_debugging.md deleted file mode 100644 index d3a069f..0000000 --- a/the_java_plugin/test_debugging.md +++ /dev/null @@ -1,4 +0,0 @@ -### 22.13.2.调试 -测试任务提供了[Test.getDebug()](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html#org.gradle.api.tasks.testing.Test:debug)属性,可使JVM等待调试器附加到5005端口后在进行调试. - -通过调用`--debug-JVM`任务选项,这也可以启用调试任务(since Gradle1.12)。 diff --git a/the_java_plugin/test_detection.md b/the_java_plugin/test_detection.md deleted file mode 100644 index 362a237..0000000 --- a/the_java_plugin/test_detection.md +++ /dev/null @@ -1,12 +0,0 @@ -### 22.13.5.测试检测 -测试任务检测哪些类是通过检查编译测试类的测试类。默认情况下它会扫描所有.calss文件.可以自定义包含/排除哪些类需不要要被扫描.所使用不同的测试框架(JUnit/ TestNG)时测试类检测使用不同的标准。 -当使用JUnit,我们扫描的JUnit3和JUnit4的测试类。如果任一下列条件匹配,类被认为是一个JUnit测试类: -* 类或父类集成自TestCase或GroovyTestCase -* 类或父类有@RunWith注解 -* 类或者父类中的方法有@Test注解 - -当使用TestNG的,我们扫描注解了@Test的方法。 - -需要注意的是抽象类不执行。Gradle还扫描了继承树插入测试classpath中的jar文件。 - -如果你不想使用测试类的检测,可以通过设置scanForTestClasses为false禁用它。这将使得测试任务只使用包含/排除找到测试类。如果scanForTestClasses是false而且额并没有包含/排除指定模式,"\*\*/\*Tests.class","\*\*/\*Test.class",与"\*\*/\*Abstract\*.class"分别为包含/排除的默认值. diff --git a/the_java_plugin/test_execution.md b/the_java_plugin/test_execution.md deleted file mode 100644 index a4274bc..0000000 --- a/the_java_plugin/test_execution.md +++ /dev/null @@ -1,12 +0,0 @@ -### 22.13.1.执行测试 -测试从main构建过程中分离出来的,运行在一个单独的JVM中执行.[Test](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html)任务允许控制这些如何发生. 有许多属性用于控制测试过程如何启动.这包括使用诸如系统属性,JVM参数和Java可执行文件。 - -可以指定是否要并行执行测试.Gradle通过同时运行多个测试进程提供并行执行测试.每个测试进程在同一时间只能执行一个测试,为了充分利用这一特性,一般不需要为tests任务做什么特别的设置,`maxParallelForks`属性指定测试进程在同一时间运行的最大进程数.默认值是1,意味着不执行并行测试. - -测试过程中设置org.gradle.test.worker系统属性为该测试过程的唯一标识符,例如,在文件名或其他资源标识符的唯一标识符。 - -你可以指定一些测试任务在已执行了一定数量的测试后重新运行.这可能是一个非常好的方式替代测试进程中的大量的堆.forkEvery属性指定测试类的在测试过程执行的最大数目。默认的是执行在各测设进程中不限数量的测试。 - -该任务有一个ignoreFailures属性来控制在测试失败时的行为。测试任务总是执行每一个检测试验.它停止构建之后,如果ignoreFailures是false,说明有失败的测试。ignoreFailures的默认值是false。 - -testLogging属性允许你配置哪个测试事件将被记录,并设置其log等级。默认情况下,将记录每一个失败的测试简明消息。详见[TestLoggingContainer](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.logging.TestLoggingContainer.html)如何按需求调整测试记录。 diff --git a/the_java_plugin/test_filtering.md b/the_java_plugin/test_filtering.md deleted file mode 100644 index ee3754b..0000000 --- a/the_java_plugin/test_filtering.md +++ /dev/null @@ -1,33 +0,0 @@ -### 22.13.3.测试过滤 -从Gradle1.10开始,可以根据测试任务名进行特点的任务测试,过滤与在构建脚本的段落中引入/排除测试任务(-Dtest.single, test.include and friends)是两种不同的机制.后者是基于文件,如测试实现类的物理位置.选择文件级的测试会不支持那些被测试等级过滤掉的一些有趣的测试脚本.下面的这些有些已经被实现,有些是将来会实现的: -- 过滤特定等级的试验方法;执行单个测试方法 -- 通配符"*"支持任意字符匹配 -- 命令行选项"--tests"用以设置测试过滤器.对经典的'执行单一测试方法'用例尤其有用.当使用命令行选项的时候,在构建脚本中声明的包含过滤器被忽略。 -- Gradle过滤测试框架API的限制.一些高级的综合性测试无法完全兼容测试过滤,但是,绝大多是测试和用例可以被熟练地处理. -- 测试过滤取代基于选择文件的测试,后者在未来可能会完全被取代.我们会完善测试过滤的API,并增加不同的过滤器 - -**例22.11.过滤测试的构建脚本吗** **build.gradle** - -``` -test{ - filter{ - //包括在测试的任何具体方法 - includeTestsMatching "*UiCheck" - - //包括所有包种的测试 - includeTestsMatching "org.gradle.internal.*" - - //包括所有的集成测试 - includeTestsMatching "*IntegTest" - } -} -``` - -要了解更多详细信息和示例,请参见[TestFilter](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/TestFilter.html)。 使用命令行选项的一些例子: -* gradle test --tests org.gradle.SomeTest.someSpecificFeature -* gradle test --tests \*SomeTest.someSpecificFeature -* gradle test --tests \*SomeSpecificTest -* gradle test --tests all.in.specific.package\* -* gradle test --tests \*IntegTest -* gradle test --tests \*IntegTest\*ui\* -* gradle someTestTask --tests \*UiTest someOtherTestTask --tests \*WebTest\*ui diff --git a/the_java_plugin/test_grouping.md b/the_java_plugin/test_grouping.md deleted file mode 100644 index ed18323..0000000 --- a/the_java_plugin/test_grouping.md +++ /dev/null @@ -1,28 +0,0 @@ -### 22.13.6.测试分组 -JUnit和TestNG允许为测试方法精密分组. - -对于分组JUnit的测试类与测试方法,JUnit4.8引入了类别的概念.[9](https://docs.gradle.org/current/userguide/java_plugin.html#ftn.N12A10)该测试任务允许您设定JUnit包括或者排除某些类的规范。 - -**例22.12.JUnit分类** -**build.gradle** -``` -test { - useJUnit { - includeCategories 'org.gradle.junit.CategoryA' - excludeCategories 'org.gradle.junit.CategoryB' - } -} -``` - -TestNG的框架有一个非常类似的概念。在TestNG的,你可以指定不同的测试组。 [[10](https://docs.gradle.org/current/userguide/java_plugin.html#ftn.N12A26)]测试分组应包括或排除在测试任务进行配置了的测试执行. - -**例22.13.TestNG分组测试** -**build.gradle** -``` -test { - useTestNG { - excludeGroups 'integrationTests' - includeGroups 'unitTests' - } -} -``` diff --git a/the_java_plugin/test_reporting.md b/the_java_plugin/test_reporting.md deleted file mode 100644 index 577c857..0000000 --- a/the_java_plugin/test_reporting.md +++ /dev/null @@ -1,25 +0,0 @@ -### 22.13.7.测试报告 -测试任务默认生成以下结果. -+ 一份HTML测试报告 -+ 一个与Ant的JUnit测试报告任务兼容的XML.这个格式与许多其他服务兼容,如CI serves -+ 结果是有效的二进制,测试任务会从这些二进制结果生成其他结果。 -有一个独立的[TestReport](https://docs.gradle.org/2.4/dsl/org.gradle.api.tasks.testing.TestReport.html)任务类型会根据一些Test任务实例生成的二进制源码生成一个HTML报告.使用这种测试类型,需要定义一个destinationDir,里面包括测试结果的报告.下面是一个示例,它产生一个从子项目的单元测试组合而成的报告: -**例22.14.创建单元测试报告子项目** -**build.gradle** -``` -subprojects { - apply plugin: 'java' - - // Disable the test report for the individual test task - test { - reports.html.enabled = false - } -} - -task testReport(type: TestReport) { - destinationDir = file("$buildDir/reports/allTests") - // Include the results from the `test` task in all subprojects - reportOn subprojects*.test -} -``` -应该注意的是,TestReport型组合来自多个测试任务的结果,需要聚集个别测试类的结果。这意味着,如果一个给定的测试类是由多个测试任务执行时,测试报告将会包括那些类,但是很难区分该输出结果分别是出自哪个类. diff --git a/the_java_plugin/test_single_test_execution_via_system_properties.md b/the_java_plugin/test_single_test_execution_via_system_properties.md deleted file mode 100644 index c852776..0000000 --- a/the_java_plugin/test_single_test_execution_via_system_properties.md +++ /dev/null @@ -1,12 +0,0 @@ -### 22.13.4.通过系统属性执行单独测试 -> 如上所述该机制已经被测试过滤取代 - -> **译者注:被取代的东西就先不翻译了** - -Setting a system property of taskName.single = testNamePattern will only execute tests that match the specified testNamePattern. The taskName can be a full multi-project path like “:sub1:sub2:test” or just the task name. The testNamePattern will be used to form an include pattern of “\*\*/testNamePattern\*.class”;. If no tests with this pattern can be found an exception is thrown. This is to shield you from false security. If tests of more than one subproject are executed, the pattern is applied to each subproject. An exception is thrown if no tests can be found for a particular subproject. In such a case you can use the path notation of the pattern, so that the pattern is applied only to the test task of a specific subproject. Alternatively you can specify the fully qualified task name to be executed. You can also specify multiple patterns. Examples: - -* gradle -Dtest.single=ThisUniquelyNamedTest test -* gradle -Dtest.single=a/b/ test -* gradle -DintegTest.single=\*IntegrationTest integTest -* gradle -Dtest.single=:proj1:test:Customer build -* gradle -DintegTest.single=c/d/ :proj1:integTest diff --git a/the_java_plugin/test_testNG_parameterized_methods_and_reporting.md b/the_java_plugin/test_testNG_parameterized_methods_and_reporting.md deleted file mode 100644 index 5370fd0..0000000 --- a/the_java_plugin/test_testNG_parameterized_methods_and_reporting.md +++ /dev/null @@ -1,3 +0,0 @@ -#### 22.13.7.1.TestNG 的参数化方法和报告 -TestNG支持[参数化方法](http://testng.org/doc/documentation-main.html#parameters),允许一个特定的测试方法使用不同的输入被执行多次。Gradle会在测试报告中包含该方法的参数值. -给出一个叫aTestMethod的测试方法,该方法有两个参数,在测试报告中会根据名字报告:aTestMethod(toStringValueOfParam1, toStringValueOfParam2). 这很容易识别的参数值的特定迭代. diff --git a/the_war_plugin/convention_properties.md b/the_war_plugin/convention_properties.md deleted file mode 100644 index 79556c4..0000000 --- a/the_war_plugin/convention_properties.md +++ /dev/null @@ -1,10 +0,0 @@ -# 公共配置 - -**表25.4.War插件-目录配置** - -属性名称 | 类型 | 默认值 | 描述 - ----- | ---- | ---- | ---- - webAppDirName | String | src/main/webapp | 在项目目录的web应用的资源文件夹名 - webAppDir | File (read-only) | projectDir/webAppDirName | Web应用的资源路径 - - 这些属性由一个[WarPluginConvention](https://docs.gradle.org/current/dsl/org.gradle.api.plugins.WarPluginConvention.html)公共对象提供 diff --git a/the_war_plugin/customizing.md b/the_war_plugin/customizing.md deleted file mode 100644 index 93b2910..0000000 --- a/the_war_plugin/customizing.md +++ /dev/null @@ -1,43 +0,0 @@ -# 定制War - -下面的例子中有一些重要的自定义选项 - -**例25.2.定制War插件** - -**build.gradle** - -``` -configuration{ - moreLibs -} - -respositories{ - faltDir {dirs "lib"} - mavenCentral() -} - -dependencies{ - compile module(":compile:1.0") { - dependency ":compile-transitive-1.0@jar" - dependency ":providedCompile-transitive:1.0@jar" - } - providedCompile "javax.servlet:servlet-api:2.5" - providedCompile module(":providedCompile:1.0") { - dependency ":providedCompile-transitive:1.0@jar" - } - runtime ":runtime:1.0" - providedRuntime ":providedRuntime:1.0@jar" - testCompile "junit:junit:4.12" - moreLibs ":otherLib:1.0" -} - -war{ - from 'src/rootContent' // 增加一个目录到归档根目录 - webInf {from 'src/additionalWebInf'} // 增加一个目录到 WEB-INF 下 - classpath fileTree('additionalLibs') // 增加一个目录到 WEB-INF/lib下. - classpath configurations.moreLibs // 增加更多地设置到 WEB-INF/lib 下. - webXml = file('src/someWeb.xml') // 复制xml文件到 WEB-INF/web.xml. -} -``` - -当然,可以用一个封闭的标签定义一个文件是否存打包到War文件中. diff --git a/the_war_plugin/dependency_management.md b/the_war_plugin/dependency_management.md deleted file mode 100644 index 5970241..0000000 --- a/the_war_plugin/dependency_management.md +++ /dev/null @@ -1,3 +0,0 @@ -# 依赖管理 - -War插件增加了名为providedCompile和providedRuntime的两个依赖配置.这两个配置有相同的作用域在编译或者运行时的配置,不同之处在于是否会将war文件归档.很重要的一点是它们都会提供配置传递.比如在任意的provided配置中添加了`commons-httpclient:commons-httpclient:3.0`,该依赖依赖于`commons-codec`,因为这个一个"provided"的配置,意味着这两个依赖都不会被加入你的WAR中,即使`commons-codec`库是一个显式的编译配置.如果不希望出现这种传递行为,`commons-httpclient:commons-httpclient:3.0@jar`这样声明provided依赖即可. diff --git a/the_war_plugin/project_layout.md b/the_war_plugin/project_layout.md deleted file mode 100644 index 04ed57a..0000000 --- a/the_war_plugin/project_layout.md +++ /dev/null @@ -1,7 +0,0 @@ -# 项目布局 - -**表25.3.War插件-项目布局** - -文件夹 | 含义 --------- | ------ -src/main/webapp | Web应用资源 diff --git a/the_war_plugin/tasks.md b/the_war_plugin/tasks.md deleted file mode 100644 index f873a47..0000000 --- a/the_war_plugin/tasks.md +++ /dev/null @@ -1,23 +0,0 @@ -# 任务 -<<<<<<< HEAD -======= - -War插件会添加下列任务到项目. - -**表25.1.War插件-任务** - -任务名 | 依赖 | 类型 | 描述 ---------- | ---------- | ---- | ----------- -war | compile | [War](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.War.html) | 组装应用程序War文件 - -War插件由Java插件添加下列依赖任务. - -**表25.2.War插件-附加的依赖任务** - -任务名 | 依赖 --------- | ------ -assemble | war - -**图25.1.War插件-任务** -![war plugin-tasks](https://docs.gradle.org/current/userguide/img/warPluginTasks.png) ->>>>>>> a655fa4be4421004591827ae70fee579703794dd diff --git a/the_war_plugin/the_war_plugin.md b/the_war_plugin/the_war_plugin.md deleted file mode 100644 index e6badcc..0000000 --- a/the_war_plugin/the_war_plugin.md +++ /dev/null @@ -1,106 +0,0 @@ -# War 插件 (未完成) - -WAR插件扩展了Java插件,支持web应用组装成War文件.它默认禁用了Java插件JAR归档任务,并增加了一个默认的WAR归档任务。 - -## 25.1.使用 -使用war插件需要在构建脚本下包括以下内容 - -**例25.1.使用war插件** - -**build.gradle** - -``` -apply plugin 'war' -``` - -## 25.2.任务 -War插件会添加下列任务到项目. - -**表25.1.War插件-任务** - -任务名 | 依赖 | 类型 | 描述 ---------- | ---------- | ---- | ----------- -war | compile | [War](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.War.html) | 组装应用程序War文件 - -War插件由Java插件添加下列依赖任务. - -**表25.2.War插件-附加的依赖任务** - -任务名 | 依赖 --------- | ------ -assemble | war - -**图25.1.War插件-任务** -![war plugin-tasks](https://docs.gradle.org/current/userguide/img/warPluginTasks.png) - -## 25.3.项目布局 - -**表25.3.War插件-项目布局** -文件夹 | 含义 --------- | ------ -src/main/webapp | Web应用资源 - -## 25.4.依赖管理 -War插件增加了名为providedCompile和providedRuntime的两个依赖配置.这两个配置有相同的作用域在编译或者运行时的配置,不同之处在于是否会将war文件归档.很重要的一点是它们都会提供配置传递.比如在任意的provided配置中添加了`commons-httpclient:commons-httpclient:3.0`,该依赖依赖于`commons-codec`,因为这个一个"provided"的配置,意味着这两个依赖都不会被加入你的WAR中,即使`commons-codec`库是一个显式的编译配置.如果不希望出现这种传递行为,`commons-httpclient:commons-httpclient:3.0@jar`这样声明provided依赖即可. - -## 25.5.公共配置 - -**表25.4.War插件-目录配置** - -属性名称 | 类型 | 默认值 | 描述 - ----- | ---- | ---- | ---- - webAppDirName | String | src/main/webapp | 在项目目录的web应用的资源文件夹名 - webAppDir | File (read-only) | projectDir/webAppDirName | Web应用的资源路径 - - 这些属性由一个[WarPluginConvention](https://docs.gradle.org/current/dsl/org.gradle.api.plugins.WarPluginConvention.html)公共对象提供 - -## 25.6.War -War任务默认会把`src/main/webapp`的内容复制到归档目录的根目录.webapp文件夹下会包含一个`WEB-INF`子文件夹,里面可能会有一个web.xml文件.编译后的class文件会在`WEB-INF/classes`下,所有runtime[[13](https://docs.gradle.org/current/userguide/war_plugin.html#ftn.N1325D)]的依赖配置会被拷贝至`WEB-INF/lib`下. - -API文档中有更多关于[War](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.War.html)的信息. - -## 25.7.定制War -下面的例子中有一些重要的自定义选项 - -**例25.2.定制War插件** - -**build.gradle** - -``` -configuration{ - moreLibs -} - -respositories{ - faltDir {dirs "lib"} - mavenCentral() -} - -dependencies{ - compile module(":compile:1.0") { - dependency ":compile-transitive-1.0@jar" - dependency ":providedCompile-transitive:1.0@jar" - } - providedCompile "javax.servlet:servlet-api:2.5" - providedCompile module(":providedCompile:1.0") { - dependency ":providedCompile-transitive:1.0@jar" - } - runtime ":runtime:1.0" - providedRuntime ":providedRuntime:1.0@jar" - testCompile "junit:junit:4.12" - moreLibs ":otherLib:1.0" -} - -war{ - from 'src/rootContent' // 增加一个目录到归档根目录 - webInf {from 'src/additionalWebInf'} // 增加一个目录到 WEB-INF 下 - classpath fileTree('additionalLibs') // 增加一个目录到 WEB-INF/lib下. - classpath configurations.moreLibs // 增加更多地设置到 WEB-INF/lib 下. - webXml = file('src/someWeb.xml') // 复制xml文件到 WEB-INF/web.xml. -} -``` - -当然,可以用一个封闭的标签定义一个文件是否存打包到War文件中. - ---- -[[13](https://docs.gradle.org/current/userguide/war_plugin.html#N1325D)]`runtime`配置将会继承`compile`配置. diff --git a/the_war_plugin/usage.md b/the_war_plugin/usage.md deleted file mode 100644 index fef6d21..0000000 --- a/the_war_plugin/usage.md +++ /dev/null @@ -1,14 +0,0 @@ -# 使用 -<<<<<<< HEAD -======= - -使用war插件需要在构建脚本下包括以下内容 - -**例25.1.使用war插件** - -**build.gradle** - -``` -apply plugin 'war' -``` ->>>>>>> a655fa4be4421004591827ae70fee579703794dd diff --git a/the_war_plugin/war.md b/the_war_plugin/war.md deleted file mode 100644 index 771285f..0000000 --- a/the_war_plugin/war.md +++ /dev/null @@ -1,8 +0,0 @@ -# War - -War任务默认会把`src/main/webapp`的内容复制到归档目录的根目录.webapp文件夹下会包含一个`WEB-INF`子文件夹,里面可能会有一个web.xml文件.编译后的class文件会在`WEB-INF/classes`下,所有runtime[[13](https://docs.gradle.org/current/userguide/war_plugin.html#ftn.N1325D)]的依赖配置会被拷贝至`WEB-INF/lib`下. - -API文档中有更多关于[War](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.War.html)的信息. - ---- -[[13](https://docs.gradle.org/current/userguide/war_plugin.html#N1325D)]`runtime`配置扩展了`compile`配置. diff --git a/troubleshooting/README.md b/troubleshooting/README.md deleted file mode 100644 index 9394c4a..0000000 --- a/troubleshooting/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# 排除故障 - -当使用 Gradle 时, 你肯定会碰到许多问题. - -# 解决遇到的问题 - -如果你碰到了问题, 首先要确定你使用的是最新版本的 Gradle. 我们会经常发布新版本, 解决一些 bug 并加入新的功能. 所以你遇到的问题可能就在新版本里解决了. - -如果你正在使用 Gradle Daemon, 先暂时关闭 daemon (你可以使用 **switch --no-daemon** 命令). 在第19章我们可以了解到更多关于 daemon 的信息. - -# 获得帮助 - -可以浏览 http://forums.gradle.org 获得相关的帮助. 在 Gradle 论坛里, 你可以提交问题, 当然也可以回答其他 Gradle 开发人员和使用者的问题. - -如果你碰到不能解决的问题, 请在论坛里报告或者提出这个问题, 通常这是解决问题最快的方法. 你也可以提出建议或者一些新的想法. 通过论坛, 你当然也可以获得 Gradle 最新的开发信息. - - - - - diff --git a/troubleshooting/getting_help.md b/troubleshooting/getting_help.md deleted file mode 100644 index 0ac9523..0000000 --- a/troubleshooting/getting_help.md +++ /dev/null @@ -1,5 +0,0 @@ -# 获得帮助 - -可以去 http://forums.gradle.org 获得相关的帮助. 在 Gradle 论坛里, 你可以提交问题, 当然也可以回答其他 Gradle 开发人员和使用者的问题. - -如果你碰到不能解决的问题, 请在论坛里报告或者提出这个问题, 通常这是解决问题最快的方法. 您也可以提出建议或者一些新的想法. 开发团队会经常性的发布新的东西或者发布通知, 通过论坛, 您可以获得 Gradle 最新的开发信息. diff --git a/troubleshooting/working_through_problems.md b/troubleshooting/working_through_problems.md deleted file mode 100644 index 352225e..0000000 --- a/troubleshooting/working_through_problems.md +++ /dev/null @@ -1,7 +0,0 @@ -# 解决遇到的问题 - -如果你碰到了问题, 首先要确定你使用的是最新版本的 Gradle. 我们会经常发布新版本, 解决一些 bug 并加入新的功能. 所以你遇到的问题可能就在新版本里解决了. - -如果你正在使用 Gradle Daemon, 先暂时关闭 daemon (你可以使用 **switch --no-daemon** 命令). 在第19章我们可以了解到更多关于 daemon 的信息. - - diff --git a/tutorial_-_this_and_that/caching.md b/tutorial_-_this_and_that/caching.md deleted file mode 100644 index e529b27..0000000 --- a/tutorial_-_this_and_that/caching.md +++ /dev/null @@ -1,3 +0,0 @@ -# 缓存 - -为了提高响应能力,Gradle 默认缓存了所有编译后的脚本. 包括所有的构建脚本,初始化脚本,还有其他脚本. Gradle 创建了一个 .gradle 目录来存放编译后的脚本,下次您运行构建脚本时,如果这个脚本自从它被编译后就再也没有被改动过,Gradle 会先使用编译后的脚本. 否则 Gradle 会重新编译脚本,然后将新编译后的文件缓存起来. 如果您使用 Gradle --recompile--scripts 运行脚本,缓存的脚本就会被删除,然后新编译后的文件就会再被缓存. 这种方法可以强制 Gradle 重新编译脚本并缓存. diff --git a/tutorials/README.md b/tutorials/README.md deleted file mode 100644 index 994c6e6..0000000 --- a/tutorials/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# 教程 - -接下来的教程讲先介绍Gradle的基础知识 - -#### Chapter 4, 安装 Gradle - -描述如何安装 Gradle. - -#### Chapter 5, 脚本构建基础 - -介绍脚本构建的基础元素: projects 和 tasks. - -#### Chapter 6, Java 快速入门 - -展示如何使用 Gradle 来构建 Java 项目. - -#### Chapter 7, 依赖管理基础 - -展示如何使用 Gradle 的依赖管理功能. - -#### Chapter 8, Groovy 快速入门 - -展示如何使用 Gradle 来构建 Groovy 项目. - -#### Chapter 9, 网页应用快速入门 - -展示如何使用 Gradle 来构建网页应用项目. - -#### Chapter 10, 使用 Gradle 命令行 - diff --git a/tutorials/getting_started.md b/tutorials/getting_started.md deleted file mode 100644 index 17c0595..0000000 --- a/tutorials/getting_started.md +++ /dev/null @@ -1,28 +0,0 @@ -# 入门 - -接下来的教程讲先介绍Gradle的基础知识 - -#### Chapter 3, 安装 Gradle - -描述如何安装 Gradle. - -#### Chapter 5, 脚本构建基础 - -介绍脚本构建的基础元素: projects 和 tasks. - -#### Chapter 6, Java 快速入门 - -展示如何开始使用 Gradle 的合约构建来构建 Java 项目. - -#### Chapter 7, 依赖管理基础 - -展示如何开始使用 Gradle 的依赖管理. - -#### Chapter 8, Groovy 快速入门 - -使用 Gradle 的合约构建来构建 Groovy 项目. - -#### Chapter 9, 网页应用快速入门 - -使用 Gradle 的合约构建来构建网页应用项目. - diff --git a/using_ant_from_gradle/API.md b/using_ant_from_gradle/API.md deleted file mode 100644 index 3cdc110..0000000 --- a/using_ant_from_gradle/API.md +++ /dev/null @@ -1,3 +0,0 @@ -## API - -Ant 集成是由 [AntBuilder](https://docs.gradle.org/current/javadoc/org/gradle/api/AntBuilder.html) 提供的.git diff --git a/using_ant_from_gradle/ant_properties_and_references.md b/using_ant_from_gradle/ant_properties_and_references.md deleted file mode 100644 index 64e0b31..0000000 --- a/using_ant_from_gradle/ant_properties_and_references.md +++ /dev/null @@ -1,61 +0,0 @@ -## Ant的属性与引用 - -有许多方法可以设定 Ant 属性,可以通过Ant任务使用属性.您可以直接在`AntBuilder`的实例设置属性。Ant的属性也可以作为一个可改变的`Map`.也可以使用Ant的任务属性,如下例所示: - -**例16.13.设置Ant属性** - -**build.gradle** -```gradle -ant.buildDir = buildDir -ant.properties.buildDir = buildDir -ant.properties['buildDir'] = buildDir -ant.property(name: 'buildDir', location: buildDir) -``` -**build.xml** -```xml -buildDir = ${buildDir} -``` - -许多任务会在执行时设置属性.下面有几种方法来获取属性值,可以直接从`AntBuilder`实例获得属性,如下所示,ant的属性仍然是作为一个map: - -**例16.14.获取Ant属性** - -**build.xml** -```xml - -``` -**build.gradle** -```gradle -println ant.antProp -println ant.properties.antProp -println ant.properties['antProp'] -``` - -设置一个ant引用的方法: - -**例16.15.设置一个Ant引用** - -**build.gradle** -```gradle -ant.path(id: 'classpath', location: 'libs') -ant.references.classpath = ant.path(location: 'libs') -ant.references['classpath'] = ant.path(location: 'libs') -``` -**build.xml** -```xml - -``` - -获取Ant引用的方法: - -**例16.16.获取一个Ant引用** - -**build.xml** -```xml - -``` -**build.gradle** -```gradle -println ant.references.antPath -println ant.references['antPath'] -``` diff --git a/using_ant_from_gradle/importing_an_ant_build.md b/using_ant_from_gradle/importing_an_ant_build.md deleted file mode 100644 index 6991f5b..0000000 --- a/using_ant_from_gradle/importing_an_ant_build.md +++ /dev/null @@ -1,139 +0,0 @@ -## 导入一个Ant构建 - -你可以在你的gradle项目中通过`ant.importBuild()`来导入一个ant构建,当你导入了一个ant构建,每一个`ant target`都会被视为一个Gradle任务.这意味着你可以像操作,执行gradle任务一样操作,执行`ant target` - -**例 16.8.导入ant构建** - -**build.gradle** -```gradle -ant.importBuild 'build.xml' -``` -**build.xml** -```xml - - - Hello, from Ant - - -``` - -`gradle hello`的输出 - -``` ->\> gradle hello ->:hello ->[ant:echo] Hello, from Ant -> ->BUILD SUCCESSFUL -> ->Total time: 1 secs -``` - -你可以添加一个依赖于`ant target`的任务: -**例 16.9.依赖于ant target的任务** - -**build.gradle** -```gradle -ant.importBuild 'build.xml' - -task intro(dependsOn: hello) << { - println 'Hello, from Gradle' -} -``` - ->`gradle intro`的输出 ->\> gradle intro ->:hello ->[ant:echo] Hello, from Ant ->:intro ->Hello, from Gradle -> ->BUILD SUCCESSFUL -> ->Total time: 1 secs - -或者,你可以为`ant target`添加动作 - -**例 16.10.为Ant target添加动作** - -**build.gradle** -```gradle -ant.importBuild 'build.xml' - -hello << { - println 'Hello, from Gradle' -} -``` - -`gradle hello`的输出 ->\> gradle hello ->:hello ->[ant:echo] Hello, from Ant ->Hello, from Gradle -> ->BUILD SUCCESSFUL -> ->Total time: 1 secs - -当然,一个`ant target`也可以依赖于gradle的任务 - -**例 16.11.为Ant target添加动作** - -**build.gradle** -```gradle -ant.importBuild 'build.xml' - -task intro << { - println 'Hello, from Gradle' -} -``` -**build.xml** -```xml - - - Hello, from Ant - - -``` - -`gradle hello`的输出 ->\> gradle hello ->:intro ->Hello, from Gradle ->:hello ->[ant:echo] Hello, from Ant -> ->BUILD SUCCESSFUL -> ->Total time: 1 secs - -有时候可能需要'重命名'`ant target`以避免与现有的gradle任务冲突.需要使用[AntBuilder.importBuilder()](https://docs.gradle.org/current/javadoc/org/gradle/api/AntBuilder.html#importBuild(java.lang.Object, org.gradle.api.Transformer))方法. - -**例 16.12.重命名导入的ant target** - -**build.gradle** -```gradle -ant.importBuild('build.xml') { antTargetName -> - 'a-' + antTargetName -} -``` -**build.xml** -```xml - - - Hello, from Ant - - -``` - -`gradle a-hello`的输出 ->\> gradle a-hello ->:a-hello ->[ant:echo] Hello, from Ant -> ->BUILD SUCCESSFUL -> ->Total time: 1 secs - -注意,方法的二个参数应该是一个[TransFormer](https://docs.gradle.org/current/javadoc/org/gradle/api/Transformer.html),在Groovy编程的时候,由于[Groovy的支持自动闭包单抽象方法的类型](http://mrhaki.blogspot.ie/2013/11/groovy-goodness-implicit-closure.html)。我们可以简单地使用闭包取代匿名内部类, - diff --git a/using_ant_from_gradle/using_ant_from_gradle.md b/using_ant_from_gradle/using_ant_from_gradle.md deleted file mode 100644 index 03cbfaa..0000000 --- a/using_ant_from_gradle/using_ant_from_gradle.md +++ /dev/null @@ -1,11 +0,0 @@ -## 在 Gradle中使用Ant - -Gradle 出色的集成了 Ant. 你可以在 Gradle 构建时使用单独的 Ant 任务或完整的 Ant 构建. 事实上, 你会发现在 Gradle 构建脚本中使用Ant任务远比直接使用 Ant 的 XML 格式更加容易和强大. 你甚至可以将 Gradle 仅仅作为一个强大的 Ant 脚本工具. - -Ant 可以分为两层. 第一层是 Ant 语言. 它给 build.xml 文件, 处理目标, 像 macrodefs 的特殊构造等提供语法支持. 换句话说, 除了 Ant 任务和类型, 其余一切都支持. Gradle 了解这种语言, 并允许用户直接导入 Ant 的 build.xml 到 Gradle 的项目下. 然后, 你可以 像 Gradle 任务一样直接使用这些 Ant 构建. - -第二层是 Ant 丰富的任务和类型, 如 javac, copy 或 jar. Gradle 提供了基于 Groovy 的集成以及梦幻般的 AntBuilder. - -最后,由于构建脚本是 Groovy 脚本, 你总是可以执行一个 Ant 构建作为一个外部进程. 构建脚本可能会含有类似的语句:“ant clean compile”.execute().[[7](https://docs.gradle.org/current/userguide/ant.html#ftn.N1135F)] - -你可以使用 Gradle 的 Ant 集成,作为迁移路径将构建 Ant 迁移到 Gradle. 例如, 你可以从通过导入现有的 Ant 构建开始, 然后将你的依赖声明从 Ant 脚本迁移到你的 build 文件. 最后, 你可以将任务迁移到你的构建文件, 或者用一些 Gradle 插件代替他们. 随着时间的推移, 这部分工作会一步一步地完成, 并且你可以在整个进程中有一个运行良好的 Gradle 构建. diff --git a/using_ant_from_gradle/using_ant_tasks_and_types_in_your_build.md b/using_ant_from_gradle/using_ant_tasks_and_types_in_your_build.md deleted file mode 100644 index 07073a2..0000000 --- a/using_ant_from_gradle/using_ant_tasks_and_types_in_your_build.md +++ /dev/null @@ -1,62 +0,0 @@ -## 16.1.使用 Ant 任务和 Ant 类型的构建 - -在构建脚本中, Ant 属性是由 Gradle提供的. 这是一个用于参考的 [AntBuilder](https://docs.gradle.org/current/javadoc/org/gradle/api/AntBuilder.html) 实例. AntBuilder 用于从构建脚本访问 Ant 任务, 类型和属性. 下面的例子解释了从 Ant 的 `build.xml` 格式到 Grooy 的映射. - -你可以通过调用 AntBuilder 实例的方法执行 Ant 任务. 你可以使用任务名称作为方法名, 比如, 可以通过调用 `anto.echo()` 任务执行 Ant `echo` 任务. Ant 任务属性通过 Map 参数传递给方法. 下面是一个 `echo` 任务的例子, 注意我们也可以混合使用 Groovy 代码和 Ant 任务标记, 这点个功能非常强大. - -**例 16.1.使用 Ant 任务** - -**build.gradle** - -```gradle -task hello << { - String greeting = 'hello from Ant' - ant.echo(message: greeting) -} -``` - -`gradle hello` 的输出 -``` ->\> gradle hello ->:hello ->[ant:echo] hello from Ant -> ->BUILD SUCCESSFUL -> ->Total time: 1 secs -``` - -你可以添加嵌套元素添加到一个封闭的 Ant 任务的内部. 定义嵌套元素跟定义任务的方式相同, 通过与调用我们要定义的元素名相同的方法. - -**例 16.3.添加嵌套元素到一个Ant任务** - -**build.gradle** -```gradle -task zip << { - ant.zip(destfile: 'archive.zip') { - fileset(dir: 'src') { - include(name: '**.xml') - exclude(name: '**.java') - } - } -} -``` - -你可以像访问任务一样访问 Ant type,只需要将 type 名作为方法名即可. 该方法调用返回的 Ant 数据类型,可以直接在构建脚本中使用.下面的例子中,我们创建了一个`ant path`对象,然后遍历他的内容. - -**例 16.4.使用 Ant 类型** - -**build.gradle** -```gradle -task list << { - def path = ant.path { - fileset(dir: 'libs', includes: '*.jar') - } - path.list().each { - println it - } -} -``` - -更多关于 AntBuilder 的信息可以参考 'Groovy in Action'8.4 或者[Groovy Wiki](http://groovy.codehaus.org/Using+Ant+from+Groovy). - diff --git a/using_ant_from_gradle/using_custom_ant_tasks_in_your_build.md b/using_ant_from_gradle/using_custom_ant_tasks_in_your_build.md deleted file mode 100644 index 9aedf7c..0000000 --- a/using_ant_from_gradle/using_custom_ant_tasks_in_your_build.md +++ /dev/null @@ -1,54 +0,0 @@ -## 在构建中使用自定义Ant任务 - -为了让你的构建可以自定义任务, 你可以使用 `taskdef(通常更容易)` 或者 `typedef` Ant 任务, 就像你在一个`build.xml`文件中一样. 然后,你可以参考内置 Ant 任务去定制 Ant 任务. - -**例 16.5.使用自定义 Ant 任务** - -**build.gradle** -```gradle -task check << { - ant.taskdef(resource: 'checkstyletask.properties') { - classpath { - fileset(dir: 'libs', includes: '*.jar') - } - } - ant.checkstyle(config: 'checkstyle.xml') { - fileset(dir: 'src') - } -} -``` - -你可以使用 Gradle 的依赖管理去组装你自定义任务所需要的 classpath. 要做到这一点, 你需要定义一个自定义配置类路径, 然后添加一些依赖配置.在[Section 51.4, “How to declare your dependencies”](https://docs.gradle.org/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies)部分有更详细的说明. - -**例 16.6.声明类路径的自定义 Ant 任务** - -**build.gradle** -```gradle -configurations { - pmd -} - -dependencies { - pmd group: 'pmd', name: 'pmd', version: '4.2.5' -} -``` - -要使用 classpath 配置, 使用自定义配置的`asPath`属性。 - -**例 16.7.一起使用自定义Ant任务和依赖管理** - -**build.gradle** - -```gradle -task check << { - ant.taskdef(name: 'pmd', - classname: 'net.sourceforge.pmd.ant.PMDTask', - classpath: configurations.pmd.asPath) - ant.pmd(shortFilenames: 'true', - failonruleviolation: 'true', - rulesetfiles: file('pmd-rules.xml').toURI().toString()) { - formatter(type: 'text', toConsole: 'true') - fileset(dir: 'src') - } -} -``` diff --git a/using_the_gradle_command-line/README.md b/using_the_gradle_command-line/README.md deleted file mode 100644 index 8d1610a..0000000 --- a/using_the_gradle_command-line/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# 使用 Gradle 命令行 - -本章介绍了命令行的一些基本功能.正如在前面的章节里你所见到的调用 **gradle** 命令来运行一个构建. diff --git a/using_the_gradle_command-line/continuing_the_build_when_a_failure_occurs.md b/using_the_gradle_command-line/continuing_the_build_when_a_failure_occurs.md deleted file mode 100644 index 6b2cc47..0000000 --- a/using_the_gradle_command-line/continuing_the_build_when_a_failure_occurs.md +++ /dev/null @@ -1,11 +0,0 @@ -# 失败后继续执行构建 - -默认情况下, 只要有任务调用失败, Gradle就会中断执行. 这可能会使调用过程更快, 但那些后面隐藏的错误就没有办法发现了. 所以你可以使用 `--continue` 选项在一次调用中尽可能多的发现所有问题. - - -采用 `--continue` 选项, Gralde 会调用*每一个*任务以及它们依赖的任务. 而不是一旦出现错误就会中断执行.所有错误信息都会在最后被列出来. - - -一旦某个任务执行失败,那么所有依赖于该任务的子任务都不会被调用.例如由于 test 任务依赖于 complie 任务,所以如果 compile 调用出错, test 便不会被直接或间接调用. - - diff --git a/using_the_gradle_command-line/excluding_tasks.md b/using_the_gradle_command-line/excluding_tasks.md deleted file mode 100644 index f775cdc..0000000 --- a/using_the_gradle_command-line/excluding_tasks.md +++ /dev/null @@ -1,21 +0,0 @@ -# 排除任务 - -你可以用命令行选项-x来排除某些任务,让我们用上面的例子来示范一下. - -*例子 11.2. 排除任务* - -`gradle dist -x test` 命令的输出 - - > gradle dist -x test - :compile - compiling source - :dist - building the distribution - - BUILD SUCCESSFUL - - Total time: 1 secs - -可以看到, test 任务并没有被调用,即使它是 dist 任务的依赖. 同时 test 任务的依赖任务 compileTest 也没有被调用,而像 compile 被 test 和其它任务同时依赖的任务仍然会被调用. - - diff --git a/using_the_gradle_command-line/executing_multiple_tasks.md b/using_the_gradle_command-line/executing_multiple_tasks.md deleted file mode 100644 index 59a912f..0000000 --- a/using_the_gradle_command-line/executing_multiple_tasks.md +++ /dev/null @@ -1,50 +0,0 @@ -# 多任务调用 - -你可以以列表的形式在命令行中一次调用多个任务. -例如 **gradle compile test** 命令会依次调用 compile 和 test 任务, 它们所依赖的任务也会被调用. 这些任务只会被调用一次, 无论它们是否被包含在脚本中:即无论是以命令行的形式定义的任务还是依赖于其它任务都会被调用执行.来看下面的例子. - -下面定义了四个任务 dist和test 都 依赖于 compile ,只用当 compile 被调用之后才会调用 `gradle dist test` 任务 - - -**示例图 11.1. 任务依赖** - -![Task dependencies](http://pkaq.github.io/gradledoc/docs/userguide/img/commandLineTutorialTasks.png) - -**例子 11.1. 多任务调用** - -**build.gradle** - - task compile << { - println 'compiling source' - } - - task compileTest(dependsOn: compile) << { - println 'compiling unit tests' - } - - task test(dependsOn: [compile, compileTest]) << { - println 'running unit tests' - } - - task dist(dependsOn: [compile, test]) << { - println 'building the distribution' - } - -**gradle dist test** 命令的输出 - - > gradle dist test - :compile - compiling source - :compileTest - compiling unit tests - :test - running unit tests - :dist - building the distribution - - BUILD SUCCESSFUL - - Total time: 1 secs - -由于每个任务仅会被调用一次,所以调用**gradle test test**与调用**gradle test**效果是相同的. - diff --git a/using_the_gradle_command-line/getting_the_insight_into_a_particular_dependency.md b/using_the_gradle_command-line/getting_the_insight_into_a_particular_dependency.md deleted file mode 100644 index 17b60f9..0000000 --- a/using_the_gradle_command-line/getting_the_insight_into_a_particular_dependency.md +++ /dev/null @@ -1,21 +0,0 @@ -# 查看特定依赖 - -执行 `gradle dependencyInsight` 命令可以查看指定的依赖. 如下面的例子. - -**例 11.15. 获取特定依赖** - -`gradle -q webapp:dependencyInsight --dependency groovy --configuration compile` 的输出结果 - -``` -> gradle -q webapp:dependencyInsight --dependency groovy --configuration compile -org.codehaus.groovy:groovy-all:2.3.3 -\--- project :api - \--- compile -``` - - -这个 task 对于了解依赖关系、了解为何选择此版本作为依赖十分有用.了解更多请参阅 [DependencyInsightReportTask](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.diagnostics.DependencyInsightReportTask.html). - -dependencyInsight 任务是'Help'任务组中的一个. 这项任务需要进行配置才可以使用. Report 查找那些在指定的配置里特定的依赖. - -如果用了Java相关的插件, 那么 dependencyInsight 任务已经预先被配置到'compile'下了. 你只需要通过 `'--dependency'` 参数来制定所需查看的依赖即可. 如果你不想用默认配置的参数项你可以通过`'--configuration'`参数来进行指定.了解更多请参阅 [DependencyInsightReportTask](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.diagnostics.DependencyInsightReportTask.html). diff --git a/using_the_gradle_command-line/listing_project_dependencies.md b/using_the_gradle_command-line/listing_project_dependencies.md deleted file mode 100644 index f837739..0000000 --- a/using_the_gradle_command-line/listing_project_dependencies.md +++ /dev/null @@ -1,55 +0,0 @@ -# 获取依赖列表 - -执行 `gradle dependencies` 命令会列出项目的依赖列表, 所有依赖会根据任务区分,以树型结构展示出来. -如下例: - -**例 11.13. 获取依赖信息** - -*gradle -q dependencies api:dependencies webapp:dependencies 的输出结果* - - > gradle -q dependencies api:dependencies webapp:dependencies - ------------------------------------------------------------ - Root project - ------------------------------------------------------------ - - No configurations - - ------------------------------------------------------------ - Project :api - The shared API for the application - ------------------------------------------------------------ - - compile - \--- org.codehaus.groovy:groovy-all:2.3.3 - - testCompile - \--- junit:junit:4.11 - \--- org.hamcrest:hamcrest-core:1.3 - - ------------------------------------------------------------ - Project :webapp - The Web application implementation - ------------------------------------------------------------ - - compile - +--- project :api - | \--- org.codehaus.groovy:groovy-all:2.3.3 - \--- commons-io:commons-io:1.2 - - testCompile - No dependencies - -虽然输出结果很多, -但这对于了解构建任务十分有用, -当然你可以通过 `--configuration` 参数来查看 指定构建任务的依赖情况: - -**例 11.14. 过滤依赖信息** - -`gradle -q api:dependencies --configuration testCompile` 的输出结果 - - > gradle -q api:dependencies --configuration testCompile - ------------------------------------------------------------ - Project :api - The shared API for the application - ------------------------------------------------------------ - - testCompile - \--- junit:junit:4.11 - \--- org.hamcrest:hamcrest-core:1.3 diff --git a/using_the_gradle_command-line/listing_project_properties.md b/using_the_gradle_command-line/listing_project_properties.md deleted file mode 100644 index c4d766b..0000000 --- a/using_the_gradle_command-line/listing_project_properties.md +++ /dev/null @@ -1,24 +0,0 @@ -# 获取项目属性列表 - -执行 `gradle properties` 可以获取项目所有属性列表. 如下例: - -**例 11.16. 属性信息** - -`gradle -q api:properties` 的输出结果 - -``` -> gradle -q api:properties ------------------------------------------------------------- -Project :api - The shared API for the application ------------------------------------------------------------- - -allprojects: [project ':api'] -ant: org.gradle.api.internal.project.DefaultAntBuilder@12345 -antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345 -artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler@12345 -asDynamicObject: org.gradle.api.internal.ExtensibleDynamicObject@12345 -baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345 -buildDir: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build -buildFile: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build.gradle -``` - diff --git a/using_the_gradle_command-line/listing_projects.md b/using_the_gradle_command-line/listing_projects.md deleted file mode 100644 index 2871786..0000000 --- a/using_the_gradle_command-line/listing_projects.md +++ /dev/null @@ -1,28 +0,0 @@ -# 项目列表 - -执行 `gradle projects` 命令会为你列出子项目名称列表. - -**例 11.7. 收集项目信息** - -**gradle -q projects** 命令的输出结果 - - > gradle -q projects - ------------------------------------------------------------ - Root project - ------------------------------------------------------------ - - Root project 'projectReports' - +--- Project ':api' - The shared API for the application - \--- Project ':webapp' - The Web application implementation - - To see a list of the tasks of a project, run gradle :tasks - For example, try running gradle :api:tasks - -这份报告展示了每个项目的描述信息. -当然你可以在项目中用 **description** 属性来指定这些描述信息. - -**例 10.8. 为项目添加描述信息** - -*build.gradle* - - description = 'The shared API for the application' diff --git a/using_the_gradle_command-line/listing_tasks.md b/using_the_gradle_command-line/listing_tasks.md deleted file mode 100644 index 3d2ebac..0000000 --- a/using_the_gradle_command-line/listing_tasks.md +++ /dev/null @@ -1,7 +0,0 @@ -# 获取构建信息 - -Gradle提供了许多内置任务来收集构建信息. -这些内置任务对于了解依赖结构以及解决问题都是很有帮助的. - -了解更多, -可以参阅[项目报告插件](http://www.gradle.org/docs/current/userguide/userguide_single.html#project_reports_plugin)以为你的项目添加构建报告 diff --git a/using_the_gradle_command-line/listing_taskss.md b/using_the_gradle_command-line/listing_taskss.md deleted file mode 100644 index 16e332c..0000000 --- a/using_the_gradle_command-line/listing_taskss.md +++ /dev/null @@ -1,105 +0,0 @@ -# 任务列表 - -执行 `gradle tasks` 命令会列出项目中所有任务. -这会显示项目中所有的默认任务以及每个任务的描述. - -例 11.9 获取任务信息 - -**gradle -q tasks** 命令的输出 - -``` -> gradle -q tasks ------------------------------------------------------------- -All tasks runnable from root project ------------------------------------------------------------- - -Default tasks: dists - -Build tasks ------------ -clean - Deletes the build directory (build) -dists - Builds the distribution -libs - Builds the JAR - -Build Setup tasks ------------------ -init - Initializes a new Gradle build. [incubating] -wrapper - Generates Gradle wrapper files. [incubating] - -Help tasks ----------- -dependencies - Displays all dependencies declared in root project 'projectReports'. -dependencyInsight - Displays the insight into a specific dependency in root project 'projectReports'. -help - Displays a help message -projects - Displays the sub-projects of root project 'projectReports'. -properties - Displays the properties of root project 'projectReports'. -tasks - Displays the tasks runnable from root project 'projectReports' (some of the displayed tasks may belong to subprojects). - -To see all tasks and more detail, run with --all.``` - -默认情况下,这只会显示那些被分组的任务. -你可以通过为任务设置 **group** 属性和 **description** 来把 这些信息展示到结果中. - -**例 11.10. 更改任务报告内容** - -**build.gradle** - -``` -dists { - description = 'Builds the distribution' - group = 'build' -}``` - -当然你也可以用 **--all** 参数来收集更多任务信息. -这会列出项目中所有任务以及任务之间的依赖关系. - -例 11.11 获得更多的任务信息 - -**gradle -q tasks --all** 命令的输出 - -``` -> gradle -q tasks --all ------------------------------------------------------------- -All tasks runnable from root project ------------------------------------------------------------- - -Default tasks: dists - -Build tasks ------------ -clean - Deletes the build directory (build) -api:clean - Deletes the build directory (build) -webapp:clean - Deletes the build directory (build) -dists - Builds the distribution [api:libs, webapp:libs] - docs - Builds the documentation -api:libs - Builds the JAR - api:compile - Compiles the source files -webapp:libs - Builds the JAR [api:libs] - webapp:compile - Compiles the source files - -Build Setup tasks ------------------ -init - Initializes a new Gradle build. [incubating] -wrapper - Generates Gradle wrapper files. [incubating] - -Help tasks ----------- -dependencies - Displays all dependencies declared in root project 'projectReports'. -api:dependencies - Displays all dependencies declared in project ':api'. -webapp:dependencies - Displays all dependencies declared in project ':webapp'. -dependencyInsight - Displays the insight into a specific dependency in root project 'projectReports'. -api:dependencyInsight - Displays the insight into a specific dependency in project ':api'. -webapp:dependencyInsight - Displays the insight into a specific dependency in project ':webapp'. -help - Displays a help message -api:help - Displays a help message -webapp:help - Displays a help message -projects - Displays the sub-projects of root project 'projectReports'. -api:projects - Displays the sub-projects of project ':api'. -webapp:projects - Displays the sub-projects of project ':webapp'. -properties - Displays the properties of root project 'projectReports'. -api:properties - Displays the properties of project ':api'. -webapp:properties - Displays the properties of project ':webapp'. -tasks - Displays the tasks runnable from root project 'projectReports' (some of the displayed tasks may belong to subprojects). -api:tasks - Displays the tasks runnable from project ':api'. -webapp:tasks - Displays the tasks runnable from project ':webapp'.``` - diff --git a/using_the_gradle_command-line/profiling_a_build.md b/using_the_gradle_command-line/profiling_a_build.md deleted file mode 100644 index 91f7bbe..0000000 --- a/using_the_gradle_command-line/profiling_a_build.md +++ /dev/null @@ -1,13 +0,0 @@ -# 构建日志 - -**--profile** 参数可以收集一些构建期间的信息并保存到 build/reports/profile 目录下. 并且会以构建时间命名这些文件. - -下面是一份日志. -这份日志记录了总体花费时间以及各过程花费的时间. -并以时间大小倒序排列. -并且记录了任务的执行情况. - -如果采用了 buildSrc, -那么在 buildSrc/build 下同时也会生成一份日志记录记录. - -![](http://gradle.org/docs/current/userguide/img/profile.png) diff --git a/using_the_gradle_command-line/selecting_which_build_to_execute.md b/using_the_gradle_command-line/selecting_which_build_to_execute.md deleted file mode 100644 index 43a9ebf..0000000 --- a/using_the_gradle_command-line/selecting_which_build_to_execute.md +++ /dev/null @@ -1,33 +0,0 @@ -# 选择执行构建 - -调用 gradle 命令时, -默认情况下总是会构建当前目录下的文件, 可以使用 **-b** 参数选择其他目录的构建文件, -并且当你使用此参数时 settings.gradle 将不会生效, -看下面的例子: - -**例 11.5. 选择文件构建** - -**subdir/myproject.gradle** - - task hello << { - println "using build file '$buildFile.name' in '$buildFile.parentFile.name'." - } - -**gradle -q -b subdir/myproject.gradle hello** 的输出 - - gradle -q -b subdir/myproject.gradle hello - using build file 'myproject.gradle' in 'subdir'. - -另外,你可以使用 **-p** 参数来指定构建的目录,例如在多项目构建中你可以用 -p 来替代 -b 参数 - -例 10.6. 选择构建目录 - -**gradle -q -p subdir hello** 命令的输出 - - gradle -q -p subdir hello - using build file 'build.gradle' in 'subdir'. - -**-b** 参数用以指定脚本具体所在位置, -格式为 dirpwd/build.gradle. - -**-p** 参数用以指定脚本目录即可. diff --git a/using_the_gradle_command-line/show_task_usage_details.md b/using_the_gradle_command-line/show_task_usage_details.md deleted file mode 100644 index 0748b9b..0000000 --- a/using_the_gradle_command-line/show_task_usage_details.md +++ /dev/null @@ -1,23 +0,0 @@ -# 获取任务具体信息 - -执行 **gradle help --task someTask** 可以显示指定任务的详细信息. 或者多项目构建中相同任务名称的所有任务的信息. -如下例. - -*例 11.12. 获取任务帮助* - -*gradle -q help --task libs的输出结果* - - > gradle -q help --task libs - Detailed task information for libs - - Paths - :api:libs - :webapp:libs - - Type - Task (org.gradle.api.Task) - - Description - Builds the JAR - -这些结果包含了任务的路径、类型以及描述信息等. diff --git a/using_the_gradle_command-line/task_name_abbreviation.md b/using_the_gradle_command-line/task_name_abbreviation.md deleted file mode 100644 index 1674477..0000000 --- a/using_the_gradle_command-line/task_name_abbreviation.md +++ /dev/null @@ -1,47 +0,0 @@ -# 简化任务名 - -当你试图调用某个任务的时候, -你并不需要输入任务的全名. -只需提供足够的可以唯一区分出该任务的字符即可. -例如, -上面的例子你也可以这么写. -用 `gradle di` 来直接调用 dist 任务: - -**例 11.3. 简化任务名** - -`gradle di` 命令的输出 - - > gradle di - :compile - compiling source - :compileTest - compiling unit tests - :test - running unit tests - :dist - building the distribution - - BUILD SUCCESSFUL - - Total time: 1 secs - -你也可以用在驼峰命名方式 (通俗的说就是每个单词的第一个字母大写,除了第一个单词) 的任务中每个单词的首字母进行调用. -例如, -可以执行 `gradle compTest` 或者 `gradle cT` 来调用 compileTest 任务 - -**例 11.4. 简化驼峰方式的任务名** - -`gradle cT` 命令的输出 - - > gradle cT - :compile - compiling source - :compileTest - compiling unit tests - - BUILD SUCCESSFUL - - Total time: 1 secs - -简化后你仍然可以使用-x参数. - diff --git a/using_the_gradle_graphical_user_interface/README.md b/using_the_gradle_graphical_user_interface/README.md deleted file mode 100644 index 14a2eef..0000000 --- a/using_the_gradle_graphical_user_interface/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# 使用 Gradle 图形界面 - -为了辅助传统的命令行交互,Gradle还提供了一个图形界面.我们可以使用Gradle命令中**--gui**选项来启动它. - -例子 12.1. 启动图形界面 - - gradle --gui - -**注意:**这个命令执行后会使得命令行一直处于封锁状态,直到我们关闭图形界面. -不过我们可以另外加上**“&”**让它在后台执行: - - gradle --gui& - -如果我们从自己的Gradle项目目录中启动这个图形界面,我们应该会看到任务树. - -图 12.1. 任务树 - -![](http://gradle.org/docs/current/userguide/img/guiTaskTree.png) - -我们建议您从当前的Gradle项目目录启动图形界面,因为这种方式可以将有关于界面的一些设置存储到您目录里面.不过您也可以在启动它后切换工作目录,方式:通过界面中**“Setup”**选项卡可以设置. - -如您所见,这个界面在顶部有4个选项卡和底部一个输出窗口. - diff --git a/using_the_gradle_graphical_user_interface/command_line.md b/using_the_gradle_graphical_user_interface/command_line.md deleted file mode 100644 index 53df02f..0000000 --- a/using_the_gradle_graphical_user_interface/command_line.md +++ /dev/null @@ -1,5 +0,0 @@ -# 命令行 - - -在**“Command Line”**选项卡,您只需将命令填入到**gradle**输入框. 就可以直接执行单个的Gradle命令. 或者说在您将某个命令添加到收藏夹之前,您想看看是什么效果的话,不妨来这里试试. - diff --git a/using_the_gradle_graphical_user_interface/favorities.md b/using_the_gradle_graphical_user_interface/favorities.md deleted file mode 100644 index 10f541c..0000000 --- a/using_the_gradle_graphical_user_interface/favorities.md +++ /dev/null @@ -1,7 +0,0 @@ -# 收藏夹 - -**"Favorites"**选项卡是个好地方. 您可以收藏常用的命令. 即使是复杂的命令集,只要它符合**Gradle规范**,您都可以添加收藏,而且您还可以为它起个通俗易懂的别名. 这个方法逼格是不是很高. 一个一眼看上去就让人明白的自定义的命令,我们可以称它为“侩子手”(fast build). - - -您还可以对收藏的任务进行排序,或者您可以导出它们到磁盘,然后将导出的命令分享给别的小伙伴使用. 如果您想编辑它们,如您所见,我们会看到有个**"Always Show Live Output"**选项,如果您勾选了,可以强制命令在执行时显示在输出窗口. - diff --git a/using_the_gradle_graphical_user_interface/setup.md b/using_the_gradle_graphical_user_interface/setup.md deleted file mode 100644 index e016005..0000000 --- a/using_the_gradle_graphical_user_interface/setup.md +++ /dev/null @@ -1,17 +0,0 @@ -# 设置 - -在设置界面,你可以配置一些常用的设置. - -图 12.2 设置界面 - -![](http://gradle.org/docs/current/userguide/img/guiSetup.png) - - -* **“Current Directory”** 图形界面会默认设置您的Gradle项目的根目录(build.gradle 文件所在的目录)为当前目录. - -* **“Stack Trace Output“** 这个选项可以指定当错误发生时,有多少信息可以写入到轨迹栈中,注意:在您设定轨迹栈级别后,如果"Command Line"(命令行)选项卡中,或者在"Favorites"(收藏夹)选项卡中的命令发生错误,这个设置就不会起作用了. - -* **”Only Show Output When Errors Occur”** 设定当编译出问题时输出窗口才显示相关信息. - -* **"Use Custom Gradle Executor"** 高级功能,您可以指定一个路径启动Gradle命令代替默认的设置,例如您的项目需要在别的批处理文件或者shell脚本进行额外的配置(例如指定一个初始化脚本),这种情况您就可以使用它. - diff --git a/using_the_gradle_graphical_user_interface/task_tree.md b/using_the_gradle_graphical_user_interface/task_tree.md deleted file mode 100644 index 63ce915..0000000 --- a/using_the_gradle_graphical_user_interface/task_tree.md +++ /dev/null @@ -1,26 +0,0 @@ -# 任务树 - -任务树使用分层方式显示了所有的项目和它们的任务,双击一个任务,您就可以执行它. - - -另外我们还可以使用过滤器过滤掉不常用的任务. 您可以点击 **Filter** 按钮来设置过滤条件. 设定哪些任务和项目可以显示. 隐藏的任务会使用红色来标记. - -**注意:**最新被创建的任务会默认被显示出来(相反是被隐藏). - - -如您所见,在任务树界面我们可以做以下几种事情: - - -* 执行任务时忽略依赖性,而且并不需要重新编译独立的项目. - -* 添加自己喜欢的任务,将其收藏(具体请看**“Favorities”**选项卡). - - -* 隐藏自己不想看到的任务,这个操作会将他们添加到过滤器中. - - -* 编辑 build.gradke 文件, - 注意:这个需要你的jdk版本为1.6以上,而且你的操作系统需要关联 .gradle 文件. - - - diff --git a/web_application_quickstart/README.md b/web_application_quickstart/README.md deleted file mode 100644 index 71c2174..0000000 --- a/web_application_quickstart/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# 网页应用快速入门 - -> 本章是一项正在进行中的工作. - -Gradle 提供了两个插件用来支持网页应用: War 插件和 Jetty 插件. War 插件是在 Java 插件的基础上扩充的用来构建 WAR 文件. Jetty 插件是在 War 插件的基础上扩充的, 允许用户将网页应用发布到一个介入的 Jetty 容器里. - diff --git a/web_application_quickstart/building_a_war_file.md b/web_application_quickstart/building_a_war_file.md deleted file mode 100644 index 736841f..0000000 --- a/web_application_quickstart/building_a_war_file.md +++ /dev/null @@ -1,13 +0,0 @@ -# 构建一个 WAR 文件 - -为了构建一个 WAR 文件, 需要在项目中加入 War 插件: - -*例子 9.1. War 插件* - -*build.gradle* - - apply plugin: 'war' - -> 注意:项目代码可以在`samples/webApplication/quickstart` 在Gradle的发行包`"-all"`中找到. - -这个插件也会在你的项目里加入 Java 插件. 运行 **gradle build** 将会编译, 测试和创建项目的 WAR 文件. Gradle 将会把源文件包含在 WAR 文件的 src/main/webapp 目录里. 编译后的 classe , 和它们运行所需要的依赖也会被包含在 WAR 文件里. diff --git a/web_application_quickstart/running_your_web_application.md b/web_application_quickstart/running_your_web_application.md deleted file mode 100644 index d5b75cb..0000000 --- a/web_application_quickstart/running_your_web_application.md +++ /dev/null @@ -1,16 +0,0 @@ -# Running your web application - -要启动Web工程,在项目中加入Jetty plugin即可: - -*例 9.2. 采用Jetty plugin启动web工程* - -*build.gradle* - - apply plugin: 'jetty' - -由于Jetty plugin继承自War plugin.使用 `gradle jettyRun` 命令将会把你的工程启动部署到jetty容器中. 调用 `gradle jettyRunWar` 命令会打包并启动部署到jetty容器中. - -> **Groovy web applications** -> 你可以结合多个插件在一个项目中,所以你可以一起使用`War` 和 `Groovy`插件构建一个 Groovy 基础 web 应用.合适的 Groovy 类库会添加到你的 `WAR` 文件中. - -TODO: which url, configure port, uses source files in place and can edit your files and reload. diff --git a/web_application_quickstart/summary.md b/web_application_quickstart/summary.md deleted file mode 100644 index 98c2d8f..0000000 --- a/web_application_quickstart/summary.md +++ /dev/null @@ -1,5 +0,0 @@ -# 总结 - -了解更多关于War plugin和Jetty plugin的应用请参阅[Chapter 26,The War Plugin](https://docs.gradle.org/current/userguide/war_plugin.html)以及[Chapter 28,The Jetty Plugin](https://docs.gradle.org/current/userguide/jetty_plugin.html). - -你可以在发行包的samples/webApplication下找到更多示例. diff --git a/working_with_files/README.md b/working_with_files/README.md deleted file mode 100644 index 7d4cf8e..0000000 --- a/working_with_files/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# 文件操作 - -大多数构建工作需要操作文件,Gradle 增加了一些API帮助您处理这些工作。 diff --git a/working_with_files/copying_files.md b/working_with_files/copying_files.md deleted file mode 100644 index 16208e9..0000000 --- a/working_with_files/copying_files.md +++ /dev/null @@ -1,212 +0,0 @@ -#复制文件 - -你可以使用复制任务( `Copy` )去复制文件. 复制任务扩展性很强,能够过滤复制文件的内容, 映射文件名. - -使用复制任务时需要提供想要复制的源文件和一个目标目录,如果你要指定文件被复制时的转换方式,可以使用 _复制规则_. 复制规则被 `CopySpec` 接口抽象,复制任务实现了这个接口. 使用 `CopySpec.from()` 方法指定源文件.使用 `CopySpec.into()` 方法指定目标目录. - -**例 15.10. 使用复制任务复制文件** - -**build.gradle** -``` -task copyTask(type: Copy) { - from 'src/main/webapp' - into 'build/explodedWar' -} - -``` - -`from()` 方法接收任何 `files()` 方法支持的参数. 当参数被解析为一个目录时,在这个目录下的任何文件都会被递归地复制到目标目录(但不是目录本身).当一个参数解析为一个文件时,该文件被复制到目标目录中.当参数被解析为一个不存在的文件时,这个参数就会忽略.如果这个参数是一个任务,任务的输出文件(这个任务创建的文件)会被复制,然后这个任务会被自动添加为复制任务的依赖. - -**例 15.11 指定复制任务的源文件和目标目录** - -**build.gradle** -``` -task anotherCopyTask(type: Copy) { - // 复制 src/main/webapp 目录下的所有文件 - from 'src/main/webapp' - // 复制一个单独文件 - from 'src/staging/index.html' - // 复制一个任务输出的文件 - from copyTask - // 显式使用任务的 outputs 属性复制任务的输出文件 - from copyTaskWithPatterns.outputs - // 复制一个 ZIP 压缩文件的内容 - from zipTree('src/main/assets.zip') - // 最后指定目标目录 - into { getDestDir() } -} - -``` - -你可以使用`Ant-style` 规则或者一个闭合选择要复制的文件. - -**例 15.12 选择要复制文件** - -**build.gradle** -``` -task copyTaskWithPatterns(type: Copy) { - from 'src/main/webapp' - into 'build/explodedWar' - include '**/*.html' - include '**/*.jsp' - exclude { details -> details.file.name.endsWith('.html') && - details.file.text.contains('staging') } -} -``` -你也可以使用 `Project.copy()` 方法复制文件,它的工作方式有一些限制,首先该方法不是增量的,请参考 [第 14.9节 跳过最新的任务](https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks).第二,当一个任务被用作复制源时(例如 from() 方法的参数), `copy()` 方法不能够实现任务依赖,因为它是一个普通的方法不是一个任务.因此,如果你使用 `copy()`方法作为一个任务的一部分功能,你需要显式的声明所有的输入和输出以确保获得正确的结果. - -**例 15.13 不使用最新检查方式下用 copy() 方法复制文件** - -**build.gradle** -``` -task copyMethod << { - copy { - from 'src/main/webapp' - into 'build/explodedWar' - include '**/*.html' - include '**/*.jsp' - } -} -``` - - - -**例 15.14 使用最新的检查方式下用 copy() 方法复制文件** - -**build.gradle** - -``` -task copyMethodWithExplicitDependencies{ - - // 对输入做最新检查,添加 copyTask 作为依赖 - inputs.file copyTask - outputs.dir 'some-dir' //对输出做最新检查 - doLast{ - copy { - // 复制 copyTask 的输出 - from copyTask - into 'some-dir' - } - } -} - -``` - -建议尽可能的使用复制任务,因为它支持增量化的构建和任务依赖推理,而不需要去额外的费力处理这些.不过 `copy()` 方法可以用作复制任务实现的一部分.即该 方法被在自定义复制任务中使用,请参考 [第60章 编写自定义任务](https://docs.gradle.org/current/userguide/custom_tasks.html).在这样的场景下,自定义任务应该充分声明与复制操作相关的输入/输出。 - -##15.6.1 重命名文件 - -**例 15.15 在复制时重命名文件** - -**build.gradle** - -``` -task rename(type: Copy) { - from 'src/main/webapp' - into 'build/explodedWar' - // 使用一个闭合映射文件名 - rename { String fileName -> - fileName.replace('-staging-', '') - } - // 使用正则表达式映射文件名 - rename '(.+)-staging-(.+)', '$1$2' - rename(/(.+)-staging-(.+)/, '$1$2') -} - -``` - -##15.6.2 过滤文件 - -**例 15.16 在复制时过滤文件** - -**build.gradle** - -``` -import org.apache.tools.ant.filters.FixCrLfFilter -import org.apache.tools.ant.filters.ReplaceTokens - -task filter(type: Copy) { - from 'src/main/webapp' - into 'build/explodedWar' - // 在文件中替代属性标记 - expand(copyright: '2009', version: '2.3.1') - expand(project.properties) - // 使用 Ant 提供的过滤器 - filter(FixCrLfFilter) - filter(ReplaceTokens, tokens: [copyright: '2009', version: '2.3.1']) - // 用一个闭合来过滤每一行 - filter { String line -> - "[$line]" - } - // 使用闭合来删除行 - filter { String line -> - line.startsWith('-') ? null : line - } -} - -``` -在源文件中扩展和过滤操作都会查找的某个标志 `token`,如果它的名字是 `tokenName` , 它的格式应该类似于 `@tokenName@`. - -## 15.6.3 使用 CopySpec 类 - -复制规范来自于层次结构,一个复制规范继承其目标路径,包括模式,排除模式,复制操作,名称映射和过滤器. - -**例 15.17. 嵌套复制规范** - -**build.gradle** - -``` -task nestedSpecs(type: Copy) { - into 'build/explodedWar' - exclude '**/*staging*' - from('src/dist') { - include '**/*.html' - } - into('libs') { - from configurations.runtime - } -} - - -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/working_with_files/creating_archives.md b/working_with_files/creating_archives.md deleted file mode 100644 index 43bdf5e..0000000 --- a/working_with_files/creating_archives.md +++ /dev/null @@ -1,172 +0,0 @@ -# 创建归档文件 - -一个项目可以有很多 JAR 文件,你可以向项目中添加 WAR , ZIP 和 TAR 文档,使用归档任务可以创建这些文档: Zip , Tar , Jar , War 和Ear. 它门都以同样的机制工作. - -**例 15.19 创建一个 ZIP 文档 ** - -**build.gradle** - -``` -apply plugin: 'java' - -task zip(type: Zip) { - from 'src/dist' - into('libs') { - from configurations.runtime - } -} - -``` - -所有的归档任务的工作机制和复制任务相同,它们都实现了 `CopySpec` 接口,和 `Copy` 任务一样,使用 `from()` 方法指定输入文件,可以选择性的使用 `into()` 方法指定什么时候结束.你还可以过滤文件内容,重命名文件等等,就如同使用复制规则一样. - -##重命名文档 - - - -`projectName-vsersion.type` 格式可以被用来生成文档名,例如: - -**例 15.20 创建压缩文档** - -**build.gradle** - -``` -apply plugin: 'java' - -version = 1.0 - -task myZip(type: Zip) { - from 'somedir' -} - -println myZip.archiveName -println relativePath(myZip.destinationDir) -println relativePath(myZip.archivePath) - -``` -使用 `gradle -q myZip` 命令进行输出: -``` -> gradle -q myZip -zipProject-1.0.zip -build/distributions -build/distributions/zipProject-1.0.zip - -``` - -上面例子使用一个名为 myZip的 Zip 归档任务生成名称为 zipProject-1.0.zip 的 ZIP 文档,区分文档任务名和最终生成的文档名非常的重要 - -可以通过设置项目属性 `archivesBaseName` 的值来 修改生成文档的默认名.当然,文档的名称也可以通过其他方法随时更改. - -归档任务中有些属性可以配置,如表 15.1 所示: - -**表 15.1 归档任务-属性名** - - -属性名 | 类型 | 默认值 | 描述 --------|------|---------|---- -archiveName | String | baseName-appendix-version-classifier.extension,如果其中任何一个都是空的,则不添加名称|归档文件的基本文件名 -archivePath | File | destinationDir/archiveName |生成归档文件的绝对路径。 -destinationDir | File | 取决于文档类型, JAR 和 WAR 使用project.buildDir/distributions. project.buildDir/libraries.ZIP 和 TAR|归档文件的目录 -baseName | String | project.name|归档文件名的基础部分。 -appendix | String | null|归档文件名的附加部分。 -version | String | project.version|归档文件名的版本部分。 -classifier | String | null|归档文件名的分类部分 -extension | String | 取决于文档类型和压缩类型: zip, jar, war, tar, tgz 或者 tbz2.|归档文件的扩展名 - - -**例 15.21 配置归档文件-自定义文档名** - -**build.gradle** - -``` -apply plugin: 'java' -version = 1.0 - -task myZip(type: Zip) { - from 'somedir' - baseName = 'customName' -} - -println myZip.archiveName - -``` - -使用 `gradle -q myZip` 命令进行输出: - -``` -> gradle -q myZip -customName-1.0.zip -``` -更多配置: - -**例 15.22 配置归档任务- 附加其他后缀** - -**build.gradle** - -``` -apply plugin: 'java' -archivesBaseName = 'gradle' -version = 1.0 - -task myZip(type: Zip) { - appendix = 'wrapper' - classifier = 'src' - from 'somedir' -} - -println myZip.archiveName - -``` - -使用 `gradle -q myZip` 命令进行输出: - -``` -> gradle -q myZip -gradle-wrapper-1.0-src.zip - -``` - -##多个文档共享内容 - -你可以使用 `Project.copySpec()` 在不用归档文件间共享内容. -如果你想发布一个文档,然后在另一个项目中使用,这部分将在第 53 章 [发布文档](https://docs.gradle.org/current/userguide/artifact_management.html) 中讲述. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/working_with_files/file_collections.md b/working_with_files/file_collections.md deleted file mode 100644 index f00f167..0000000 --- a/working_with_files/file_collections.md +++ /dev/null @@ -1,101 +0,0 @@ -# 文件集合 - - 文件集合表示一组文件,Gradle 使用 `FileCollection` 接口表示文件集合, Gradle API 中的许多项目都实现了这个接口,例如 [dependency configurations ](https://docs.gradle.org/current/userguide/dependency_management.html#sub:configurations). - - 获取 `FileCollection` 实例的一种方法是使用 `Project.files()` 方法.你可以传递任何数量的对象参数,这个方法能将你传递的对象集合转换为一组文件对象.`files()` 方法接收任何类型对象参数.每一个 `file()` 方法都依赖于项目目录(在第 15 章,第一小节中介绍).`files()`方法也接收 `collections `, `iterables`, `maps` 和 `arrays` 类型参数.这些参数的内容会被解析,然后被转换为文件对象. - -**例 15.2 创建文件集合 ** - -**build.gradle** -``` -FileCollection collection = files('src/file1.txt', - new File('src/file2.txt'), - ['src/file3.txt', 'src/file4.txt']) -``` - -文件集合可以被迭代器,使用迭代操作能够将其转换为其他的一些类型.你可以使用 `+` 操作将两个文件集合合并,使用 `-` 操作能够对一个文件集合做减法.下面一些例子介绍如何操作文件集合. - -**例 15.3 使用文件集合** - -**build.gradle** - -``` -// 对文件集合进行迭代 -collection.each {File file -> - println file.name -} - -// 转换文件集合为其他类型 -Set set = collection.files -Set set2 = collection as Set -List list = collection as List -String path = collection.asPath -File file = collection.singleFile -File file2 = collection as File - -// 增加和减少文件集合 -def union = collection + files('src/file3.txt') -def different = collection - files('src/file3.txt') - -``` - -你也可以向 `files()` 方法专递一个闭合或者可回调的实例参数.当查询集合的内容时就会调用它,然后将返回值转换为一些文件实例.返回值可以是 `files()` 方法支持的任何类型的对象.下面有个简单的例子来演示实现 `FileCollection` 接口 - -**例 15.4 实现一个文件集合** - -**build.gradle** -``` -task list << { - File srcDir - - // 使用闭合创建一个文件集合 - collection = files { srcDir.listFiles() } - - srcDir = file('src') - println "Contents of $srcDir.name" - collection.collect { relativePath(it) }.sort().each { println it } - - srcDir = file('src2') - println "Contents of $srcDir.name" - collection.collect { relativePath(it) }.sort().each { println it } -} - -``` -使用 `gradle -q list` 输出结果 - -``` -> gradle -q list -Contents of src -src/dir1 -src/file1.txt -Contents of src2 -src2/dir1 -src2/dir2 - -``` - -另外, `files()` 方法也接收其他类型的参数: - -**FileCollection** - -内容损坏的文件包含在文件集合中. - -**Task** - -任务的输出文件包含在文件集合中. - -**TaskOutputs** - -`TaskOutputs` 的输出文件包含在文件集合中 - -值得注意的是当有需要时文件集合的内容会被被惰性处理,就比如一些任务在需要的时候会创建一个 `FileCollecion` 代表的文件集合. - - - - - - - - - - diff --git a/working_with_files/file_trees.md b/working_with_files/file_trees.md deleted file mode 100644 index c010b43..0000000 --- a/working_with_files/file_trees.md +++ /dev/null @@ -1,67 +0,0 @@ -# 文件树 - -文件树就是一个按照层次结构分布的文件集合,例如,一个文件树可以代表一个目录树结构或者一个 ZIP 压缩文件的内容.它被抽象为 `FileTree` 结构,`FileTree` 继承自 `FileCollection`,所以你可以像处理文件集合一样处理文件树, Gradle 有些对象实现了`FileTree` 接口,例如 [源集合](https://docs.gradle.org/current/userguide/java_plugin.html#sec:source_sets). -使用 `Project.fileTree()` 方法可以得到 `FileTree` 的实例,它会创建一个基于基准目录的对象,然后视需要使用一些 `Ant-style` 的包含和去除规则. - -**例 15.5 创建文件树** -**build.gradle** - -``` -/以一个基准目录创建一个文件树 -FileTree tree = fileTree(dir: 'src/main') - -// 添加包含和排除规则 -tree.include '**/*.java' -tree.exclude '**/Abstract*' - -// 使用路径创建一个树 -tree = fileTree('src').include('**/*.java') - -// 使用闭合创建一个数 -tree = fileTree('src') { - include '**/*.java' -} - -// 使用map创建一个树 -tree = fileTree(dir: 'src', include: '**/*.java') -tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml']) -tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**') - -``` - -就像使用文件集合一样,你可以访问文件树的内容,使用 `Ant-style` 规则选择一个子树。 - -**例 15.6 使用文件树** -**build.gradle** - -``` -// 遍历文件树 -tree.each {File file -> - println file -} - -// 过滤文件树 -FileTree filtered = tree.matching { - include 'org/gradle/api/**' -} - -// 合并文件树A -FileTree sum = tree + fileTree(dir: 'src/test') - -// 访问文件数的元素 -tree.visit {element -> - println "$element.relativePath => $element.file" -} - -``` - - - - - - - - - - - diff --git a/working_with_files/java.md b/working_with_files/java.md deleted file mode 100644 index 06d77a6..0000000 --- a/working_with_files/java.md +++ /dev/null @@ -1 +0,0 @@ -# Java插件 diff --git a/working_with_files/locating_files.md b/working_with_files/locating_files.md deleted file mode 100644 index 9991164..0000000 --- a/working_with_files/locating_files.md +++ /dev/null @@ -1,39 +0,0 @@ -# Locating files - -使用 `Project.file()` 方法能够相对项目目录定位一个文件 - -**例 16.1. 定位文件** - -**build.gradle** -``` -// 使用一个相对路径 - -File configFile = file('src/config.xml') - -// 使用一个绝对路径 - -configFile = file(configFile.absolutePath) - -// 使用一个项目路径的文件对象 - -configFile = file(new File('src/config.xml'))` -``` - - -`file()` 方法接收任何形式的对象参数.它会将参数值转换为一个绝对文件对象,一般情况下,你可以传递一个 `String` 或者一个 `File` 实例.如果传递的路径是个绝对路径,它会被直接构造为一个文件实例.否则,会被构造为项目目录加上传递的目录的文件对象.另外,`file()函数`也能识别`URL`,例如 file:/some/path.xml. - - -这个方法非常有用,它将参数值转换为一个绝对路径文件.所以请尽量使用 `new File(somePath)` , 因为 `file()` 总是相对于当前项目路径计算传递的路径,然后加以矫正.因为当前工作区间目录依赖于用户以何种方式运行 Gradle. - - - - - - - - - - - - - diff --git a/working_with_files/specifying_a_set_of_input_files.md b/working_with_files/specifying_a_set_of_input_files.md deleted file mode 100644 index 7ded6fa..0000000 --- a/working_with_files/specifying_a_set_of_input_files.md +++ /dev/null @@ -1,59 +0,0 @@ -# 指定一组输入文件 - - -在 `Gradle` 中有一些对象的某些属性可以接收一组输入文件.例如,`JavaComplile` 任务有一个 `source` 属性,它定义了编译的源文件,你可以设置这个属性的值,只要 `files()` 方法支持. 这意味着你可以使用 `File` , `String` , `collection` , `FileCollection` -甚至是使用一个闭合去设置属性的值. - -**例 15.8 指定文件** - -**build.gradle** -``` -//使用一个 File 对象设置源目录 -compile { - source = file('src/main/java') -} - -//使用一个字符路径设置源目录 -compile { - source = 'src/main/java' -} - -// 使用一个集合设置多个源目录 -compile { - source = ['src/main/java', '../shared/java'] -} - -// 使用 FileCollection 或者 FileTree 设置源目录 -compile { - source = fileTree(dir: 'src/main/java').matching { include 'org/gradle/api/**' } -} - -// 使用一个闭合设置源目录 -compile { - source = { - // Use the contents of each zip file in the src dir - file('src').listFiles().findAll {it.name.endsWith('.zip')}.collect { zipTree(it) } - } -} -``` - -Usually, there is a method with the same name as the property, which appends to the set of files. Again, this method accepts any of the types supported by the files() method. - -通常情况下,会有一个方法名和属性名相同的方法能够附加一组文件,这个方法接收 `files()` 方法支持的任何类型的值. - -** 例 15.9 指定文件** - -**build.gradle** -``` -compile { - // 使用字符路径添加源目录 - source 'src/main/java', 'src/main/groovy' - - // 使用 File 对象添加源目录 - source file('../shared/java') - - // 使用闭合添加源目录 - source { file('src/test/').listFiles() } -} - -``` diff --git a/working_with_files/using_a_file_collection.md b/working_with_files/using_a_file_collection.md deleted file mode 100644 index f13e675..0000000 --- a/working_with_files/using_a_file_collection.md +++ /dev/null @@ -1,93 +0,0 @@ -# Using a file collection -A file collection is iterable, and can be converted to a number of other types using the as operator. You can also add 2 file collections together using the + operator, or subtract one file collection from another using the - operator. Here are some examples of what you can do with a file collection. - -文件集合可以被迭代器,使用迭代操作能够将其转换为其他的一些类型.你可以使用`+`将两个文件集合合并,使用`-`能够对一个文件集合做减法.下面一些例子介绍如何操作文件集合. -**例子 15.3 使用文件集合** - -***build.gradle** - -``` -// 对文件集合进行迭代 -collection.each {File file -> - println file.name -} - -// 转换文件集合为其他类型 -Set set = collection.files -Set set2 = collection as Set -List list = collection as List -String path = collection.asPath -File file = collection.singleFile -File file2 = collection as File - -// 增加和减少文件集合 -def union = collection + files('src/file3.txt') -def different = collection - files('src/file3.txt') - -``` - -You can also pass the files() method a closure or a Callable instance. This is called when the contents of the collection are queried, and its return value is converted to a set of File instances. The return value can be an object of any of the types supported by the files() method. This is a simple way to 'implement' the FileCollection interface. - -你也可以向 `files()` 方法专递一个闭合或者可回调的实例参数.当查询集合的内容时就会调用它,然后将返回值转换为一些文件实例.返回值可以是`files()`方法支持的任何类型的对象.下面有个简单的例子来演示实现`FileCollection`接口 - -**例子15.4 实现一个文件集合** -**build.gradle** -``` -task list << { - File srcDir - - // 使用闭合创建一个文件集合 - collection = files { srcDir.listFiles() } - - srcDir = file('src') - println "Contents of $srcDir.name" - collection.collect { relativePath(it) }.sort().each { println it } - - srcDir = file('src2') - println "Contents of $srcDir.name" - collection.collect { relativePath(it) }.sort().each { println it } -} - -``` -使用`gradle -q list`输出结果 - -``` -> gradle -q list -Contents of src -src/dir1 -src/file1.txt -Contents of src2 -src2/dir1 -src2/dir2 - -``` - -`files()`方法也接收其他类型的参数: - -**FileCollection** -These are flattened and the contents included in the file collection. -**Task** -The output files of the TaskOutputs are included in the file collection. - -**TaskOutputs** -The output files of the TaskOutputs are included in the file collection. - -It is important to note that the content of a file collection is evaluated lazily, when it is needed. This means you can, for example, create a FileCollection that represents files which will be created in the future by, say, some task. - -值得注意的是文件集合的内容是被惰性,当你需要的时候,就比如创建一个`FileCollecion`代表文件集合会被一些`task`在需要的时候被创建. - - - - - - - - - - - - - - - - diff --git a/working_with_files/using_the_contents_of_an_archive_as_a_file_tree.md b/working_with_files/using_the_contents_of_an_archive_as_a_file_tree.md deleted file mode 100644 index b3768cb..0000000 --- a/working_with_files/using_the_contents_of_an_archive_as_a_file_tree.md +++ /dev/null @@ -1,24 +0,0 @@ -# 使用一个归档文件的内容作为文件树 - -你可以使用 ZIP 或者 TAR 等压缩文件的内容作为文件树, `Project.zipTree()` 和 `Project.tarTree()` 方法返回一个 `FileTree` 实例, 你可以像使用其他文件树或者文件集合一样使用它.例如,你可以使用它去扩展一个压缩文档或者合并一些压缩文档. - -**例 15.7 使用压缩文档作为文件树** -**build.gradle** -``` -// 使用路径创建一个 ZIP 文件 -FileTree zip = zipTree('someFile.zip') - -// 使用路径创建一个 TAR 文件 -FileTree tar = tarTree('someFile.tar') - -//tar tree 能够根据文件扩展名得到压缩方式,如果你想明确的指定压缩方式,你可以使用下面方法 -FileTree someTar = tarTree(resources.gzip('someTar.ext')) -``` - - - - - - - - diff --git a/working_with_files/using_the_sync_task.md b/working_with_files/using_the_sync_task.md deleted file mode 100644 index 91bc1ea..0000000 --- a/working_with_files/using_the_sync_task.md +++ /dev/null @@ -1,17 +0,0 @@ -# 使用同步任务 -同步任务 ( `Sync` ) 任务继承自复制任务 ( `Copy` ) , 当它执行时,它会复制源文件到目标目录中,然后从目标目录中的删除所有非复制的文件,这种方式非常有用,比如安装一个应用,创建一个文档的副本,或者维护项目的依赖关系副本. - -下面有一个例子,维护 `build/libs` 目录下项目在运行时的依赖 - -**例 15.7 使用 Sync 任务复制依赖关系** - -**build.gradle** - -``` -task libs(type: Sync) { - from configurations.runtime - into "$buildDir/libs" -} - -``` - diff --git a/writing_build_scripts/README.md b/writing_build_scripts/README.md deleted file mode 100644 index 36042b1..0000000 --- a/writing_build_scripts/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# 编写构建脚本 -这一章我们将要深入的学习如何编写构建脚本. diff --git a/writing_build_scripts/closure_delegate.md b/writing_build_scripts/closure_delegate.md deleted file mode 100644 index 5106c53..0000000 --- a/writing_build_scripts/closure_delegate.md +++ /dev/null @@ -1,12 +0,0 @@ -# 闭包委托对象 -每个闭包都有一个委托对象,当闭包既不是局部变量也不是作为方法参数时,Groovy 使用委托对象查找变量和方法引用. 当委托对象被用来管理时,Gradle 使用它来管理闭包. - -**例子 13.9.闭包引用** - -**build.gradle** - - dependencies { - assert delegate == project.dependencies - testCompile('junit:junit:4.11') - delegate.testCompile('junit:junit:4.11') - } diff --git a/writing_build_scripts/closures_as_the_last_parameter_in_a_method.md b/writing_build_scripts/closures_as_the_last_parameter_in_a_method.md deleted file mode 100644 index 22f3e43..0000000 --- a/writing_build_scripts/closures_as_the_last_parameter_in_a_method.md +++ /dev/null @@ -1,12 +0,0 @@ -# 闭包作为方法的最后一个参数 -Gradle DSL 在很多地方使用闭包,这里我们将讨论更多关于闭包的使用. 当一个方法的最后一个参数是一个闭包时,您可以在方法调用后放置一个闭包. - -**例子: 13.8.闭包作为方法的参数** - -**build.gradle** - - repositories { - println "in a closure" - } - repositories() { println "in a closure" } - repositories({println "in a closure" }) diff --git a/writing_build_scripts/declaring_variables.md b/writing_build_scripts/declaring_variables.md deleted file mode 100644 index 3163ef8..0000000 --- a/writing_build_scripts/declaring_variables.md +++ /dev/null @@ -1,3 +0,0 @@ -# 声明变量 -在 Gradle 构建脚本中有两种类型的变量可以声明:局部变量 ( local ) 和 扩展属性 ( extra ) . - diff --git a/writing_build_scripts/extra_properties.md b/writing_build_scripts/extra_properties.md deleted file mode 100644 index 05a5697..0000000 --- a/writing_build_scripts/extra_properties.md +++ /dev/null @@ -1,54 +0,0 @@ -# 扩展属性 -在 Gradle 领域模型中所有被增强的对象能够拥有自己定义的属性. 这包括,但不仅限于 projects , tasks , 还有 source sets . Project 对象可以添加,读取,更改扩展的属性. 另外,使用 ext 扩展块可以一次添加多个属性. - -**例子 13.3. 使用扩展属性** - -**build.gradle** - - apply plugin: "java" - - ext { - springVersion = "3.1.0.RELEASE" - emailNotification = "build@master.org" - } - - sourceSets.all { ext.purpose = null } - - sourceSets { - main { - purpose = "production" - } - test { - purpose = "test" - } - plugin { - purpose = "production" - } - - } - - task printProperties << { - println springVersion - println emailNotification - sourceSets.matching { it.purpose == "production" }.each { println it.name } - } - -使用**gradle -q printProperties**输出结果 - - > gradle -q printProperties - 3.1.0.RELEASE - build@master.org - main - plugin - -在上面的例子中,一个 ext 扩展块向 Project 对象添加了两个扩展属性. 名为 perpose 的属性被添加到每个 source set,然后设置 ext.purpose 等于 null ( null值是被允许的 ). 当这些扩展属性被添加后,它们就像预定义的属性一样可以被读取,更改值. - -例子中我们通过一个特殊的语句添加扩展属性,当您试图设置一个预定义属性或者扩展属性,但是属性名拼写错误或者并不存在时,操作就会失败. Project 对象可以在任何地方使用其扩展属性 ,它们比局部变量有更大的作用域. 一个项目的扩展属性对其子项目也可见. - -关于扩展属性更多的细节还有它的API,请看 [ExtraPropertiesExtension](http://gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html) 类的 API 文档说明. - - - - - - diff --git a/writing_build_scripts/groovy_jdk.md b/writing_build_scripts/groovy_jdk.md deleted file mode 100644 index 651d017..0000000 --- a/writing_build_scripts/groovy_jdk.md +++ /dev/null @@ -1,11 +0,0 @@ -# Groovy JDK -Groovy 在 Java 基础上添加了很多有用的方法. 例如,Iterable 有一个 each 方法, 通过使用 each 方法,我们可以迭代出 Iterable 中的每一个元素: - -**例子: 13.4.Groovy JDK 方法** - -**build.gradle** - - configuration.runtime.each { File f -> println f } - -更多内容请阅读 http://groovy.codehaus.org/groovy-jdk/ - diff --git a/writing_build_scripts/list_and_map_literals.md b/writing_build_scripts/list_and_map_literals.md deleted file mode 100644 index bb76db6..0000000 --- a/writing_build_scripts/list_and_map_literals.md +++ /dev/null @@ -1,23 +0,0 @@ -# List 和 Map 集合 -Groovy 为预定义的 List 和 Map 集合提供了一些操作捷径,这两个字面值都比较简单易懂,但是 Map 会有一些不同. - -例如,当您使用 "apply" 方法使用插件时,apply 会自动加上 Map 的一个参数,当您这样写 " apply plugin: 'java' "时,实际上使用的是 name 参数(name-value),只不过在 Groovy 中 使用 Map 没有 < > ,当方法被调用的时候,name 参数就会被转换成 Map 键值对,只不过在 Groovy 中看起来不像一个 Map. - -**例子 13.7.List 和 Map 集合 - -**build.gradle** - - // List 集合 - test.includes = ['org/gradle/api/**', 'org/gradle/internal/**'] - - List list = new ArraryList() - list.add('org/gradle/api/**') - list.add('org/gradle/internal/**') - test.includes = list - - // Map 集合 - Map map = [key1:'value1', key2:'valu2'] - - // Groovy 会强制将Map的键值对转换为只有value的映射 - apply plugin: 'java' - diff --git a/writing_build_scripts/local_variables.md b/writing_build_scripts/local_variables.md deleted file mode 100644 index 466fc6c..0000000 --- a/writing_build_scripts/local_variables.md +++ /dev/null @@ -1,15 +0,0 @@ -# 局部变量 -局部变量使用关键字 def 来声明,其只在声明它的地方可见 . 局部变量是 Groovy 语言的一个基本特性. - -**例子 13.2 . 使用局部变量** - - def dest = "dest" - - task copy(type: Copy) { - form "source" - into dest - - } - - - diff --git a/writing_build_scripts/optional_parentheses_on_method_calls.md b/writing_build_scripts/optional_parentheses_on_method_calls.md deleted file mode 100644 index b794a73..0000000 --- a/writing_build_scripts/optional_parentheses_on_method_calls.md +++ /dev/null @@ -1,11 +0,0 @@ -# 可有可无的圆括号 -在调用方法时,圆括号可有可无,是个可选的. - -**例子: 13.6.不使用圆括号调用方法** - -**build.gradle** - - test.systemProperty 'some.prop', 'value' - test.systemProperty('some.prop', 'value') - - diff --git a/writing_build_scripts/property_accessors.md b/writing_build_scripts/property_accessors.md deleted file mode 100644 index 1d5bcf5..0000000 --- a/writing_build_scripts/property_accessors.md +++ /dev/null @@ -1,14 +0,0 @@ -# 属性存取器 -Groovy 自动将一个属性的引用转换为相应的 getter 或 setter 方法. - -**例子: 13.5. 属性存取器** - - // 使用 getter 方法 - println project.buildDir - println getProject().getBuildDir() - - // 使用 setter 方法 - project.buildDir = 'target' - getProject().setBuildDir('target') - - diff --git a/writing_build_scripts/some_groovy_basics.md b/writing_build_scripts/some_groovy_basics.md deleted file mode 100644 index 33689e0..0000000 --- a/writing_build_scripts/some_groovy_basics.md +++ /dev/null @@ -1,2 +0,0 @@ -# Groovy 基础 -Groovy 提供了大量的特性用来创建 DSL. Gradle 构建语言知道 Groovy 语言的工作原理,并利用这些特性帮助您编写构建脚本,特别是您在编写 plugin 或者 task 的时候,你会觉得很方便. diff --git a/writing_build_scripts/standard_project_properties.md b/writing_build_scripts/standard_project_properties.md deleted file mode 100644 index cfa521e..0000000 --- a/writing_build_scripts/standard_project_properties.md +++ /dev/null @@ -1,20 +0,0 @@ -# 标准项目属性 -Project 对象提供了一些标准的属性,您可以在构建脚本中很方便的使用他们. 下面列出了常用的属性: - -Name | Type | Default Value -:------|:------|:------ -project | [Project](http://gradle.org/docs/current/dsl/org.gradle.api.Project.html)|Project 实例对象 -name | String | 项目目录的名称 -path | String | 项目的绝对路径 -description| String | 项目描述 -projectDir | File | 包含构建脚本的目录 -build | File | *projectDir*/build -group | Object | 未具体说明 -version | Object | 未具体说明 -ant |[AntBuilder](http://gradle.org/docs/current/javadoc/org/gradle/api/AntBuilder.html) | Ant实例对象 - -**建议:** - -不要忘记我们的构建脚本只是个很简单的 Groovy 代码 ,不过它会再调用 **Gradle API**,[Project](http://gradle.org/docs/current/dsl/org.gradle.api.Project.html) 接口通过调用 ** Gradle API ** 让我们可以操作任何事情,因此如果你想知道哪个标签('tags') 可以在构建脚本种使用,您可以翻阅 Project 接口的的说明文档. - - diff --git a/writing_build_scripts/the_gradle_build_language.md b/writing_build_scripts/the_gradle_build_language.md deleted file mode 100644 index 824fc73..0000000 --- a/writing_build_scripts/the_gradle_build_language.md +++ /dev/null @@ -1,7 +0,0 @@ -# Gradle 构建语言 - -Gradle 是以 Groovy 语言为基础, 基于DSL (领域特定语言) 语法的自动化构建工具,但是它增加了一些额外的特性,这使得Gradle更加的容易去阐释构建. - -一个构建脚本能够包含任何Groovy语言的元素 ( Any language element except for statement labels ), 每个构建脚本都使用UTF-8编码. - - diff --git a/writing_build_scripts/the_project_api.md b/writing_build_scripts/the_project_api.md deleted file mode 100644 index 2e817f4..0000000 --- a/writing_build_scripts/the_project_api.md +++ /dev/null @@ -1,32 +0,0 @@ -# 项目 API - -在第七章 Java构建入门那部分我们使用了 apply() 方法,这个方法是从哪里来的呢? 我们之前说过Gradle在构建脚本中定义了一个项目. 对于构建脚本中每个项目,Gradle 都创建了一个 [Project](http://gradle.org/docs/current/dsl/org.gradle.api.Project.html) 类型的对象用来关联此项目. 当构建脚本执行时,它会去配置所关联的工程对象. - - * 构建脚本中每个被调用的方法(这些方法并未在构建脚本中定义)都被委托给当前工程对象(使用工程对象引用方法)。 - - * 构建脚本中每个被操作的属性(这些属性并未在构建脚本中定义)都被委托给当前工程对象(使用工程对象引用属性). - -让我们尝试下如何操作工程对象的属性. - -例子:13.1 操作工程对象的属性 - - **build.gradle** - - println name - println project.name - - -使用 **gradle -q check** 命令输出结果: - - > gradle -q check - projectApi - projectApi - -如您所见,两个 **println** 语句都输出了相同的属性,第一个输出使用的是自动委托 ( auto-delegation ), 因为当前属性并没有在构建脚本中定义. 另一个语句使用了项目一个属性,这个属性在任何构建脚本中都可用,它的返回值是被关联的工程对象. 只有当您定义了一个属性或者一个方法, 它的名字和工程对象的某个成员的名字相同时, 你应该使用项目属性. - - - - - - - diff --git a/writing_build_scripts/the_script_api.md b/writing_build_scripts/the_script_api.md deleted file mode 100644 index b102be3..0000000 --- a/writing_build_scripts/the_script_api.md +++ /dev/null @@ -1,2 +0,0 @@ -# 脚本 API -当 Gradle 执行一个脚本时,它会将这个脚本编译为实现了 [Script](http://gradle.org/docs/current/dsl/org.gradle.api.Script.html) 的类. 也就是说所有的属性和方法都是在 Script 接口中声明的,由于你的脚本实现了 Script 接口,所以你可以在自己的脚本中使用它们. From e301e2c2bcbc002cefff7db3fa0a43fd2e327689 Mon Sep 17 00:00:00 2001 From: DONG Date: Sun, 1 Apr 2018 22:05:28 +0800 Subject: [PATCH 067/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=B8=B8=E7=94=A8?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../chang-yong-tasks.md | 38 ------------------- .../ming-ling-xing-jie-mian/common-tasks.md | 35 +++++++++++++++++ 3 files changed, 36 insertions(+), 39 deletions(-) delete mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md diff --git a/SUMMARY.md b/SUMMARY.md index 1872721..a435609 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -24,7 +24,7 @@ * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md) - * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md) + * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md deleted file mode 100644 index 3bf9989..0000000 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/chang-yong-tasks.md +++ /dev/null @@ -1,38 +0,0 @@ -# 常用 Tasks - -The following are task conventions applied by built-in and most major Gradle plugins. - -### Computing all outputs - -It is common in Gradle builds for the`build`task to designate assembling all outputs and running all checks. - -``` -❯ gradle build -``` - -### Running applications - -It is common for applications to be run with the`run`task, which assembles the application and executes some script or binary. - -``` -❯ gradle run -``` - -### Running all checks - -It is common for_all_verification tasks, including tests and linting, to be executed using the`check`task. - -``` -❯ gradle check -``` - -### Cleaning outputs - -You can delete the contents of the build directory using the`clean`task, though doing so will cause pre-computed outputs to be lost, causing significant additional build time for the subsequent task execution. - -``` -❯ gradle clean -``` - - - diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md new file mode 100644 index 0000000..6c9e19a --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md @@ -0,0 +1,35 @@ +# 常用 Tasks + +Gradle 本身以及绝大多数 Gradle 插件都包含下列任务, 原文中称这是一种任务约定(task conventions). + +### 计算所有的输出 + +在 Gradle 构建中, `build` 任务被用来集合所有的输出以及运行所有的检查. + +``` +> gradle build +``` + +### 运行应用 + +`run` 任务用来聚合应用, 执行脚本. + +``` +> gradle run +``` + +### 运行所有的检查 + +`check` 任务用来执行所有的检查任务, 包括测试和语法检查. + +``` +> gradle check +``` + +### 清除输出 + +You can delete the contents of the build directory using the`clean` 任务会删除构建目录里的内容, 之前的预计算输出都将丢失, 随后的任务执行时间都将大大加长. + +``` +> gradle clean +``` From 32821ff0376e98c867f4a1746d061443c7208ffd Mon Sep 17 00:00:00 2001 From: DONG Date: Sun, 1 Apr 2018 22:52:20 +0800 Subject: [PATCH 068/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../{zhi-xing-tasks.md => executing-tasks.md} | 43 +++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) rename shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/{zhi-xing-tasks.md => executing-tasks.md} (59%) diff --git a/SUMMARY.md b/SUMMARY.md index a435609..0f85248 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -23,7 +23,7 @@ ## 使用 Gradle 构建 * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) - * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md) + * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md similarity index 59% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md rename to shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md index 7b970d3..5c90938 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/zhi-xing-tasks.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md @@ -3,7 +3,7 @@ 你可以运行一个 task 和它所有的[依赖](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:task_dependencies). ``` -❯ gradle myTask +> gradle myTask ``` ### 在多项目构建中执行 tasks @@ -11,8 +11,8 @@ 在一个 [多项目构建当中](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html), 子项目的 tasks 可以通过在子项目名后添加 ":" 和 task 名来执行: ``` -❯ gradle :mySubproject:taskName -❯ gradle mySubproject:taskName +> gradle :mySubproject:taskName +> gradle mySubproject:taskName ``` > 当从根项目执行时, 上面2个是相等的 @@ -26,8 +26,8 @@ 当在一个子项目中执行命令, 就不需要显式的指定子项目名称, 且该任务只对子项目本身执行: ``` -❯ cd mySubproject -❯ gradle taskName +> cd mySubproject +> gradle taskName ``` 当在子项目中执行 Gradle Wrapper, 必须引用`gradlew`的相对路径. 举个例子:`../gradlew taskName`. 社区 [gdub project](http://www.gdub.rocks/) 可以提供更多的支持. @@ -37,7 +37,7 @@ 你也可以同时指定执行多个任务. 举个例子, 下面的命令将按命令行中的顺序执行`test`和`deploy`命令, 当然, 也会执行各个 task 的依赖: ``` -❯ gradle test deploy +> gradle test deploy ``` ### 从执行中排除 tasks @@ -48,12 +48,12 @@ ![](https://docs.gradle.org/current/userguide/img/commandLineTutorialTasks.png "Example Task Graph") -**Example: Excluding tasks** +**Example: 排除任务** `gradle dist --exclude-task test`的输出: ``` ->gradle dist --exclude-task test +> gradle dist --exclude-task test :compile compiling source :dist @@ -70,36 +70,35 @@ BUILD SUCCESSFUL in 0s 许多任务, 特别是 Gradle 本身提供的任务都支持增量版本. 这些任务可以根据它们的输入或输出自上次运行以来是否发生变化来确定它们是否需要运行. 当 Gradle 在构建运行期间在其名称旁边显示文本`UP-TO-DATE`时,你就可以轻松识别参与增量构建的任务. 但是有时你可能偶尔想强制 Gradle 运行所有的任务, 不需要判断是否需要运行. 如果是这样, 只要使用`--rerun-tasks`选项即可: ``` -❯ gradle test --rerun-tasks +> gradle test --rerun-tasks ``` 该命令就会强制执行`test`以及它所有的依赖. -### Continuing the build when a failure occurs +### 发生错误时继续执行构建 -By default, Gradle will abort execution and fail the build as soon as any task fails. This allows the build to complete sooner, but hides other failures that would have occurred. In order to discover as many failures as possible in a single build execution, you can use the`--continue`option. +默认, 只要任务失败, Gradle 就会放弃执行构建. 随后其他的任务都不会执行了, 但是这样会漏掉这些还未执行的任务里的错误, 你可以使用 `--continue` 选项来解决这个问题. ``` -❯ gradle test --continue +> gradle test --continue ``` -When executed with`--continue`, Gradle will execute\_every\_task to be executed where all of the dependencies for that task completed without failure, instead of stopping as soon as the first failure is encountered. Each of the encountered failures will be reported at the end of the build. +当执行 `--continue` 时, Gradle 将执行每一个任务, 前提是这每一个任务的依赖都不出错. 这样所有可以执行的任务都将执行, 而不是出现第一个错误就停止. 每一个监听到的错误都会在构建结束后打印出来. -If a task fails, any subsequent tasks that were depending on it will not be executed. For example, tests will not run if there is a compilation failure in the code under test; because the test task will depend on the compilation task \(either directly or indirectly\). +如果一个任务失败, 所有随后依赖于它的任务都不会执行. 比如, 如果有个编译错误, 那随后的任务就不会执行. 因为测试任务是依赖于编译任务的(直接或间接). -### Task name abbreviation +### 任务名缩写 -When you specify tasks on the command-line, you don’t have to provide the full name of the task. You only need to provide enough of the task name to uniquely identify the task. For example, it’s likely`gradle che`is enough for Gradle to identify the`check`task. +当你在命令行里写任务名称时, 不需要写任务的全名. 只需要输入能唯一识别该任务的名称即可. 比如, `gradle che` 可以缩写为 `check` 任务. -You can also abbreviate each word in a camel case task name. For example, you can execute task`compileTest`by running`gradle compTest`or even`gradle cT`. +你也可以使用驼峰形式的缩写来识别任务. 比如任务 `compileTest` 可以缩写为 `gradle compTest` 或者 `gradle cT`. -**Example: Abbreviated camel case task name** +**Example: 驼峰式缩写** -Output of`gradle cT` +`gradle cT` 的输出: ``` -> - gradle cT +> gradle cT :compile compiling source :compileTest @@ -109,5 +108,5 @@ BUILD SUCCESSFUL in 0s 2 actionable tasks: 2 executed ``` -You can also use these abbreviations with the -x command-line option. +当使用之前讲的 -x 命令行来排除某个任务执行的时候也可以使用任务名缩写. \ No newline at end of file From a22fcc1ba67e509549cc7f1a915a5d905dc9ec2a Mon Sep 17 00:00:00 2001 From: DONG Date: Mon, 2 Apr 2018 23:30:21 +0800 Subject: [PATCH 069/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=20Debug=20=E9=80=89?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../debug-xuan-xiang.md | 30 ------------------- .../debugging-options.md | 30 +++++++++++++++++++ 3 files changed, 31 insertions(+), 31 deletions(-) delete mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md diff --git a/SUMMARY.md b/SUMMARY.md index 0f85248..11e2fb6 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -27,7 +27,7 @@ * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) - * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md) + * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md) * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md deleted file mode 100644 index 5e091a8..0000000 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debug-xuan-xiang.md +++ /dev/null @@ -1,30 +0,0 @@ -# Debug 选项 - -`-?`,`-h`,`--help` - -Shows a help message with all available CLI options. - -`-v`,`--version` - -Prints Gradle, Groovy, Ant, JVM, and operating system version information. - -`-S`,`--full-stacktrace` - -Print out the full \(very verbose\) stacktrace for any exceptions. See also[logging options](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging). - -`-s`,`--stacktrace` - -Print out the stacktrace also for user exceptions \(e.g. compile error\). See also[logging options](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging). - -`--scan` - -Create a[build scan](https://gradle.com/build-scans)with fine-grained information about all aspects of your Gradle build. - -`-Dorg.gradle.debug=true` - -Debug Gradle client \(non-Daemon\) process. Gradle will wait for you to attach a debugger at`localhost:5005`by default. - -`-Dorg.gradle.daemon.debug=true` - -Debug[Gradle Daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html)process. - diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md new file mode 100644 index 0000000..d0588d7 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md @@ -0,0 +1,30 @@ +# Debug 选项 + +`-?`,`-h`,`--help` + +实现所有命令行选项的帮助信息. + +`-v`,`--version` + +打印 Gradle, Groovy, Ant, JVM 以及操作系统的版本信息. + +`-S`,`--full-stacktrace` + +打印完整的堆栈信息来查找任意异常. 查看[logging 选项](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging)了解更多. + +`-s`,`--stacktrace` + +打印完整的堆栈信息来查看用户异常(user exceptions) \(e.g. 编译错误\). 查看[logging 选项](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging)了解更多. + +`--scan` + +创建 [build scan](https://gradle.com/build-scans) 来查看构建各个方面的详细信息. + +`-Dorg.gradle.debug=true` + +Debug Gradle 客户端进程 \(非守护进程\). 默认的, 你可以在 `localhost:5005` 给 Gradle 添加一个调试器. + +`-Dorg.gradle.daemon.debug=true` + +Debug[守护进程](https://docs.gradle.org/current/userguide/gradle_daemon.html). + From 1f16f24bff70bb7e3af3d9d3482e10e0aa7e155e Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 4 Apr 2018 10:01:57 +0000 Subject: [PATCH 070/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../bootstrapping-new-projects.md | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md diff --git a/SUMMARY.md b/SUMMARY.md index 11e2fb6..af59671 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -32,4 +32,5 @@ * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md) * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md) + * [Bootstrapping new projects](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md new file mode 100644 index 0000000..d06f7db --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md @@ -0,0 +1,24 @@ +### Creating new Gradle builds + +Use the built-in`gradle init`task to create a new Gradle builds, with new or existing projects. + +``` +❯ gradle init +``` + +Most of the time you’ll want to specify a project type. Available types include`basic`\(default\),`java-library`,`java-application`, and more. See[init plugin documentation](https://docs.gradle.org/4.6/userguide/build_init_plugin.html)for details. + +``` +❯ gradle init --type java-library +``` + +### Standardize and provision Gradle + +The built-in`gradle wrapper`task generates a script,`gradlew`, that invokes a declared version of Gradle, downloading it beforehand if necessary. + +``` +❯ gradle wrapper --gradle-version=4.4 +``` + +You can also specify`--distribution-type=(bin|all)`,`--gradle-distribution-url`,`--gradle-distribution-sha256-sum`in addition to`--gradle-version`. Full details on how to use these options are documented in the[Gradle wrapper section](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html). + From c0449d5a1ead029de8276b8c7ef6de07c7e4772a Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 4 Apr 2018 10:02:27 +0000 Subject: [PATCH 071/102] Updates shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../continuous-build.md | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md diff --git a/SUMMARY.md b/SUMMARY.md index af59671..87881d4 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -33,4 +33,5 @@ * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md) * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md) * [Bootstrapping new projects](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md) + * [Continuous Build](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md new file mode 100644 index 0000000..3d11948 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md @@ -0,0 +1,58 @@ +Continuous Build allows you to automatically re-execute the requested tasks when task inputs change. + +For example, you can continuously run the`test`task and all dependent tasks by running: + +``` +❯ gradle test --continuous +``` + +Gradle will behave as if you ran`gradle test`after a change to sources or tests that contribute to the requested tasks. This means that unrelated changes \(such as changes to build scripts\) will not trigger a rebuild. In order to incorporate build logic changes, the continuous build must be restarted manually. + +### Terminating Continuous Build + +If Gradle is attached to an interactive input source, such as a terminal, the continuous build can be exited by pressing`CTRL-D`\(On Microsoft Windows, it is required to also press`ENTER`or`RETURN`after`CTRL-D`\). If Gradle is not attached to an interactive input source \(e.g. is running as part of a script\), the build process must be terminated \(e.g. using the`kill`command or similar\). If the build is being executed via the Tooling API, the build can be cancelled using the Tooling API’s cancellation mechanism. + +### Limitations and quirks + +Continuous build is an[incubating](https://docs.gradle.org/4.6/userguide/feature_lifecycle.html)feature. + +There are several issues to be aware with the current implementation of continuous build. These are likely to be addressed in future Gradle releases. + +#### Build cycles + +Gradle starts watching for changes just before a task executes. If a task modifies its own inputs while executing, Gradle will detect the change and trigger a new build. If every time the task executes, the inputs are modified again, the build will be triggered again. This isn’t unique to continuous build. A task that modifies its own inputs will never be considered up-to-date when run "normally" without continuous build. + +If your build enters a build cycle like this, you can track down the task by looking at the list of files reported changed by Gradle. After identifying the file\(s\) that are changed during each build, you should look for a task that has that file as an input. In some cases, it may be obvious \(e.g., a Java file is compiled with`compileJava`\). In other cases, you can use`--info`logging to find the task that is out-of-date due to the identified files. + +#### Restrictions with Java 9 + +Due to class access restrictions related to Java 9, Gradle cannot set some operating system specific options, which means that: + +* On macOS, Gradle will poll for file changes every 10 seconds instead of every 2 seconds. + +* On Windows, Gradle must use individual file watches \(like on Linux/Mac OS\), which may cause continuous build to no longer work on very large projects. + +#### Performance and stability + +The JDK file watching facility relies on inefficient file system polling on macOS \(see:[JDK-7133447](https://bugs.openjdk.java.net/browse/JDK-7133447)\). This can significantly delay notification of changes on large projects with many source files. + +Additionally, the watching mechanism may deadlock under_heavy_load on macOS \(see:[JDK-8079620](https://bugs.openjdk.java.net/browse/JDK-8079620)\). This will manifest as Gradle appearing not to notice file changes. If you suspect this is occurring, exit continuous build and start again. + +On Linux, OpenJDK’s implementation of the file watch service can sometimes miss file system events \(see:[JDK-8145981](https://bugs.openjdk.java.net/browse/JDK-8145981)\). + +#### Changes to symbolic links + +* Creating or removing symbolic link to files will initiate a build. + +* Modifying the target of a symbolic link will not cause a rebuild. + +* Creating or removing symbolic links to directories will not cause rebuilds. + +* Creating new files in the target directory of a symbolic link will not cause a rebuild. + +* Deleting the target directory will not cause a rebuild. + +#### Changes to build logic are not considered + +The current implementation does not recalculate the build model on subsequent builds. This means that changes to task configuration, or any other change to the build model, are effectively ignored. + From a4ae941994066ee1cb4e7f6657c1d4776e72e5f9 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 4 Apr 2018 10:05:32 +0000 Subject: [PATCH 072/102] Updates shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md Auto commit by GitBook Editor --- SUMMARY.md | 2 + .../customizing-execution.md | 0 .../configuring-build-environment.md | 348 ++++++++++++++++++ 3 files changed, 350 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/customizing-execution.md create mode 100644 shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md diff --git a/SUMMARY.md b/SUMMARY.md index 87881d4..2ec1b0c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -22,6 +22,8 @@ ## 使用 Gradle 构建 +* [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) + * [Configuring Build Environment](shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md) * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) diff --git a/shi-yong-gradle-gou-jian/customizing-execution.md b/shi-yong-gradle-gou-jian/customizing-execution.md new file mode 100644 index 0000000..e69de29 diff --git a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md new file mode 100644 index 0000000..8a793a2 --- /dev/null +++ b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md @@ -0,0 +1,348 @@ +Gradle provides multiple mechanisms for configuring behavior of Gradle itself and specific projects. The following is a reference for using these mechanisms. + +When configuring Gradle behavior you can use these methods, listed in order of highest to lowest precedence \(first one wins\): + +* [Command-line flags](https://docs.gradle.org/4.6/userguide/command_line_interface.html)such as`--build-cache`. These have precedence over properties and environment variables. + +* [System properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_system_properties)such as`systemProp.http.proxyHost=somehost.org`stored in a`gradle.properties`file. + +* [Gradle properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_configuration_properties)such as`org.gradle.caching=true`that are typically stored in a`gradle.properties`file in a project root directory or`GRADLE_USER_HOME`environment variable. + +* [Environment variables](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_environment_variables)such as`GRADLE_OPTS`sourced by the environment that executes Gradle. + +Aside from configuring the build environment, you can configure a given project build using[Project properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:project_properties)such as`-PreleaseType=final`. + +## Gradle properties + +Gradle provides several options that make it easy to configure the Java process that will be used to execute your build. While it’s possible to configure these in your local environment via`GRADLE_OPTS`or`JAVA_OPTS`, it is useful to store certain settings like JVM memory configuration and Java home location in version control so that an entire team can work with a consistent environment. + +Setting up a consistent environment for your build is as simple as placing these settings into a`gradle.properties`file. The configuration is applied in following order \(if an option is configured in multiple locations the_last one wins_\): + +* `gradle.properties`in project root directory. + +* `gradle.properties`in`GRADLE_USER_HOME`directory. + +* system properties, e.g. when`-Dgradle.user.home`is set on the command line. + +The following properties can be used to configure the Gradle build environment: + +`org.gradle.caching=(true,false)` + +When set to true, Gradle will reuse task outputs from any previous build, when possible, resulting is much faster builds. Learn more about[using the build cache](https://docs.gradle.org/4.6/userguide/build_cache.html). + +`org.gradle.caching.debug=(true,false)` + +When set to true, individual input property hashes and the build cache key for each task are logged on the console. Learn more about[task output caching](https://docs.gradle.org/4.6/userguide/build_cache.html#sec:task_output_caching). + +`org.gradle.configureondemand=(true,false)` + +Enables incubating[configuration on demand](https://docs.gradle.org/4.6/userguide/multi_project_builds.html#sec:configuration_on_demand), where Gradle will attempt to configure only necessary projects. + +`org.gradle.console=(auto,plain,rich,verbose)` + +Customize console output coloring or verbosity. Default depends on how Gradle is invoked. See[command-line logging](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_logging)for additional details. + +`org.gradle.daemon=(true,false)` + +When set to`true`the[Gradle Daemon](https://docs.gradle.org/4.6/userguide/gradle_daemon.html)is used to run the build. Default is`true`. + +`org.gradle.daemon.idletimeout=(# of idle millis)` + +Gradle Daemon will terminate itself after specified number of idle milliseconds. Default is`10800000`\(3 hours\). + +`org.gradle.debug=(true,false)` + +When set to`true`, Gradle will run the build with remote debugging enabled, listening on port 5005. Note that this is the equivalent of adding`-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005`to the JVM command line and will suspend the virtual machine until a debugger is attached. Default is`false`. + +`org.gradle.java.home=(path to JDK home)` + +Specifies the Java home for the Gradle build process. The value can be set to either a`jdk`or`jre`location, however, depending on what your build does, using a JDK is safer. A reasonable default is used if the setting is unspecified. + +`org.gradle.jvmargs=(JVM arguments)` + +Specifies the JVM arguments used for the Gradle Daemon. The setting is particularly useful for[configuring JVM memory settings](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:configuring_jvm_memory)for build performance. + +`org.gradle.logging.level=(quiet,warn,lifecycle,info,debug)` + +When set to quiet, warn, lifecycle, info, or debug, Gradle will use this log level. The values are not case sensitive. The`lifecycle`level is the default. See[the section called “Choosing a log level”](https://docs.gradle.org/4.6/userguide/logging.html#sec:choosing_a_log_level). + +`org.gradle.parallel=(true,false)` + +When configured, Gradle will fork up to`org.gradle.workers.max`JVMs to execute projects in parallel. To learn more about parallel task execution, see[the Gradle performance guide](https://guides.gradle.org/performance/#parallel_execution). + +`org.gradle.warning.mode=(all,none,summary)` + +When set to`all`,`summary`or`none`, Gradle will use different warning type display. See[the section called “Logging options”](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_logging)for details. + +`org.gradle.workers.max=(max # of worker processes)` + +When configured, Gradle will use a maximum of the given number of workers. Default is number of CPU processors. See also[performance command-line options](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_performance). + +The following example demonstrates usage of various properties. + + + +**Example: Setting properties with a gradle.properties file** + +`gradle.properties` + +``` +gradlePropertiesProp=gradlePropertiesValue +sysProp=shouldBeOverWrittenBySysProp +envProjectProp=shouldBeOverWrittenByEnvProp +systemProp.system=systemValue + +``` + +`build.gradle` + +``` +task printProps { + doLast { + println commandLineProjectProp + println gradlePropertiesProp + println systemProjectProp + println envProjectProp + println System.properties[ +'system' +] + } +} + +``` + +Output of**`gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps`** + +``` +> + gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps +commandLineProjectPropValue +gradlePropertiesValue +systemPropertyValue +envPropertyValue +systemValue + +``` + +## System properties + +Using the`-D`command-line option, you can pass a system property to the JVM which runs Gradle. The`-D`option of the`gradle`command has the same effect as the`-D`option of the`java`command. + +You can also set system properties in`gradle.properties`files with the prefix`systemProp.` + + + +**Example: Specifying system properties in`gradle.properties`** + +``` +systemProp.gradle.wrapperUser=myuser +systemProp.gradle.wrapperPassword=mypassword +``` + +The following system properties are available. Note that command-line options take precedence over system properties. + +`gradle.wrapperUser=(myuser)` + +Specify user name to download Gradle distributions from servers using HTTP Basic Authentication. Learn more in[the section called “Authenticated Gradle distribution download”](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html#sec:authenticated_download). + +`gradle.wrapperPassword=(mypassword)` + +Specify password for downloading a Gradle distribution using the Gradle wrapper. + +`gradle.user.home=(path to directory)` + +Specify the Gradle user home directory. + +In a multi project build, “`systemProp.`” properties set in any project except the root will be ignored. That is, only the root project’s`gradle.properties`file will be checked for properties that begin with the “`systemProp.`” prefix. + +## Environment variables + +The following environment variables are available for the`gradle`command. Note that command-line options and system properties take precedence over environment variables. + +`GRADLE_OPTS` + +Specifies[command-line arguments](https://docs.gradle.org/4.6/userguide/command_line_interface.html)to use when starting the Gradle client. This can be useful for setting the properties to use when running Gradle. + +`GRADLE_USER_HOME` + +Specifies the Gradle user home directory \(which defaults to`$USER_HOME/.gradle`if not set\). + +`JAVA_HOME` + +Specifies the JDK installation directory to use. + +## Project properties + +You can add properties directly to your[`Project`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html)object via the`-P`command line option. + +Gradle can also set project properties when it sees specially-named system properties or environment variables. If the environment variable name looks like`ORG_GRADLE_PROJECT`_`_prop`_`=somevalue`, then Gradle will set a`prop`property on your project object, with the value of`somevalue`. Gradle also supports this for system properties, but with a different naming pattern, which looks like`org.gradle.project.`_`prop`_. Both of the following will set the`foo`property on your Project object to`"bar"`. + + + +**Example: Setting a project property via gradle.properties** + +``` +org.gradle.project.foo=bar +``` + + + +**Example: Setting a project property via environment variable** + +``` +ORG_GRADLE_PROJECT_foo=bar +``` + +The properties file in the user’s home directory has precedence over property files in the project directories. + +This feature is very useful when you don’t have admin rights to a continuous integration server and you need to set property values that should not be easily visible. Since you cannot use the`-P`option in that scenario, nor change the system-level configuration files, the correct strategy is to change the configuration of your continuous integration build job, adding an environment variable setting that matches an expected pattern. This won’t be visible to normal users on the system. + +You can access a project property in your build script simply by using its name as you would use a variable. + +If a project property is referenced but does not exist, an exception will be thrown and the build will fail. + +You should check for existence of optional project properties before you access them using the[`Project.hasProperty(java.lang.String)`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html#org.gradle.api.Project:hasProperty%28java.lang.String%29)method. + +## Configuring JVM memory + +Gradle defaults to 1024 megabytes maximum heap per JVM process \(`-Xmx1024m`\), however, that may be too much or too little depending on the size of your project. There are many JVM options \(this[blog post on Java performance tuning](https://dzone.com/articles/java-performance-tuning)and[this reference](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)may be helpful\). + +You can adjust JVM options for Gradle in the following ways: + +The`JAVA_OPTS`environment variable is used for the Gradle client, but not forked JVMs. + + + +**Example: Changing JVM settings for Gradle client JVM** + +``` +JAVA_OPTS="-Xmx2g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" +``` + +You need to use the`org.gradle.jvmargs`Gradle property to configure JVM settings for the[Gradle Daemon](https://docs.gradle.org/4.6/userguide/gradle_daemon.html). + + + +**Example: Changing JVM settings for forked Gradle JVMs** + +``` +org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +``` + +Many settings \(like the Java version and maximum heap size\) can only be specified when launching a new JVM for the build process. This means that Gradle must launch a separate JVM process to execute the build after parsing the various`gradle.properties`files. + +When running with the[Gradle Daemon](https://docs.gradle.org/4.6/userguide/gradle_daemon.html), a JVM with the correct parameters is started once and reused for each daemon build execution. When Gradle is executed without the daemon, then a new JVM must be launched for every build execution, unless the JVM launched by the Gradle start script happens to have the same parameters. + +Certain tasks in Gradle also fork additional JVM processes, like the`test`task when using[`Test.setMaxParallelForks(int)`](https://docs.gradle.org/4.6/javadoc/org/gradle/api/tasks/testing/Test.html#setMaxParallelForks-int-)for JUnit or TestNG tests. You must configure these through the tasks themselves. + + + +**Example: Set Java compile options for**[**`JavaCompile`**](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.compile.JavaCompile.html)**tasks** + +``` +apply plugin: "java" + +tasks.withType(JavaCompile) { + options.compilerArgs += ["-Xdoclint:none", "-Xlint:none", "-nowarn"] +} +``` + +See other examples in the[`Test`](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.testing.Test.html)API documentation and[test execution in the Java plugin reference](https://docs.gradle.org/4.6/userguide/java_plugin.html#sec:test_execution). + +[Build scans](https://scans.gradle.com/)will tell you information about the JVM that executed the build when you use the`--scan`option. + +[![](https://docs.gradle.org/4.6/userguide/img/build-scan-infrastructure.png "Build Environment in build scan")](https://scans.gradle.com/s/sample/cpp-parallel/infrastructure) + +## Configuring a task using project properties + +It’s possible to change the behavior of a task based on project properties specified at invocation time. + +Suppose you’d like to ensure release builds are only triggered by CI. A simple way to handle this is through an`isCI`project property. + + + +**Example: Prevent releasing outside of CI** + +`build.gradle` + +``` +task performRelease { + doLast { + +if + (project.hasProperty( +"isCI" +)) { + println( +"Performing release actions" +) + } +else + { + +throw +new + InvalidUserDataException( +"Cannot perform release outside of CI" +) + } + } +} + +``` + +Output of**`gradle performRelease -PisCI=true --quiet`** + +``` +> + gradle performRelease -PisCI=true --quiet +Performing release actions + +``` + +## Accessing the web through a HTTP proxy + +Configuring an HTTP or HTTPS proxy \(for downloading dependencies, for example\) is done via standard JVM system properties. These properties can be set directly in the build script; for example, setting the HTTP proxy host would be done with`System.setProperty('http.proxyHost', 'www.somehost.org')`. Alternatively, the properties can be[specified in gradle.properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_configuration_properties). + + + +**Example: Configuring an HTTP proxy using`gradle.properties`** + +``` +systemProp.http.proxyHost=www.somehost.org +systemProp.http.proxyPort=8080 +systemProp.http.proxyUser=userid +systemProp.http.proxyPassword=password +systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost +``` + +There are separate settings for HTTPS. + + + +**Example: Configuring an HTTPS proxy using`gradle.properties`** + +``` +systemProp.https.proxyHost=www.somehost.org +systemProp.https.proxyPort=8080 +systemProp.https.proxyUser=userid +systemProp.https.proxyPassword=password +systemProp.https.nonProxyHosts=*.nonproxyrepos.com|localhost +``` + +You may need to set other properties to access other networks. Here are 2 references that may be helpful: + +* [ProxySetup.java in the Ant codebase](https://git-wip-us.apache.org/repos/asf?p=ant.git;a=blob;f=src/main/org/apache/tools/ant/util/ProxySetup.java;hb=HEAD) + +* [JDK 7 Networking Properties](http://download.oracle.com/javase/7/docs/technotes/guides/net/properties.html) + +### NTLM Authentication + +If your proxy requires NTLM authentication, you may need to provide the authentication domain as well as the username and password. There are 2 ways that you can provide the domain for authenticating to a NTLM proxy: + +* Set the`http.proxyUser`system property to a value like_`domain`_`/`_`username`_. + +* Provide the authentication domain via the`http.auth.ntlm.domain`system property. + + + From 3f45fbaf861037e958346ff86b063bc755f5ee33 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 4 Apr 2018 10:06:10 +0000 Subject: [PATCH 073/102] Updates shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../configuring-gradle-daemon.md | 194 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md diff --git a/SUMMARY.md b/SUMMARY.md index 2ec1b0c..17646ed 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -24,6 +24,7 @@ * [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) * [Configuring Build Environment](shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md) + * [Configuring Gradle Daemon](shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md) * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) diff --git a/shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md b/shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md new file mode 100644 index 0000000..6965a5d --- /dev/null +++ b/shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md @@ -0,0 +1,194 @@ +From Wikipedia… + +> A daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user. + +Gradle runs on the Java Virtual Machine \(JVM\) and uses several supporting libraries that require a non-trivial initialization time. As a result, it can sometimes seem a little slow to start. The solution to this problem is the Gradle_Daemon_: a long-lived background process that executes your builds much more quickly than would otherwise be the case. We accomplish this by avoiding the expensive bootstrapping process as well as leveraging caching, by keeping data about your project in memory. Running Gradle builds with the Daemon is no different than without. Simply configure whether you want to use it or not - everything else is handled transparently by Gradle. + +## Why the Gradle Daemon is important for performance + +The Daemon is a long-lived process, so not only are we able to avoid the cost of JVM startup for every build, but we are able to cache information about project structure, files, tasks, and more in memory. + +The reasoning is simple: improve build speed by reusing computations from previous builds. However, the benefits are dramatic: we typically measure build times reduced by 15-75% on subsequent builds. We recommend profiling your build by using`--profile`to get a sense of how much impact the Gradle Daemon can have for you. + +The Gradle Daemon is enabled by default starting with Gradle 3.0, so you don’t have to do anything to benefit from it. + +If you run CI builds in ephemeral environments \(such as containers\) that do not reuse any processes, use of the Daemon will slightly decrease performance \(due to caching additional information\) for no benefit, and may be disabled. + +## Running Daemon Status + +To get a list of running Gradle Daemons and their statuses use the`--status`command. + +Sample output: + +``` + PID VERSION STATUS +28411 3.0 IDLE +34247 3.0 BUSY +``` + +Currently, a given Gradle version can only connect to daemons of the same version. This means the status output will only show Daemons for the version of Gradle being invoked and not for any other versions. Future versions of Gradle will lift this constraint and will show the running Daemons for all versions of Gradle. + +## Disabling the Daemon + +The Gradle Daemon is enabled by default, and we recommend always enabling it. There are several ways to disable the Daemon, but the most common one is to add the line + +``` +org.gradle.daemon=false +``` + +to the file`«USER_HOME»/.gradle/gradle.properties`, where`«USER_HOME»`is your home directory. That’s typically one of the following, depending on your platform: + +* `C:\Users\`\(Windows Vista & 7+\) + +* `/Users/`\(macOS\) + +* `/home/`\(Linux\) + +If that file doesn’t exist, just create it using a text editor. You can find details of other ways to disable \(and enable\) the Daemon in[the section called “FAQ”](https://docs.gradle.org/4.6/userguide/gradle_daemon.html#daemon_faq)further down. That section also contains more detailed information on how the Daemon works. + +Note that having the Daemon enabled, all your builds will take advantage of the speed boost, regardless of the version of Gradle a particular build uses. + +### Continuous integration + +Since Gradle 3.0, we enable Daemon by default and recommend using it for both developers' machines and Continuous Integration servers. However, if you suspect that Daemon makes your CI builds unstable, you can disable it to use a fresh runtime for each build since the runtime is_completely_isolated from any previous builds. + +## Stopping an existing Daemon + +As mentioned, the Daemon is a background process. You needn’t worry about a build up of Gradle processes on your machine, though. Every Daemon monitors its memory usage compared to total system memory and will stop itself if idle when available system memory is low. If you want to explicitly stop running Daemon processes for any reason, just use the command`gradle --stop`. + +This will terminate all Daemon processes that were started with the same version of Gradle used to execute the command. If you have the Java Development Kit \(JDK\) installed, you can easily verify that a Daemon has stopped by running the`jps`command. You’ll see any running Daemons listed with the name`GradleDaemon`. + +## FAQ + +### How do I disable the Gradle Daemon? + +There are two recommended ways to disable the Daemon persistently for an environment: + +* Via environment variables: add the flag`-Dorg.gradle.daemon=false`to the`GRADLE_OPTS`environment variable + +* Via properties file: add`org.gradle.daemon=false`to the`«GRADLE_USER_HOME»/gradle.properties`file + +Note,`«GRADLE_USER_HOME»`defaults to`«USER_HOME»/.gradle`, where`«USER_HOME»`is the home directory of the current user. This location can be configured via the`-g`and`--gradle-user-home`command line switches, as well as by the`GRADLE_USER_HOME`environment variable and`org.gradle.user.home`JVM system property. + +Both approaches have the same effect. Which one to use is up to personal preference. Most Gradle users choose the second option and add the entry to the user`gradle.properties`file. + +On Windows, this command will disable the Daemon for the current user: + +``` +(if not exist "%USERPROFILE%/.gradle" mkdir "%USERPROFILE%/.gradle") +& +& + (echo. +> +> + "%USERPROFILE%/.gradle/gradle.properties" +& +& + echo org.gradle.daemon=false +> +> + "%USERPROFILE%/.gradle/gradle.properties") +``` + +On UNIX-like operating systems, the following Bash shell command will disable the Daemon for the current user: + +``` +mkdir -p ~/.gradle +& +& + echo "org.gradle.daemon=false" +> +> + ~/.gradle/gradle.properties +``` + +Once the Daemon is disabled for a build environment in this way, a Gradle Daemon will not be started unless explicitly requested using the`--daemon`option. + +The`--daemon`and`--no-daemon`command line options enable and disable usage of the Daemon for individual build invocations when using the Gradle command line interface. These command line options have the_highest_precedence when considering the build environment. Typically, it is more convenient to enable the Daemon for an environment \(e.g. a user account\) so that all builds use the Daemon without requiring to remember to supply the`--daemon`option. + +### Why is there more than one Daemon process on my machine? + +There are several reasons why Gradle will create a new Daemon, instead of using one that is already running. The basic rule is that Gradle will start a new Daemon if there are no existing idle or compatible Daemons available. Gradle will kill any Daemon that has been idle for 3 hours or more, so you don’t have to worry about cleaning them up manually. + +idle + +An idle Daemon is one that is not currently executing a build or doing other useful work. + +compatible + +A compatible Daemon is one that can \(or can be made to\) meet the requirements of the requested build environment. The Java runtime used to execute the build is an example aspect of the build environment. Another example is the set of JVM system properties required by the build runtime. + +Some aspects of the requested build environment may not be met by an Daemon. If the Daemon is running with a Java 7 runtime, but the requested environment calls for Java 8, then the Daemon is not compatible and another must be started. Moreover, certain properties of a Java runtime cannot be changed once the JVM has started. For example, it is not possible to change the memory allocation \(e.g.`-Xmx1024m`\), default text encoding, default locale, etc of a running JVM. + +The “requested build environment” is typically constructed implicitly from aspects of the build client’s \(e.g. Gradle command line client, IDE etc.\) environment and explicitly via command line switches and settings. See[Build Environment](https://docs.gradle.org/4.6/userguide/build_environment.html)for details on how to specify and control the build environment. + +The following JVM system properties are effectively immutable. If the requested build environment requires any of these properties, with a different value than a Daemon’s JVM has for this property, the Daemon is not compatible. + +* file.encoding + +* user.language + +* user.country + +* user.variant + +* java.io.tmpdir + +* javax.net.ssl.keyStore + +* javax.net.ssl.keyStorePassword + +* javax.net.ssl.keyStoreType + +* javax.net.ssl.trustStore + +* javax.net.ssl.trustStorePassword + +* javax.net.ssl.trustStoreType + +* com.sun.management.jmxremote + +The following JVM attributes, controlled by startup arguments, are also effectively immutable. The corresponding attributes of the requested build environment and the Daemon’s environment must match exactly in order for a Daemon to be compatible. + +* The maximum heap size \(i.e. the -Xmx JVM argument\) + +* The minimum heap size \(i.e. the -Xms JVM argument\) + +* The boot classpath \(i.e. the -Xbootclasspath argument\) + +* The “assertion” status \(i.e. the -ea argument\) + +The required Gradle version is another aspect of the requested build environment. Daemon processes are coupled to a specific Gradle runtime. Working on multiple Gradle projects during a session that use different Gradle versions is a common reason for having more than one running Daemon process. + +### How much memory does the Daemon use and can I give it more? + +If the requested build environment does not specify a maximum heap size, the Daemon will use up to 1GB of heap. It will use the JVM’s default minimum heap size. 1GB is more than enough for most builds. Larger builds with hundreds of subprojects, lots of configuration, and source code may require, or perform better, with more memory. + +To increase the amount of memory the Daemon can use, specify the appropriate flags as part of the requested build environment. Please see[Build Environment](https://docs.gradle.org/4.6/userguide/build_environment.html)for details. + +### How can I stop a Daemon? + +Daemon processes will automatically terminate themselves after 3 hours of inactivity or less. If you wish to stop a Daemon process before this, you can either kill the process via your operating system or run the`gradle --stop`command. The`--stop`switch causes Gradle to request that_all_running Daemon processes,_of the same Gradle version used to run the command_, terminate themselves. + +### What can go wrong with Daemon? + +Considerable engineering effort has gone into making the Daemon robust, transparent and unobtrusive during day to day development. However, Daemon processes can occasionally be corrupted or exhausted. A Gradle build executes arbitrary code from multiple sources. While Gradle itself is designed for and heavily tested with the Daemon, user build scripts and third party plugins can destabilize the Daemon process through defects such as memory leaks or global state corruption. + +It is also possible to destabilize the Daemon \(and build environment in general\) by running builds that do not release resources correctly. This is a particularly poignant problem when using Microsoft Windows as it is less forgiving of programs that fail to close files after reading or writing. + +Gradle actively monitors heap usage and attempts to detect when a leak is starting to exhaust the available heap space in the daemon. When it detects a problem, the Gradle daemon will finish the currently running build and proactively restart the daemon on the next build. This monitoring is enabled by default, but can be disabled by setting the`org.gradle.daemon.performance.enable-monitoring`system property to false. + +If it is suspected that the Daemon process has become unstable, it can simply be killed. Recall that the`--no-daemon`switch can be specified for a build to prevent use of the Daemon. This can be useful to diagnose whether or not the Daemon is actually the culprit of a problem. + +## Tools & IDEs + +The Gradle Tooling API \(see[Embedding Gradle using the Tooling API](https://docs.gradle.org/4.6/userguide/embedding.html)\), that is used by IDEs and other tools to integrate with Gradle,_always_use the Gradle Daemon to execute builds. If you are executing Gradle builds from within you’re IDE you are using the Gradle Daemon and do not need to enable it for your environment. + +## How does the Gradle Daemon make builds faster? + +The Gradle Daemon is a_long lived_build process. In between builds it waits idly for the next build. This has the obvious benefit of only requiring Gradle to be loaded into memory once for multiple builds, as opposed to once for each build. This in itself is a significant performance optimization, but that’s not where it stops. + +A significant part of the story for modern JVM performance is runtime code optimization. For example, HotSpot \(the JVM implementation provided by Oracle and used as the basis of OpenJDK\) applies optimization to code while it is running. The optimization is progressive and not instantaneous. That is, the code is progressively optimized during execution which means that subsequent builds can be faster purely due to this optimization process. Experiments with HotSpot have shown that it takes somewhere between 5 and 10 builds for optimization to stabilize. The difference in perceived build time between the first build and the 10th for a Daemon can be quite dramatic. + +The Daemon also allows more effective in memory caching across builds. For example, the classes needed by the build \(e.g. plugins, build scripts\) can be held in memory between builds. Similarly, Gradle can maintain in-memory caches of build data such as the hashes of task inputs and outputs, used for incremental building. + From a3f1586bb663e0667b38d457ccdfc13418ab668b Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 4 Apr 2018 10:06:37 +0000 Subject: [PATCH 074/102] Updates shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + .../initialization-scripts.md | 262 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md diff --git a/SUMMARY.md b/SUMMARY.md index 17646ed..1038f2f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -25,6 +25,7 @@ * [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) * [Configuring Build Environment](shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md) * [Configuring Gradle Daemon](shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md) + * [Initialization Scripts](shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md) * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) diff --git a/shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md b/shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md new file mode 100644 index 0000000..067dd3d --- /dev/null +++ b/shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md @@ -0,0 +1,262 @@ +Gradle provides a powerful mechanism to allow customizing the build based on the current environment. This mechanism also supports tools that wish to integrate with Gradle. + +Note that this is completely different from the “`init`” task provided by the “`build-init`” incubating plugin \(see[Build Init Plugin](https://docs.gradle.org/4.6/userguide/build_init_plugin.html)\). + +## Basic usage + +Initialization scripts \(a.k.a._init scripts_\) are similar to other scripts in Gradle. These scripts, however, are run before the build starts. Here are several possible uses: + +* Set up enterprise-wide configuration, such as where to find custom plugins. + +* Set up properties based on the current environment, such as a developer’s machine vs. a continuous integration server. + +* Supply personal information about the user that is required by the build, such as repository or database authentication credentials. + +* Define machine specific details, such as where JDKs are installed. + +* Register build listeners. External tools that wish to listen to Gradle events might find this useful. + +* Register build loggers. You might wish to customize how Gradle logs the events that it generates. + +One main limitation of init scripts is that they cannot access classes in the`buildSrc`project \(see[the section called “Build sources in the`buildSrc`project”](https://docs.gradle.org/4.6/userguide/organizing_build_logic.html#sec:build_sources)for details of this feature\). + +## Using an init script + +There are several ways to use an init script: + +* Specify a file on the command line. The command line option is`-I`or`--init-script`followed by the path to the script. The command line option can appear more than once, each time adding another init script. + +* Put a file called`init.gradle`in the_`USER_HOME`_`/.gradle/`directory. + +* Put a file that ends with`.gradle`in the_`USER_HOME`_`/.gradle/init.d/`directory. + +* Put a file that ends with`.gradle`in the_`GRADLE_HOME`_`/init.d/`directory, in the Gradle distribution. This allows you to package up a custom Gradle distribution containing some custom build logic and plugins. You can combine this with the[Gradle wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html)as a way to make custom logic available to all builds in your enterprise. + +If more than one init script is found they will all be executed, in the order specified above. Scripts in a given directory are executed in alphabetical order. This allows, for example, a tool to specify an init script on the command line and the user to put one in their home directory for defining the environment and both scripts will run when Gradle is executed. + +## Writing an init script + +Similar to a Gradle build script, an init script is a Groovy script. Each init script has a[`Gradle`](https://docs.gradle.org/4.6/dsl/org.gradle.api.invocation.Gradle.html)instance associated with it. Any property reference and method call in the init script will delegate to this`Gradle`instance. + +Each init script also implements the[`Script`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Script.html)interface. + +### Configuring projects from an init script + +You can use an init script to configure the projects in the build. This works in a similar way to configuring projects in a multi-project build. The following sample shows how to perform extra configuration from an init script_before_the projects are evaluated. This sample uses this feature to configure an extra repository to be used only for certain environments. + + + +**Example: Using init script to perform extra configuration before projects are evaluated** + +`build.gradle` + +``` +repositories { + mavenCentral() +} + +task showRepos { + doLast { + println +"All repos:" + + println repositories.collect { it.name } + } +} + +``` + +`init.gradle` + +``` +allprojects { + repositories { + mavenLocal() + } +} + +``` + +Output of**`gradle --init-script init.gradle -q showRepos`** + +``` +> + gradle --init-script init.gradle -q showRepos +All repos: +[MavenLocal, MavenRepo] +``` + +## External dependencies for the init script + +In[the section called “External dependencies for the build script”](https://docs.gradle.org/4.6/userguide/organizing_build_logic.html#sec:build_script_external_dependencies)it was explained how to add external dependencies to a build script. Init scripts can also declare dependencies. You do this with the`initscript()`method, passing in a closure which declares the init script classpath. + + + +**Example: Declaring external dependencies for an init script** + +`init.gradle` + +``` +initscript { + repositories { + mavenCentral() + } + dependencies { + classpath group: +'org.apache.commons' +, name: +'commons-math' +, version: +'2.0' + + } +} + +``` + +The closure passed to the`initscript()`method configures a[`ScriptHandler`](https://docs.gradle.org/4.6/javadoc/org/gradle/api/initialization/dsl/ScriptHandler.html)instance. You declare the init script classpath by adding dependencies to the`classpath`configuration. This is the same way you declare, for example, the Java compilation classpath. You can use any of the dependency types described in[Declaring Dependencies](https://docs.gradle.org/4.6/userguide/declaring_dependencies.html), except project dependencies. + +Having declared the init script classpath, you can use the classes in your init script as you would any other classes on the classpath. The following example adds to the previous example, and uses classes from the init script classpath. + + + +**Example: An init script with external dependencies** + +`init.gradle` + +``` +import + org.apache.commons.math.fraction.Fraction + +initscript { + repositories { + mavenCentral() + } + dependencies { + classpath group: +'org.apache.commons' +, name: +'commons-math' +, version: +'2.0' + + } +} + +println Fraction.ONE_FIFTH.multiply( +2 +) + +``` + +Output of**`gradle --init-script init.gradle -q doNothing`** + +``` +> + gradle --init-script init.gradle -q doNothing +2 / 5 + +``` + +## Init script plugins + +Similar to a Gradle build script or a Gradle settings file, plugins can be applied on init scripts. + + + +**Example: Using plugins in init scripts** + +`init.gradle` + +``` +apply plugin:EnterpriseRepositoryPlugin + + +class + EnterpriseRepositoryPlugin +implements + Plugin +< +Gradle +> + { + + +private +static + String ENTERPRISE_REPOSITORY_URL = +"https://repo.gradle.org/gradle/repo" +void + apply(Gradle gradle) { + +// ONLY USE ENTERPRISE REPO FOR DEPENDENCIES + + gradle.allprojects{ project - +> + + project.repositories { + + +// Remove all repositories not pointing to the enterprise repository url + + all { ArtifactRepository repo - +> +if + (!(repo +instanceof + MavenArtifactRepository) || + repo.url.toString() != ENTERPRISE_REPOSITORY_URL) { + project.logger.lifecycle +"Repository ${repo.url} removed. Only $ENTERPRISE_REPOSITORY_URL is allowed" + + remove repo + } + } + + +// add the enterprise repository + + maven { + name +"STANDARD_ENTERPRISE_REPO" + + url ENTERPRISE_REPOSITORY_URL + } + } + } + } +} + +``` + +`build.gradle` + +``` +repositories{ + mavenCentral() +} + + task showRepositories { + doLast { + repositories.each { + println +"repository: ${it.name} ('${it.url}')" + + } + } +} + +``` + +Output of**`gradle -q -I init.gradle showRepositories`** + +``` +> + gradle -q -I init.gradle showRepositories +repository: STANDARD_ENTERPRISE_REPO ('https://repo.gradle.org/gradle/repo') +``` + +The plugin in the init script ensures that only a specified repository is used when running the build. + +When applying plugins within the init script, Gradle instantiates the plugin and calls the plugin instance’s[`Plugin.apply(T)`](https://docs.gradle.org/4.6/javadoc/org/gradle/api/Plugin.html#apply-T-)method. The`gradle`object is passed as a parameter, which can be used to configure all aspects of a build. Of course, the applied plugin can be resolved as an external dependency as described in[the section called “External dependencies for the init script”](https://docs.gradle.org/4.6/userguide/init_scripts.html#sec:custom_classpath) + From 8573d70da72d94d9603c46ddfcb01541ab2eabe0 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 4 Apr 2018 10:07:20 +0000 Subject: [PATCH 075/102] Updates executing-multi-project-builds.md Auto commit by GitBook Editor --- SUMMARY.md | 9 ++-- executing-multi-project-builds.md | 84 +++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 executing-multi-project-builds.md diff --git a/SUMMARY.md b/SUMMARY.md index 1038f2f..0006264 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -22,10 +22,6 @@ ## 使用 Gradle 构建 -* [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) - * [Configuring Build Environment](shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md) - * [Configuring Gradle Daemon](shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md) - * [Initialization Scripts](shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md) * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) @@ -38,4 +34,9 @@ * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md) * [Bootstrapping new projects](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md) * [Continuous Build](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md) +* [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) + * [Configuring Build Environment](shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md) + * [Configuring Gradle Daemon](shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md) + * [Initialization Scripts](shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md) +* [Executing Multi-Project Builds](executing-multi-project-builds.md) diff --git a/executing-multi-project-builds.md b/executing-multi-project-builds.md new file mode 100644 index 0000000..368397b --- /dev/null +++ b/executing-multi-project-builds.md @@ -0,0 +1,84 @@ +# Executing Multi-Project Builds + +[Structure of a multi-project build](https://docs.gradle.org/4.6/userguide/intro_multi_project_builds.html#sec:structure_of_a_multiproject_build) + +[Executing a multi-project build](https://docs.gradle.org/4.6/userguide/intro_multi_project_builds.html#sec:executing_a_multiproject_build) + +Only the smallest of projects has a single build file and source tree, unless it happens to be a massive, monolithic application. It’s often much easier to digest and understand a project that has been split into smaller, inter-dependent modules. The word “inter-dependent” is important, though, and is why you typically want to link the modules together through a single build. + +Gradle supports this scenario through_multi-project_builds. + +## Structure of a multi-project build + +Such builds come in all shapes and sizes, but they do have some common characteristics: + +* A`settings.gradle`file in the root or`master`directory of the project + +* A`build.gradle`file in the root or`master`directory + +* Child directories that have their own`*.gradle`build files \(some multi-project builds may omit child project build scripts\) + +The`settings.gradle`file tells Gradle how the project and subprojects are structured. Fortunately, you don’t have to read this file simply to learn what the project structure is as you can run the command`gradle projects`. Here’s the output from using that command on the Java_multiproject_build in the Gradle samples: + + + +**Example: Listing the projects in a build** + +Output of**`gradle -q projects`** + +``` +> + gradle -q projects + +------------------------------------------------------------ +Root project +------------------------------------------------------------ + +Root project 'multiproject' ++--- Project ':api' ++--- Project ':services' +| +--- Project ':services:shared' +| \--- Project ':services:webservice' +\--- Project ':shared' + +To see a list of the tasks of a project, run gradle +< +project-path +> +:tasks +For example, try running gradle :api:tasks + +``` + +This tells you that_multiproject_has three immediate child projects:_api_,_services_and_shared_. The_services_project then has its own children,_shared_and_webservice_. These map to the directory structure, so it’s easy to find them. For example, you can find_webservice_in`/services/webservice`. + +By default, Gradle uses the name of the directory it finds the`settings.gradle`as the name of the root project. This usually doesn’t cause problems since all developers check out the same directory name when working on a project. On Continuous Integration servers, like Jenkins, the directory name may be auto-generated and not match the name in your VCS. For that reason, it’s recommended that you always set the root project name to something predictable, even in single project builds. You can configure the root project name by setting`rootProject.name`. + +Each project will usually have its own build file, but that’s not necessarily the case. In the above example, the_services_project is just a container or grouping of other subprojects. There is no build file in the corresponding directory. However,_multiproject_does have one for the root project. + +The root`build.gradle`is often used to share common configuration between the child projects, for example by applying the same sets of plugins and dependencies to all the child projects. It can also be used to configure individual subprojects when it is preferable to have all the configuration in one place. This means you should always check the root build file when discovering how a particular subproject is being configured. + +Another thing to bear in mind is that the build files might not be called`build.gradle`. Many projects will name the build files after the subproject names, such as`api.gradle`and`services.gradle`from the previous example. Such an approach helps a lot in IDEs because it’s tough to work out which`build.gradle`file out of twenty possibilities is the one you want to open. This little piece of magic is handled by the`settings.gradle`file, but as a build user you don’t need to know the details of how it’s done. Just have a look through the child project directories to find the files with the`.gradle`suffix. + +Once you know what subprojects are available, the key question for a build user is how to execute the tasks within the project. + +## Executing a multi-project build + +From a user’s perspective, multi-project builds are still collections of tasks you can run. The difference is that you may want to control_which_project’s tasks get executed. You have two options here: + +* Change to the directory corresponding to the subproject you’re interested in and just execute`gradle `as normal. + +* Use a qualified task name from any directory, although this is usually done from the root. For example:`gradle :services:webservice:build`will build the_webservice_subproject and any subprojects it depends on. + +The first approach is similar to the single-project use case, but Gradle works slightly differently in the case of a multi-project build. The command`gradle test`will execute the`test`task in any subprojects, relative to the current working directory, that have that task. So if you run the command from the root project directory, you’ll run`test`in_api_,_shared_,_services:shared_and_services:webservice_. If you run the command from the services project directory, you’ll only execute the task in_services:shared_and_services:webservice_. + +For more control over what gets executed, use qualified names \(the second approach mentioned\). These are paths just like directory paths, but use ‘:’ instead of ‘/’ or ‘\’. If the path begins with a ‘:’, then the path is resolved relative to the root project. In other words, the leading ‘:’ represents the root project itself. All other colons are path separators. + +This approach works for any task, so if you want to know what tasks are in a particular subproject, just use the`tasks`task, e.g.`gradle :services:webservice:tasks`. + +Regardless of which technique you use to execute tasks, Gradle will take care of building any subprojects that the target depends on. You don’t have to worry about the inter-project dependencies yourself. If you’re interested in how this is configured, you can read about writing multi-project builds[later in the user guide](https://docs.gradle.org/4.6/userguide/multi_project_builds.html). + +There’s one last thing to note. When you’re using the Gradle wrapper, the first approach doesn’t work well because you have to specify the path to the wrapper script if you’re not in the project root. For example, if you’re in the_webservice_subproject directory, you would have to run`../../gradlew build`. + +That’s all you really need to know about multi-project builds as a build user. You can now identify whether a build is a multi-project one and you can discover its structure. And finally, you can execute tasks within specific subprojects. + From b7a3e3e98f1a98bc0ef3efb5e619f5ffc4fc0173 Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 09:26:50 +0800 Subject: [PATCH 076/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../environment-options.md | 48 +++++++++++++++++++ .../environment-xuan-xiang.md | 48 ------------------- 3 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md delete mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md diff --git a/SUMMARY.md b/SUMMARY.md index 0006264..159facb 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -31,7 +31,7 @@ * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md) - * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md) + * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md) * [Bootstrapping new projects](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md) * [Continuous Build](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md) * [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md new file mode 100644 index 0000000..3fea13e --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md @@ -0,0 +1,48 @@ +# Environment 选项 + +Gradle 的许多方面都可以通过以下的选项被自定义, 比如构建脚本的位置, 设置, 缓存等等. 你可以通过学习[构建环境](https://docs.gradle.org/current/userguide/build_environment.html)来自定义你的构建. + +`-b`,`--build-file` + +指定构建文件. 比如:`gradle --build-file=foo.gradle`, 因为默认的文件是`build.gradle`, 如果没找到, 将依次寻找`build.gradle.kts` 和 `myProjectName.gradle`. 通过使用这个选项, Gradle 将直接查找 foo.gradle 文件作为构建文件. + +`-c`,`--settings-file` + +指定设置文件. 比如:`gradle --settings-file=somewhere/else/settings.gradle` + +`-g`,`--gradle-user-home` + +指定 Gradle 默认的用户 home 路径. 默认是用户 home 目录下的 `.gradle` 文件目录. + +`-p`,`--project-dir` + +指定 Gradle 开始构建的文件夹, 或者说是需要构建的项目所在的文件夹, 默认是当前文件夹. + +`--project-cache-dir` + +指定项目相关的缓存文件夹. 默认是项目根目录的 `.gradle` 文件夹. + +`-u`,`--no-search-upward`\(deprecated\) + +不要去父文件夹寻找 `settings.gradle` 文件. + +`-D`,`--system-prop` + +设置 JVM 的一个系统属性, 比如 `-Dmyprop=myvalue`. 查看[系统属性](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_system_properties)了解更多. + +`-I`,`--init-script` + +指定初始化脚本. 查看[初始化脚本](https://docs.gradle.org/current/userguide/init_scripts.html)了解更多. + +`-P`,`--project-prop` + +设置根项目的一个项目属性,比如 `-Pmyprop=myvalue`. 查看[项目属性](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties)了解更多. + +`-Dorg.gradle.jvmargs` + +设置 JVM 参数. + +`-Dorg.gradle.java.home` + +设置 JDK home 目录. + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md deleted file mode 100644 index 8523497..0000000 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-xuan-xiang.md +++ /dev/null @@ -1,48 +0,0 @@ -# Environment 选项 - -You can customize many aspects about where build scripts, settings, caches, and so on through the options below. Learn more about customizing your[build environment](https://docs.gradle.org/current/userguide/build_environment.html). - -`-b`,`--build-file` - -Specifies the build file. For example:`gradle --build-file=foo.gradle`. The default is`build.gradle`, then`build.gradle.kts`, then`myProjectName.gradle`. - -`-c`,`--settings-file` - -Specifies the settings file. For example:`gradle --settings-file=somewhere/else/settings.gradle` - -`-g`,`--gradle-user-home` - -Specifies the Gradle user home directory. The default is the`.gradle`directory in the user’s home directory. - -`-p`,`--project-dir` - -Specifies the start directory for Gradle. Defaults to current directory. - -`--project-cache-dir` - -Specifies the project-specific cache directory. Default value is`.gradle`in the root project directory. - -`-u`,`--no-search-upward`\(deprecated\) - -Don’t search in parent directories for a`settings.gradle`file. - -`-D`,`--system-prop` - -Sets a system property of the JVM, for example`-Dmyprop=myvalue`. See[the section called “System properties”](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_system_properties). - -`-I`,`--init-script` - -Specifies an initialization script. See[Initialization Scripts](https://docs.gradle.org/current/userguide/init_scripts.html). - -`-P`,`--project-prop` - -Sets a project property of the root project, for example`-Pmyprop=myvalue`. See[the section called “Project properties”](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties). - -`-Dorg.gradle.jvmargs` - -Set JVM arguments. - -`-Dorg.gradle.java.home` - -Set JDK home dir. - From 4f7e5a5bc93c2f7860fbfbee04fa95c57d9c479c Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 10:08:51 +0800 Subject: [PATCH 077/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../project-reporting.md | 133 +++++++++++++++++ .../xiang-mu-bao-gao.md | 139 ------------------ 3 files changed, 134 insertions(+), 140 deletions(-) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md delete mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md diff --git a/SUMMARY.md b/SUMMARY.md index 159facb..7a5a06c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -25,7 +25,7 @@ * [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) - * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md) + * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md) * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md) * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md new file mode 100644 index 0000000..a610ad1 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md @@ -0,0 +1,133 @@ +# 项目报告 + +Gradle 本身含有一些内建任务来显示构建的一些特别的详细信息. 可以帮助用户来更好的理解构建的结构和依赖, 来更好的解决问题. + +你可以直接使用 `gradle help` 来获得相关的帮助信息. + +### 列出所有项目 + +运行 `gradle projects` 来显示所选项目的所有子项目以及它们的层级关系. + +``` +❯ gradle projects +``` + +你也可以通过 build scans 来获得完整的项目报告. 阅读[创建 build scans](https://guides.gradle.org/creating-build-scans/)了解更多. + +### 列出所有任务 + +运行 `gradle tasks` 来显示所选项目的主要任务以及各个任务的描述. + +``` +❯ gradle tasks +``` + +默认的, 这个报告只显示已经被分组的任务. 你可以通过使用 `--all` 选项来获得更多任务信息. + +``` +❯ gradle tasks --all +``` + +### 显示任务的使用详情 + +使用 `gradle help --task someTask` 命令可以显示指定任务的详细信息. + +**Example: 获得任务的详细信息** + +**`gradle -q help --task libs`** 的输出: + +``` +> gradle -q help --task libs +Detailed task information for libs + +Paths + :api:libs + :webapp:libs + +Type + Task (org.gradle.api.Task) + +Description + Builds the JAR + +Group + build + +``` + +通过上面的输出, 你可以看到完整的任务路径, 类型, 可能的命令行选项以及任务的描述和分组. + +### 显示依赖的详情 + +Build scans 可以显示完整的依赖详情, 比如哪些配置有哪些依赖, 依赖的版本等等. + +``` +❯ gradle myTask --scan +``` + +使用这个命令可以生成一个链接, 指向一个网页报告, 你可以发现如下的依赖信息: + +![](https://docs.gradle.org/current/userguide/img/gradle-core-test-build-scan-dependencies.png "Build Scan dependencies report") + +阅读[检查依赖](https://docs.gradle.org/current/userguide/inspecting_dependencies.html)了解更多. + +### 显示项目的所有依赖 + +运行 `gradle dependencies` 命令将列出指定项目的所有依赖, 以每一个配置作为分隔. 对于每一个配置, 它的直接的依赖或者 transitive dependencies 都将以树形结构来显示: + +``` +❯ gradle dependencies +``` + +具体的例子可以阅读[检测依赖](https://docs.gradle.org/current/userguide/inspecting_dependencies.html)了解更多. + +运行 `gradle buildEnvironment` 可以显示所选项目的构建脚本的依赖, 和 `gradle dependencies` 一样, 显示正在构建的软件的依赖. + +``` +❯ gradle buildEnvironment +``` + +运行 `gradle dependencyInsight` 可以了解一个或几个匹配特别输入的特别的依赖. + +``` +❯ gradle dependencyInsight +``` + +有时候, 依赖报告会非常大, 你可以添加 `--configuration` 选项来限制只报告某个特别的配置: + +### 显示项目的所有属性 + +运行 `gradle properties` 显示所选项目的所有属性. + +**Example: 属性的信息** + +**`gradle -q api:properties`**的输出: + +``` +> gradle -q api:properties + +------------------------------------------------------------ +Project :api - The shared API for the application +------------------------------------------------------------ + +allprojects: [project ':api'] +ant: org.gradle.api.internal.project.DefaultAntBuilder@12345 +antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345 +artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345 +asDynamicObject: DynamicObject for project ':api' +baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345 +buildDir: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build +buildFile: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build.gradle + +``` + +### 软件模型的相关报告 + +通过 `model` 任务, 你可以的得到一个[软件模型](https://docs.gradle.org/current/userguide/software_model.html) 项目的各个元素的层级显示: + +``` +❯ gradle model +``` + +阅读[模型报告](https://docs.gradle.org/current/userguide/software_model.html#model-report)了解更多. + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md deleted file mode 100644 index 28755d9..0000000 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/xiang-mu-bao-gao.md +++ /dev/null @@ -1,139 +0,0 @@ -# 项目报告 - -Gradle provides several built-in tasks which show particular details of your build. This can be useful for understanding the structure and dependencies of your build, and for debugging problems. - -You can get basic help about available reporting options using`gradle help`. - -### Listing projects - -Running`gradle projects`gives you a list of the sub-projects of the selected project, displayed in a hierarchy. - -``` -❯ gradle projects -``` - -You also get a project report within build scans. Learn more about[creating build scans](https://guides.gradle.org/creating-build-scans/). - -### Listing tasks - -Running`gradle tasks`gives you a list of the main tasks of the selected project. This report shows the default tasks for the project, if any, and a description for each task. - -``` -❯ gradle tasks -``` - -By default, this report shows only those tasks which have been assigned to a task group. You can obtain more information in the task listing using the`--all`option. - -``` -❯ gradle tasks --all -``` - -### Show task usage details - -Running`gradle help --task someTask`gives you detailed information about a specific task. - - - -**Example: Obtaining detailed help for tasks** - -Output of**`gradle -q help --task libs`** - -``` -> - gradle -q help --task libs -Detailed task information for libs - -Paths - :api:libs - :webapp:libs - -Type - Task (org.gradle.api.Task) - -Description - Builds the JAR - -Group - build - -``` - -This information includes the full task path, the task type, possible command line options and the description of the given task. - -### Reporting dependencies - -Build scans give a full, visual report of what dependencies exist on which configurations, transitive dependencies, and dependency version selection. - -``` -❯ gradle myTask --scan -``` - -This will give you a link to a web-based report, where you can find dependency information like this. - -![](https://docs.gradle.org/current/userguide/img/gradle-core-test-build-scan-dependencies.png "Build Scan dependencies report") - -Learn more in[Inspecting Dependencies](https://docs.gradle.org/current/userguide/inspecting_dependencies.html). - -### Listing project dependencies - -Running`gradle dependencies`gives you a list of the dependencies of the selected project, broken down by configuration. For each configuration, the direct and transitive dependencies of that configuration are shown in a tree. Below is an example of this report: - -``` -❯ gradle dependencies -``` - -Concrete examples of build scripts and output available in the[Inspecting Dependencies](https://docs.gradle.org/current/userguide/inspecting_dependencies.html). - -Running`gradle buildEnvironment`visualises the buildscript dependencies of the selected project, similarly to how`gradle dependencies`visualizes the dependencies of the software being built. - -``` -❯ gradle buildEnvironment -``` - -Running`gradle dependencyInsight`gives you an insight into a particular dependency \(or dependencies\) that match specified input. - -``` -❯ gradle dependencyInsight -``` - -Since a dependency report can get large, it can be useful to restrict the report to a particular configuration. This is achieved with the optional`--configuration`parameter: - -### Listing project properties - -Running`gradle properties`gives you a list of the properties of the selected project. - - - -**Example: Information about properties** - -Output of**`gradle -q api:properties`** - -``` -> - gradle -q api:properties - ------------------------------------------------------------- -Project :api - The shared API for the application ------------------------------------------------------------- - -allprojects: [project ':api'] -ant: org.gradle.api.internal.project.DefaultAntBuilder@12345 -antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345 -artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345 -asDynamicObject: DynamicObject for project ':api' -baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345 -buildDir: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build -buildFile: /home/user/gradle/samples/userguide/tutorial/projectReports/api/build.gradle - -``` - -### Software Model reports - -You can get a hierarchical view of elements for[software model](https://docs.gradle.org/current/userguide/software_model.html)projects using the`model`task: - -``` -❯ gradle model -``` - -Learn more about[the model report](https://docs.gradle.org/current/userguide/software_model.html#model-report)in the software model documentation. - From 05856d1269e5364e53a6cd84291a7de09a631b3e Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 10:18:52 +0800 Subject: [PATCH 078/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=96=B0=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bootstrapping-new-projects.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md index d06f7db..b26ec1b 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md @@ -1,12 +1,14 @@ -### Creating new Gradle builds +# 创建新项目 -Use the built-in`gradle init`task to create a new Gradle builds, with new or existing projects. +### 创建新的 Gradle 构建 + +可以在一个全新的或者已经存在的项目里使用内建的 `gradle init` 任务来创建一个新的 Gradle 构建. ``` ❯ gradle init ``` -Most of the time you’ll want to specify a project type. Available types include`basic`\(default\),`java-library`,`java-application`, and more. See[init plugin documentation](https://docs.gradle.org/4.6/userguide/build_init_plugin.html)for details. +许多时候, 你可能想要指定项目的类型. 一般有`basic`\(默认的\),`java-library`,`java-application` 等等. 阅读[初始化插件](https://docs.gradle.org/4.6/userguide/build_init_plugin.html)了解更多. ``` ❯ gradle init --type java-library @@ -14,11 +16,11 @@ Most of the time you’ll want to specify a project type. Available types includ ### Standardize and provision Gradle -The built-in`gradle wrapper`task generates a script,`gradlew`, that invokes a declared version of Gradle, downloading it beforehand if necessary. +内建的 `gradle wrapper` 任务会生成一个脚本,`gradlew`, 将调用声明的 Gradle 版本, 如果需要的话, 会提前下载 Gradle. ``` ❯ gradle wrapper --gradle-version=4.4 ``` -You can also specify`--distribution-type=(bin|all)`,`--gradle-distribution-url`,`--gradle-distribution-sha256-sum`in addition to`--gradle-version`. Full details on how to use these options are documented in the[Gradle wrapper section](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html). +你可以使用 `--distribution-type=(bin|all)`,`--gradle-distribution-url`,`--gradle-distribution-sha256-sum`包括`--gradle-version` 来进行一些特殊的指定. 具体可以查看[Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html). From fdf6d61c31148459cb4932bbaacd0936a5f34709 Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 10:31:48 +0800 Subject: [PATCH 079/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../execution-options.md | 19 ++++++++++++++++ .../execution-xuan-xiang.md | 22 ------------------- 3 files changed, 20 insertions(+), 23 deletions(-) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md delete mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md diff --git a/SUMMARY.md b/SUMMARY.md index 7a5a06c..27fc045 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -30,7 +30,7 @@ * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md) * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) - * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md) + * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md) * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md) * [Bootstrapping new projects](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md) * [Continuous Build](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md new file mode 100644 index 0000000..f74e895 --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md @@ -0,0 +1,19 @@ +# Execution 选项 + +下列的选项将影响构建的执行, 比如构建什么以及如何处理依赖. + +`--include-build` + +以合成的方式运行一个构建, 指定一个构建脚本. 阅读[合成构建](https://docs.gradle.org/current/userguide/composite_builds.html)了解更多. + +`--offline` + +指定构建是离线模式的, 即不能使用网络上的资源[覆写依赖缓存的选项](https://docs.gradle.org/current/userguide/troubleshooting_dependency_resolution.html#sec:controlling_dependency_caching_command_line)了解更多. + +`--refresh-dependencies` + +刷新依赖的状态. 阅读[依赖管理了解更多](https://docs.gradle.org/current/userguide/troubleshooting_dependency_resolution.html#sec:controlling_dependency_caching_command_line). + +`--dry-run` + +Run Gradle with all task actions disabled. Use this to show which task would have executed. \ No newline at end of file diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md deleted file mode 100644 index bb9926c..0000000 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-xuan-xiang.md +++ /dev/null @@ -1,22 +0,0 @@ -# Execution 选项 - -The following options affect how builds are executed, by changing what is built or how dependencies are resolved. - -`--include-build` - -Run the build as a composite, including the specified build. See[Composite Builds](https://docs.gradle.org/current/userguide/composite_builds.html). - -`--offline` - -Specifies that the build should operate without accessing network resources. Learn more about[options to override dependency caching](https://docs.gradle.org/current/userguide/troubleshooting_dependency_resolution.html#sec:controlling_dependency_caching_command_line). - -`--refresh-dependencies` - -Refresh the state of dependencies. Learn more about how to use this in the[dependency management docs](https://docs.gradle.org/current/userguide/troubleshooting_dependency_resolution.html#sec:controlling_dependency_caching_command_line). - -`--dry-run` - -Run Gradle with all task actions disabled. Use this to show which task would have executed. - - - From 99de751dc61942381576613a07f9f1509ec448b3 Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 10:46:46 +0800 Subject: [PATCH 080/102] =?UTF-8?q?=E8=A1=A5=E5=85=A8=E9=83=A8=E5=88=86?= =?UTF-8?q?=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../execution-options.md | 2 +- .../logging-xuan-xiang.md | 32 +++++-------------- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md index f74e895..6e9717b 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md @@ -16,4 +16,4 @@ `--dry-run` -Run Gradle with all task actions disabled. Use this to show which task would have executed. \ No newline at end of file +运行 Gradle 的时候禁用所有任务的动作. 我们可以使用这个选项来查看我们定义的依赖或者插件里的依赖是否都正确定义了. 我们可以在输出中查看都有哪些依赖被执行了. \ No newline at end of file diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md index 20cf4fa..6b369bc 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md @@ -1,48 +1,32 @@ # Logging 选项 -### Setting log level +### 设置 log level -You can customize the verbosity of Gradle logging with the following options, ordered from least verbose to most verbose. Learn more in the[logging documentation](https://docs.gradle.org/current/userguide/logging.html). +以下为自定义 Gradle logging 相关的选项, 从显示最少的信息到最多的信息. 阅读[logging documentation](https://docs.gradle.org/current/userguide/logging.html)了解更多. `-Dorg.gradle.logging.level=(quiet,warn,lifecycle,info,debug)` Set logging level via Gradle properties. -`-q` +`-q`,`--quiet` -, +安静模式, 只显示 erros. 其余一概不显示. -`--quiet` - -Log errors only. - -`-w` - -, - -`--warn` +`-w`,`--warn` Set log level to warn. -`-i` - -, - -`--info` +`-i`,`--info` Set log level to info. -`-d` - -, - -`--debug` +`-d`,`--debug` Log in debug mode \(includes normal stacktrace\). Lifecycle is the default log level. -### Customizing log format +### 自定义 log 样式 You can control the use of rich output \(colors and font variants\) by specifying the "console" mode in the following ways: From 52066df943db7f26d63115dec9f2730b3f8fd0e1 Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 13:51:49 +0800 Subject: [PATCH 081/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=A1=8C=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md index 7c18b96..355e7bd 100644 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md @@ -1,7 +1,6 @@ # 命令行补全 -Gradle provides bash and zsh tab completion support for tasks, options, and Gradle properties through[gradle-completion](https://github.com/gradle/gradle-completion), installed separately. - +Gradle 提供 bash 和 zsh tab 键的补全功能. 可以补全任务名, 选项, Gradle 属性. 需要单独安装[gradle-completion](https://github.com/gradle/gradle-completion). **Figure: Gradle Completion** From 86004b0a5c3fe80b67d9e45024bc3a54fab8e77e Mon Sep 17 00:00:00 2001 From: Chuan DONG Date: Thu, 5 Apr 2018 14:21:13 +0800 Subject: [PATCH 082/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 +- .../performance-options.md | 60 +++++++++++++++ .../performance-xuan-xiang.md | 76 ------------------- 3 files changed, 61 insertions(+), 77 deletions(-) create mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md delete mode 100644 shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md diff --git a/SUMMARY.md b/SUMMARY.md index 27fc045..de9ba37 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -28,7 +28,7 @@ * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md) * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md) - * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md) + * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md) * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md) * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md) diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md new file mode 100644 index 0000000..1e6e8ee --- /dev/null +++ b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md @@ -0,0 +1,60 @@ +# Performance 选项 + +在你想优化构建性能的时候可以尝试以下选项. 可以阅读[提升 Gradle 构建性能](https://guides.gradle.org/performance/)了解更多. + +大部分选项都可以直接在 `gradle.properties` 文件中直接指定, 并不需要在命令行中添加选项. 阅读[配置构建环境指南](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties)了解更多. + +`--build-cache`,`--no-build-cache` + +这两个选项使用来切换[Gradle 构建缓存](https://docs.gradle.org/current/userguide/build_cache.html). Gradle 将会尝试再使用之前构建的输出._默认是关的_. + +`--configure-on-demand`,`--no-configure-on-demand` + +切换[Configure-on-demand](https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:configuration_on_demand)(部分文章称之为孵化模式). 只有相关的项目才会在这个构建运行中被配置._默认是关的_. + +`--max-workers` + +设置 Gradle 可以使用的工作线程的最大数量._默认是处理器的数量_. + +`--parallel`,`--no-parallel` + +通过构建项目. 可以阅读[同步项目执行](https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:parallel_execution)了解这个选项的局限线._默认是关的_. + +`--profile` + +在 `$buildDir/reports/profile` 文件夹生成一个高级别的性能报告. 但更推荐使用 `--scan`. + +`--scan` + +生成一个包含具体性能诊断的 build scan. + +![](https://docs.gradle.org/current/userguide/img/gradle-core-test-build-scan-performance.png "Build Scan performance report") + +### Gradle 守护进程选项 + +你可以通过下面的选项来管理[Gradle 守护进程](https://docs.gradle.org/current/userguide/gradle_daemon.html). + +`--daemon`,`--no-daemon` + +使用[Gradle 守护进程](https://docs.gradle.org/current/userguide/gradle_daemon.html)来构建项目. 开始守护进程如果没有运行或者正在运行的守护进程正忙._默认是开的_. + +`--foreground` + +在前台进程开始 Gradle 守护进程. + +`--status` + +\(Standalone command\) + +运行 `gradle --status` 将会列出正在运行以及最近刚停止的 Gradle 守护进程. 只显示同一个 Gradle 版本的守护进程. + +`--stop` + +\(Standalone command\) + +运行 `gradle --stop` 来停止同一个版本的所有的 Gradle 守护进程. + +`-Dorg.gradle.daemon.idletimeout=(number of milliseconds)` + +Gradle 守护进程空闲后, 将会在指定的毫秒数之后自己停止._默认是 10800000_\(3 个小时\). + diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md b/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md deleted file mode 100644 index a395ccb..0000000 --- a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-xuan-xiang.md +++ /dev/null @@ -1,76 +0,0 @@ -# Performance 选项 - -Try these options when optimizing build performance. Learn more about[improving performance of Gradle builds here](https://guides.gradle.org/performance/). - -Many of these options can be specified in`gradle.properties`so command-line flags are not necessary. See the[configuring build environment guide](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties). - -`--build-cache` - -, - -`--no-build-cache` - -Toggles the[Gradle build cache](https://docs.gradle.org/current/userguide/build_cache.html). Gradle will try to reuse outputs from previous builds._Default is off_. - -`--configure-on-demand` - -, - -`--no-configure-on-demand` - -Toggles[Configure-on-demand](https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:configuration_on_demand). Only relevant projects are configured in this build run._Default is off_. - -`--max-workers` - -Sets maximum number of workers that Gradle may use._Default is number of processors_. - -`--parallel` - -, - -`--no-parallel` - -Build projects in parallel. For limitations of this option please see[the section called “Parallel project execution”](https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:parallel_execution)._Default is off_. - -`--profile` - -Generates a high-level performance report in the`$buildDir/reports/profile`directory.`--scan`is preferred. - -`--scan` - -Generate a build scan with detailed performance diagnostics. - -![](https://docs.gradle.org/current/userguide/img/gradle-core-test-build-scan-performance.png "Build Scan performance report") - -### Gradle daemon options - -You can manage the[Gradle Daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html)through the following command line options. - -`--daemon` - -, - -`--no-daemon` - -Use the[Gradle Daemon](https://docs.gradle.org/current/userguide/gradle_daemon.html)to run the build. Starts the daemon if not running or existing daemon busy._Default is on_. - -`--foreground` - -Starts the Gradle Daemon in a foreground process. - -`--status` - -\(Standalone command\) - -Run`gradle --status`to list running and recently stopped Gradle daemons. Only displays daemons of the same Gradle version. - -`--stop` - -\(Standalone command\) - -Run`gradle --stop`to stop all Gradle Daemons of the same version. - -`-Dorg.gradle.daemon.idletimeout=(number of milliseconds)` - -Gradle Daemon will stop itself after this number of milliseconds of idle time._Default is 10800000_\(3 hours\). - From 14d6177609582fde0d7e6a7fd646502d5b0b5c6a Mon Sep 17 00:00:00 2001 From: BurjalHou Date: Mon, 9 Apr 2018 09:18:18 +0000 Subject: [PATCH 083/102] Updates xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md Auto commit by GitBook Editor --- SUMMARY.md | 5 + project-tutorials.md | 0 xiang-mu-shi-yong-jiao-cheng/android.md | 0 .../android/gou-jian-android-ying-yong.md | 497 ++++++++++++++++++ 4 files changed, 502 insertions(+) create mode 100644 project-tutorials.md create mode 100644 xiang-mu-shi-yong-jiao-cheng/android.md create mode 100644 xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md diff --git a/SUMMARY.md b/SUMMARY.md index de9ba37..1e019ff 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -40,3 +40,8 @@ * [Initialization Scripts](shi-yong-gradle-gou-jian/customizing-execution/initialization-scripts.md) * [Executing Multi-Project Builds](executing-multi-project-builds.md) +## 项目使用教程 + +* [Android](xiang-mu-shi-yong-jiao-cheng/android.md) + * [构建Android应用](xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md) + diff --git a/project-tutorials.md b/project-tutorials.md new file mode 100644 index 0000000..e69de29 diff --git a/xiang-mu-shi-yong-jiao-cheng/android.md b/xiang-mu-shi-yong-jiao-cheng/android.md new file mode 100644 index 0000000..e69de29 diff --git a/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md b/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md new file mode 100644 index 0000000..75d7319 --- /dev/null +++ b/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md @@ -0,0 +1,497 @@ +# Building Android Apps + +Android applications \(known colloquially as_apps_\) use Gradle as their build tool, normally through the only supported IDE, Android Studio. Many resources are available for learning how to build Android applications. This guide, however, focuses on the details of the Gradle build files generated when creating a new Android application, and how to use Gradle to invoke relevant build tasks for them. + +Contents + +* [What you’ll build](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_build) +* [What you’ll need](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_need) +* [Create a new Android Studio project](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#create_a_new_android_studio_project) +* [Review the list of generated Gradle files](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_list_of_generated_gradle_files) +* [Review the top-level Gradle build file](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_top_level_gradle_build_file) +* [Review the build file in the app module](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_build_file_in_the_app_module) +* [Run standard Gradle tasks](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#run_standard_gradle_tasks) +* [Use the Gradle window](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#use_the_gradle_window) +* [Publish a build scan](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#publish_a_build_scan) +* [Summary](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#summary) +* [Next Steps](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#next_steps) +* [Help improve this guide](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#help_improve_this_guide) + +## [What you’ll build](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_build) {#what_you_ll_build} + +You’ll create a "Hello, World!" type of Android application, explore its generated Gradle build files, and execute common tasks using them. + +## [What you’ll need](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_need) {#what_you_ll_need} + +* About26 minutes + +* Android Studio, version 2.4 or higher. You can download Android Studio, along with the latest Android SDK, from[https://developer.android.com/studio/index.html](https://developer.android.com/studio/index.html). The system requirements for the IDE are also found at that link. + +* The Java Development Kit \(JDK\), version 1.7 or higher + +## [Create a new Android Studio project](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#create_a_new_android_studio_project) {#create_a_new_android_studio_project} + +After downloading and installing Android Studio, start the application. On the welcome screen, click the link entitled, "Start a new Android Studio project", as shown in the figure. When ready, click_Next_. + +![](https://guides.gradle.org/building-android-apps/images/Welcome-to-Android-Studio.png "Welcome to Android Studio") + +On the "Create Android Project" screen, set the application name to "HelloWorldGradle", the company domain to your own \(the domain_gradle.org_is used in the accompanying figure\), and select any convenient directory for the project location. Then click_Next_. + +![](https://guides.gradle.org/building-android-apps/images/Create-New-Project.png "Create New Project") + +On the "Target Android Devices" screen, select_Phone and Tablet_and choose any recent API level from the_Minimum SDK_drop-down list. The figure shows API 19, which is common, but the value chose will not affect the rest of this guide. + +![](https://guides.gradle.org/building-android-apps/images/Target-Android-Devices.png "Target Android Devices") + +On the "Add an Activity" screen, select_Empty Activity_and click_Next_. + +Accept all the defaults on the "Configure Activity" screen and click_Finish_. + +![](https://guides.gradle.org/building-android-apps/images/Configure-Activity.png "Configure Activity") + +## [Review the list of generated Gradle files](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_list_of_generated_gradle_files) {#review_the_list_of_generated_gradle_files} + +By default, Android Studio will start with a "Project View" in "Android" mode, as shown in the figure: + +![](https://guides.gradle.org/building-android-apps/images/Project-View-Android.png "Project View Android") + +Android projects are Gradle multi-project builds, with a top-level`build.gradle`file and a subdirectory called`app`, with its own`build.gradle`file. The top-level build file is noted as`(Project: HelloWorldGradle)`in the figure, and the`app`build file has`(Module: app)`appended to it. + +There may be two files called`gradle.properties`. One is local to the project. The other, optional file of the same name exists only if you have a global`gradle.properties`file in the`.gradle`sub-directory of your home directory. + +The file`settings.gradle`is used by Gradle to configure the multi-project build. It should consist of a single line: + +``` +include +' +:app +' +``` + +This tells Gradle that the`app`sub-directory is also a Gradle project. If, at some later time, you were to add an Android Library to this project through the available wizard, another project sub-directory would be created and added to this file. + +The last file is called`gradle-wrapper.properties`, which configures the so-called Gradle Wrapper. This allows you to build Android projects without having to install Gradle first. The contents of the file should be similar to: + +``` +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https +\ +: +//services.gradle.org/distributions/gradle-4.1-all.zip +``` + +The first four lines indicate that when the wrapper runs the first time, it will download a Gradle distribution and store it in the directory`.gradle/wrapper/dists`in your home directory. + +The last line shows the value of the`distributionUrl`, which is the location where Gradle will download the distribution specified. + +| | The specific version number might differ from that shown here \(4.1\), and the URL might refer to a binary version \(`-bin`\) instead of the complete \(`-all`\) version shown in this example. | +| :--- | :--- | + + +## [Review the top-level Gradle build file](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_top_level_gradle_build_file) {#review_the_top_level_gradle_build_file} + +The project`build.gradle`file should have contents similar to: + +``` +// Top-level build file where you can add configuration options common to all sub-projects/modules. + + +buildscript { + + repositories { + google() + jcenter() + } + dependencies { + + classpath +' +com.android.tools.build:gradle:3.0.1 +' +// NOTE: Do not place your application dependencies here; they belong +// in the individual module build.gradle files + + } +} + +allprojects { + + repositories { + google() + jcenter() + } +} + +task clean( +type +: Delete) { + + delete rootProject.buildDir +} +``` + +| | Download plugins block | +| :--- | :--- | +| | Identifies the Android plugin | +| | Configuration for top-level and module projects | +| | Ad hoc task | + +Gradle defines a domain-specific language \(DSL\) for builds, used inside the build files. The`buildscript`tag is part of that DSL. It tells Gradle that the build requires a plugin that may not be part of the baseline Gradle distribution, and tells Gradle where to find it. In this case, the required plugin is specified using coordinate syntax "group:name:version", where the group is`com.android.tools.build`, the name is`gradle`, and the version is`3.0.1`. + +| | The version number of the Gradle plugin is updated frequently. Please use the latest plugin, as it will contain all the available bug fixes and performance improvements. | +| :--- | :--- | + + +When Gradle builds this project the first time, the plugin will be downloaded and cached, so this task is only performed once. + +The`allprojects`tag holds configuration details that apply to both the top-level project and any sub-projects it contains. In this case, the block specifies that any required dependencies should be downloaded from`google`, or`jcenter`, the public Bintray Artifactory repository at[https://jcenter.bintray.com](https://jcenter.bintray.com/). + +Finally, the build file contains a custom \(or_ad hoc_\) task, called`clean`. It uses the built-in task type`Delete`and configures it so that the`clean`task will delete the`buildDir`in the`rootProject`. Both are project properties, whose values default to the`build`directory in the project where this app resides. + +## [Review the build file in the app module](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_build_file_in_the_app_module) {#review_the_build_file_in_the_app_module} + +Open the`build.gradle`file in the`app`module. The first line is: + +``` +apply +plugin +: +' +com.android.application +' +``` + +This "applies" the Android plugin \(referred to in the`buildscript`section of the top-level build file\) to the current project. Plugins in Gradle can add custom tasks, new configurations, dependencies, and other capabilities to Gradle projects. In this case, applying the Android plugin adds a wide variety of tasks, which are configured by the`android`block shown next. + +``` +android { + compileSdkVersion +26 + + defaultConfig { + applicationId +" +org.gradle.helloworldgradle +" + + minSdkVersion +19 + + targetSdkVersion +26 + + versionCode +1 + + versionName +" +1.0 +" + + testInstrumentationRunner +" +android.support.test.runner.AndroidJUnitRunner +" + + } + buildTypes { + release { + minifyEnabled +false + + proguardFiles getDefaultProguardFile( +' +proguard-android.txt +' +), +' +proguard-rules.pro +' + + } + } +} +``` + +These properties are more relevant to Android than the Gradle build system, to they will only be lightly reviewed here. In short: + +* The`compileSdkVersion`is associated with the Android SDK and should always be the latest available version. + +* The`defaultConfig`section hold properties that are shared by all variants \(combinations of build types and product flavors\) of the app. + +* The`applicationId`is based on the domain name and project name specified when creating the app, and must be unique in the Google Play store. + +* The value of`minSdkVersion`is the minimum Android API you are willing to support with this app, and the`targetSdkVersion`should be the latest Android version available. + +* The value of`versionCode`should be an integer that is incremented before uploading a new version of the app into the Google Play store. This value, along with the`applicationId`, tell Google that this is a new version of an existing app, as opposed to a new app. + +* The`versionName`value is used for your own internal version tracking. + +* The`testInstrumentationRunner`property is configured to use the JUnit 4 test runner configured for Android apps. + +Below this section is a block called`buildTypes`. By default, Android apps support two build types,`debug`and`release`. This section allows you to configure each however you like. The`debug`section is not shown here, implying that all the default settings for`debug`are being used. + +After the`android`block, there is a block that shows the libraries used for this app. + +``` +dependencies { + implementation fileTree( +dir +: +' +libs +' +, +include +: [ +' +*.jar +' +]) + implementation +' +com.android.support:appcompat-v7:26.1.0 +' + + implementation +' +com.android.support.constraint:constraint-layout:1.0.2 +' + + testImplementation +' +junit:junit:4.12 +' + + androidTestImplementation +' +com.android.support.test:runner:1.0.1 +' + + androidTestImplementation +' +com.android.support.test.espresso:espresso-core:3.0.1 +' + +} +``` + +Configuring dependencies is a fundamental part of building Gradle applications. In this case, the`dependencies`section shows values for the`implementation`,`testImplementation`, and`androidTestImplementation`configurations. + +Taking the simplest one first, the`testImplementation`dependency consists only of the latest stable JUnit 4 distribution. The JUnit classes and test annotations will then be available at compile time in the`src/test/java`hierarchy. + +The`androidTestImplementation`dependency refers to the Espresso testing library, which is used for integration testing of Android apps. In this case, Espresso is requested without the`support-annotations`library that it would normally include, because a different version is already included through other dependencies. In a later step, you’ll see how to find out what version of this library was included and why. + +Finally, there are three lines that add dependencies to the`implementation`configuration: + +* The first,`fileTree(dir: 'libs', include: ['*.jar'])`, is a`fileTree`dependency that adds any jar files in the`libs`folder to the compile classpath + +* The second,`com.android.support:appcompat-v7:26.1.0`adds the Android Compatibility library to the project. This allows you to use the Material design theme and other capabilities in any Android app as old as SDK version 7. + +* The third,`com.android.support.constraint:constraint-layout:1.0.2`adds the Android Constraint Layout to the project. This allows you to use the ConstraintLayout layout class in any Android app as old as SDK version 9. + +## [Run standard Gradle tasks](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#run_standard_gradle_tasks) {#run_standard_gradle_tasks} + +Android Studio makes it easy to build and deploy a debug version of an app through the IDE, but ultimately Gradle is still involved. To see this, open the Terminal window in Android Studio \(or open an external command prompt and navigate to the root directory of your app\). From there you can run the`build`task. + +``` +$ ./gradlew build +``` + +This will run many tasks and eventually return "Build Successful". To see the resulting APK \(Android package, the deployable version of an Android app\), look in the directory`app/build/outputs/apk`. There you will find a`debug`and a`release`directories. The`debug`directory contains`app-debug.apk`, which is the APK version that will be deployed to an emulator or connected device. If you want to deploy a release APK, you need to create a signing configuration first, which is beyond the scope of this guide, but is a straightforward process described in the resources. + +From the terminal, you can also find out the version of the`support-annotations`module being used in the project. To do so, first run the`dependencies`task in the`app`project, asking for the details of the`releaseCompileClasspath`configuration only. + +``` +$ ./gradlew :app:dependencies --configuration releaseCompileClasspath +:app:dependencies + +------------------------------------------------------------ +Project :app +------------------------------------------------------------ + +releaseCompileClasspath - Resolved configuration for compilation for variant: release ++--- com.android.support:appcompat-v7:26.1.0 +| +--- com.android.support:support-annotations:26.1.0 +| +--- com.android.support:support-v4:26.1.0 +| | +--- com.android.support:support-compat:26.1.0 +| | | +--- com.android.support:support-annotations:26.1.0 +| | | \--- android.arch.lifecycle:runtime:1.0.0 +| | | +--- android.arch.lifecycle:common:1.0.0 +| | | \--- android.arch.core:common:1.0.0 +| | +--- com.android.support:support-media-compat:26.1.0 +| | | +--- com.android.support:support-annotations:26.1.0 +| | | \--- com.android.support:support-compat:26.1.0 (*) +| | +--- com.android.support:support-core-utils:26.1.0 +| | | +--- com.android.support:support-annotations:26.1.0 +| | | \--- com.android.support:support-compat:26.1.0 (*) +| | +--- com.android.support:support-core-ui:26.1.0 +| | | +--- com.android.support:support-annotations:26.1.0 +| | | \--- com.android.support:support-compat:26.1.0 (*) +| | \--- com.android.support:support-fragment:26.1.0 +| | +--- com.android.support:support-compat:26.1.0 (*) +| | +--- com.android.support:support-core-ui:26.1.0 (*) +| | \--- com.android.support:support-core-utils:26.1.0 (*) +| +--- com.android.support:support-vector-drawable:26.1.0 +| | +--- com.android.support:support-annotations:26.1.0 +| | \--- com.android.support:support-compat:26.1.0 (*) +| \--- com.android.support:animated-vector-drawable:26.1.0 +| +--- com.android.support:support-vector-drawable:26.1.0 (*) +| \--- com.android.support:support-core-ui:26.1.0 (*) +\--- com.android.support.constraint:constraint-layout:1.0.2 + \--- com.android.support.constraint:constraint-layout-solver:1.0.2 + +(*) - dependencies omitted (listed previously) + + +BUILD SUCCESSFUL +``` + +From the output, you can see that the`support-annotations`module, version 26.1.0, is a dependency of the`appcompat-v7`library. + +Another way to see the version required is to use the`dependencyInsight`task. Run the following command \(all on one line\). + +``` +$ ./gradlew :app:dependencyInsight --dependency support-annotations --configuration releaseCompileClasspath +:app:dependencyInsight +com.android.support:support-annotations:26.1.0 ++--- com.android.support:appcompat-v7:26.1.0 +| \--- releaseCompileClasspath ++--- com.android.support:support-compat:26.1.0 +| +--- com.android.support:support-vector-drawable:26.1.0 +| | +--- com.android.support:appcompat-v7:26.1.0 (*) +| | \--- com.android.support:animated-vector-drawable:26.1.0 +| | \--- com.android.support:appcompat-v7:26.1.0 (*) +| +--- com.android.support:support-v4:26.1.0 +| | \--- com.android.support:appcompat-v7:26.1.0 (*) +| +--- com.android.support:support-media-compat:26.1.0 +| | \--- com.android.support:support-v4:26.1.0 (*) +| +--- com.android.support:support-fragment:26.1.0 +| | \--- com.android.support:support-v4:26.1.0 (*) +| +--- com.android.support:support-core-utils:26.1.0 +| | +--- com.android.support:support-v4:26.1.0 (*) +| | \--- com.android.support:support-fragment:26.1.0 (*) +| \--- com.android.support:support-core-ui:26.1.0 +| +--- com.android.support:animated-vector-drawable:26.1.0 (*) +| +--- com.android.support:support-v4:26.1.0 (*) +| \--- com.android.support:support-fragment:26.1.0 (*) ++--- com.android.support:support-core-ui:26.1.0 (*) ++--- com.android.support:support-core-utils:26.1.0 (*) ++--- com.android.support:support-media-compat:26.1.0 (*) +\--- com.android.support:support-vector-drawable:26.1.0 (*) + +(*) - dependencies omitted (listed previously) + + +BUILD SUCCESSFUL +``` + +Both the`dependency`and`dependencyInsight`tasks are available in any Gradle project. They can help you track down and resolve any issues with library version conflicts. + +## [Use the Gradle window](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#use_the_gradle_window) {#use_the_gradle_window} + +Android Studio includes a special window for executing Gradle tasks. Android projects provide over 80 different tasks, and this window tries to organize them into categories. + +Open the Tasks folder under`:app`, and look inside the`android`category. The following figure shows an example. + +![](https://guides.gradle.org/building-android-apps/images/Gradle-window-signingReport.png "Gradle window signingReport") + +Since the`signingReport`task does not require any arguments, you can simply double-click on it to execute it. The results are shown in the next figure. + +![](https://guides.gradle.org/building-android-apps/images/Run-and-Gradle-Console.png "Run and Gradle Console") + +The`signingReport`task tells you where the public key is stored \(here the`debug.keystore`file in the user’s root directory\), its alias, and its MD5 and SHA1 hashes. + +Note that there is no release key at the moment. Look at the tasks listed in the Gradle window in the`install`category, as shown the next figure. + +![](https://guides.gradle.org/building-android-apps/images/Gradle-window-install.png "Gradle window install") + +You’ll see that there is an`installDebug`task and an`uninstallDebug`task, an`uninstallRelease`task, and even an`uninstallAllTask`. Conspicuous by its absence, however, is an`installRelease`task. That task is only available if you create a signing configuration for a release key, which Gradle can use to create a signed release APK. + +If you were now to start up multiple emulators or attach multiple devices, you could deploy the app into all of them by executing the`installDebug`task. + +``` +$ ./gradlew installDebug +``` + +This is different from running the app through the IDE. In that case, you would select a single connected device or emulator, and would both install the app and start it up. The`installDebug`task from Gradle will deploy the app in all connected devices in one step, though it will not start the app in any of them. The result will be similar to the next figure. + +![](https://guides.gradle.org/building-android-apps/images/Android-Emulator-Pixel_API_25.png "Android Emulator Pixel API 25") + +![](https://guides.gradle.org/building-android-apps/images/Android-Emulator-Nexus_9_API_23.png "Android Emulator Nexus 9 API 23") + +You can launch the app by double-clicking on the icon, as usual. You can also remove the app by using the`uninstallAll`task. + +``` +$ ./gradlew uninstallAll +``` + +This will remove the app from all connected devices. + +## [Publish a build scan](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#publish_a_build_scan) {#publish_a_build_scan} + +[Build scans](https://gradle.com/build-scans)are a persistent, shareable record of what happened when running a build. With build scans, you gain deep insights about your build. + +If you are using Gradle 4.3+, you can easily create a build scan by using the`--scan`command line option, e.g.`gradle build --scan`. For older Gradle versions, see the[Build Scan Plugin User Manual](https://docs.gradle.com/build-scan-plugin/#getting_set_up)on how to enable build scans. + +``` +./gradlew build --scan + +BUILD SUCCESSFUL in 1s +4 actionable tasks: 4 executed + +Do you accept the Gradle Cloud Services license agreement (https://gradle.com/terms-of-service)? [yes, no] +yes +Gradle Cloud Services license agreement accepted. + +Publishing build scan... +https://gradle.com/s/carzirlfjwjlo +``` + +The resulting page will resemble: + +![](https://guides.gradle.org/building-android-apps/images/Build-scan-for-HelloWorldGradle.png "Build scan for HelloWorldGradle") + +Feel free to explore all the details. The report contains information on many features, including dependencies. If you dig into the dependencies section and open the`releaseCompileClasspath`configuration of the`:app`subproject, inside the`appcompat-v7`library is the`support-annotations`library described earlier. + +![](https://guides.gradle.org/building-android-apps/images/Build-scan-dep-support-annotations.png "Build scan dep support annotations") + +Build scans are a powerful way to analyze your build. For more details, see the[Getting Started guide for Creating Build Scans](https://guides.gradle.org/creating-build-scans/)and the[Build Scan Plugin User Manual](https://docs.gradle.com/build-scan-plugin/). + +## [Summary](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#summary) {#summary} + +In this guide, you created an Android app and examined many of the Gradle capabilities that came with it. Specifically, you learned how to: + +* Create an Android app using Android Studio + +* View the generated project as a Gradle multi-project build + +* Add the Android plugin to the top-level Gradle build file + +* See which version of Gradle is used in the generated wrapper + +* Interpret the settings added in the`android`section of the app + +* Work with the default dependencies added to the app + +* Build the app and see the output APK + +* Determine which version of a dependency is being used + +* Use the Gradle window to execute tasks + +* Deploy and uninstall the app on multiple devices + +* Run a build scan on an Android project + +## [Next Steps](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#next_steps) {#next_steps} + +The book_Gradle Recipes for Android_, by Ken Kousen and published by O’Reilly Media, Inc, is available for purchase at[http://shop.oreilly.com/product/0636920032656.do](http://shop.oreilly.com/product/0636920032656.do), but an electronic version can also be downloaded for free at[https://gradle.org/books/](https://gradle.org/books/). + +## [Help improve this guide](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#help_improve_this_guide) {#help_improve_this_guide} + +Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/building-android-apps](https://github.com/gradle-guides/building-android-apps/)and we’ll get back to you. + From de80b4cbc238898ab5f82fab503f4e34c5a3b49c Mon Sep 17 00:00:00 2001 From: BurjalHou Date: Mon, 9 Apr 2018 10:56:20 +0000 Subject: [PATCH 084/102] Updates xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md Auto commit by GitBook Editor --- .../android/gou-jian-android-ying-yong.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md b/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md index 75d7319..7a3163c 100644 --- a/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md +++ b/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md @@ -1,4 +1,4 @@ -# Building Android Apps +# 构建Android应用 Android applications \(known colloquially as_apps_\) use Gradle as their build tool, normally through the only supported IDE, Android Studio. Many resources are available for learning how to build Android applications. This guide, however, focuses on the details of the Gradle build files generated when creating a new Android application, and how to use Gradle to invoke relevant build tasks for them. @@ -35,15 +35,15 @@ After downloading and installing Android Studio, start the application. On the w ![](https://guides.gradle.org/building-android-apps/images/Welcome-to-Android-Studio.png "Welcome to Android Studio") -On the "Create Android Project" screen, set the application name to "HelloWorldGradle", the company domain to your own \(the domain_gradle.org_is used in the accompanying figure\), and select any convenient directory for the project location. Then click_Next_. +On the "Create Android Project" screen, set the application name to "HelloWorldGradle", the company domain to your own \(the domain_gradle.org\_is used in the accompanying figure\), and select any convenient directory for the project location. Then click\_Next_. ![](https://guides.gradle.org/building-android-apps/images/Create-New-Project.png "Create New Project") -On the "Target Android Devices" screen, select_Phone and Tablet_and choose any recent API level from the_Minimum SDK_drop-down list. The figure shows API 19, which is common, but the value chose will not affect the rest of this guide. +On the "Target Android Devices" screen, select\_Phone and Tablet\_and choose any recent API level from the\_Minimum SDK\_drop-down list. The figure shows API 19, which is common, but the value chose will not affect the rest of this guide. ![](https://guides.gradle.org/building-android-apps/images/Target-Android-Devices.png "Target Android Devices") -On the "Add an Activity" screen, select_Empty Activity_and click_Next_. +On the "Add an Activity" screen, select_Empty Activity\_and click\_Next_. Accept all the defaults on the "Configure Activity" screen and click_Finish_. From 0d271c801d8cab868f727930c2beec86f321057f Mon Sep 17 00:00:00 2001 From: Burjal Date: Mon, 9 Apr 2018 18:58:05 +0800 Subject: [PATCH 085/102] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48f0073..6bebaa1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ##### 项目教程 -* [ ] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) +* [x] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) * [ ] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) * [ ] [Groovy](https://docs.gradle.org/current/userguide/userguide.html#building-groovy-projects) * [ ] [Java](https://docs.gradle.org/current/userguide/userguide.html#building-java-projects) From 26f3faa5a8476f9eaf3978162c19c99d73014ef8 Mon Sep 17 00:00:00 2001 From: DONG Date: Mon, 9 Apr 2018 22:31:26 +0800 Subject: [PATCH 086/102] =?UTF-8?q?=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加章节负责人 --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6bebaa1..658ce37 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,14 @@ ##### 开始 -* [x] [Installing Gradle](https://docs.gradle.org/current/userguide/installation.html) -* [x] [Creating New Gradle Builds](https://guides.gradle.org/creating-new-gradle-builds/) -* [x] [Creating Build Scans](https://guides.gradle.org/creating-build-scans/) +* [x] [Installing Gradle](https://docs.gradle.org/current/userguide/installation.html) ([@DONGChuan](https://github.com/DONGChuan)) +* [x] [Creating New Gradle Builds](https://guides.gradle.org/creating-new-gradle-builds/) ([@DONGChuan](https://github.com/DONGChuan)) +* [x] [Creating Build Scans](https://guides.gradle.org/creating-build-scans/) ([@DONGChuan](https://github.com/DONGChuan)) * [ ] [Migrating From Maven](https://guides.gradle.org/migrating-from-maven/) ##### 使用 Gradle 构建 -* [ ] [Command-Line Interface](https://docs.gradle.org/current/userguide/command_line_interface.html) +* [ ] [Command-Line Interface](https://docs.gradle.org/current/userguide/command_line_interface.html) ([@DONGChuan](https://github.com/DONGChuan)) * [ ] [Customizing Execution](https://docs.gradle.org/current/userguide/userguide.html#customizing-execution) * [ ] [Executing Multi-Project Builds](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html) * [ ] [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) @@ -26,7 +26,7 @@ ##### 项目教程 -* [x] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) +* [ ] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) ([@BurjalHou](https://github.com/BurjalHou)) * [ ] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) * [ ] [Groovy](https://docs.gradle.org/current/userguide/userguide.html#building-groovy-projects) * [ ] [Java](https://docs.gradle.org/current/userguide/userguide.html#building-java-projects) @@ -90,6 +90,7 @@ Gitbook 提供了非常棒的在线编辑功能, 所以想贡献的同学可以 | UFreedom | sunfreedom@sina.cn | [Github](https://github.com/UFreedom) | | 张扬 | zhangyang911120@gmail.com | [Github](https://github.com/dreamkidd) | | d0048 | d0048@foxmail.com | [Github](https://github.com/D0048) | +| BurjalHou | burjalhou@gmail.com | [Github](https://github.com/BurjalHou) | From fafced67fd5768f4173875fe914cb3c91054adeb Mon Sep 17 00:00:00 2001 From: DONG Date: Mon, 9 Apr 2018 22:40:23 +0800 Subject: [PATCH 087/102] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=92=8C=E6=96=87=E4=BB=B6=E5=A4=B9=E5=90=8D?= =?UTF-8?q?=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 24 +++++++++---------- installing_gradle/prerequisites.md | 17 +++++++++---- installing_gradle/yu-bei-zhi-shi.md | 15 ------------ ...-jie-mian.md => command-line-interface.md} | 0 .../bootstrapping-new-projects.md | 0 .../command-line-completion.md} | 0 .../common-tasks.md | 0 .../continuous-build.md | 0 .../debugging-options.md | 0 .../environment-options.md | 0 .../executing-tasks.md | 0 .../execution-options.md | 0 .../logging-xuan-xiang.md | 0 .../performance-options.md | 0 .../project-reporting.md | 0 15 files changed, 24 insertions(+), 32 deletions(-) delete mode 100644 installing_gradle/yu-bei-zhi-shi.md rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian.md => command-line-interface.md} (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/bootstrapping-new-projects.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md => command-line-interface/command-line-completion.md} (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/common-tasks.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/continuous-build.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/debugging-options.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/environment-options.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/executing-tasks.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/execution-options.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/logging-xuan-xiang.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/performance-options.md (100%) rename shi-yong-gradle-gou-jian/{ming-ling-xing-jie-mian => command-line-interface}/project-reporting.md (100%) diff --git a/SUMMARY.md b/SUMMARY.md index 1e019ff..dc0300b 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -22,18 +22,18 @@ ## 使用 Gradle 构建 -* [命令行界面](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md) - * [执行 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md) - * [常用 tasks](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md) - * [项目报告](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md) - * [命令行补全](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md) - * [Debug 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md) - * [Performance 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md) - * [Logging 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md) - * [Execution 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md) - * [Environment 选项](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md) - * [Bootstrapping new projects](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md) - * [Continuous Build](shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md) +* [命令行界面](shi-yong-gradle-gou-jian/command-line-interface.md) + * [执行 tasks](shi-yong-gradle-gou-jian/command-line-interface/executing-tasks.md) + * [常用 tasks](shi-yong-gradle-gou-jian/command-line-interface/common-tasks.md) + * [项目报告](shi-yong-gradle-gou-jian/command-line-interface/project-reporting.md) + * [命令行补全](shi-yong-gradle-gou-jian/command-line-interface/command-line-completion.md) + * [Debug 选项](shi-yong-gradle-gou-jian/command-line-interface/debugging-options.md) + * [Performance 选项](shi-yong-gradle-gou-jian/command-line-interface/performance-options.md) + * [Logging 选项](shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md) + * [Execution 选项](shi-yong-gradle-gou-jian/command-line-interface/execution-options.md) + * [Environment 选项](shi-yong-gradle-gou-jian/command-line-interface/environment-options.md) + * [Bootstrapping new projects](shi-yong-gradle-gou-jian/command-line-interface/bootstrapping-new-projects.md) + * [Continuous Build](shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md) * [Customizing Execution](shi-yong-gradle-gou-jian/customizing-execution.md) * [Configuring Build Environment](shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md) * [Configuring Gradle Daemon](shi-yong-gradle-gou-jian/customizing-execution/configuring-gradle-daemon.md) diff --git a/installing_gradle/prerequisites.md b/installing_gradle/prerequisites.md index fc40e93..90c19a1 100644 --- a/installing_gradle/prerequisites.md +++ b/installing_gradle/prerequisites.md @@ -1,8 +1,15 @@ -# 准备阶段 +# 预备知识 -Gradle 需要运行在一个 Java 环境里 +Gradle 可以在所有的主流操作系统上运行. 只需要安装 [Java JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 7 以及更高的版本. 用户可以通过运行 `java -version` 命令来查看Java JDK 的版本: -* 安装一个 Java JDK 或者 JRE. 而且 Java 版本必须至少是 6 以上. -* Gradle 自带 Groovy 库, 所以没必要安装 Groovy. 任何已经安装的 Groovy 会被 Gradle 忽略. +``` +❯ java -version +java version "1.8.0_151" +Java(TM) SE Runtime Environment (build 1.8.0_151-b12) +Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) +``` + +Gradle 自带 Groovy library, 所以用户不需要安装 Groovy. 所有已经安装的 Groovy 都会被 Gradle 忽略. + +Gradle 会直接使用你路径里默认的 JDK. 或者, 你可以设置环境变量`JAVA_HOME `来指定需要使用的 JDK. -Gradle 使用任何已经存在在你的路径中的 JDK (可以通过 **java -version** 检查, 如果有就说明系统已经安装了 Java 环境). 或者, 你也可以设置 JAVA_HOME 环境参数来指定希望使用的JDK的安装目录. diff --git a/installing_gradle/yu-bei-zhi-shi.md b/installing_gradle/yu-bei-zhi-shi.md deleted file mode 100644 index 90c19a1..0000000 --- a/installing_gradle/yu-bei-zhi-shi.md +++ /dev/null @@ -1,15 +0,0 @@ -# 预备知识 - -Gradle 可以在所有的主流操作系统上运行. 只需要安装 [Java JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 7 以及更高的版本. 用户可以通过运行 `java -version` 命令来查看Java JDK 的版本: - -``` -❯ java -version -java version "1.8.0_151" -Java(TM) SE Runtime Environment (build 1.8.0_151-b12) -Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) -``` - -Gradle 自带 Groovy library, 所以用户不需要安装 Groovy. 所有已经安装的 Groovy 都会被 Gradle 忽略. - -Gradle 会直接使用你路径里默认的 JDK. 或者, 你可以设置环境变量`JAVA_HOME `来指定需要使用的 JDK. - diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md b/shi-yong-gradle-gou-jian/command-line-interface.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian.md rename to shi-yong-gradle-gou-jian/command-line-interface.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md b/shi-yong-gradle-gou-jian/command-line-interface/bootstrapping-new-projects.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/bootstrapping-new-projects.md rename to shi-yong-gradle-gou-jian/command-line-interface/bootstrapping-new-projects.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md b/shi-yong-gradle-gou-jian/command-line-interface/command-line-completion.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/ming-ling-xing-bu-quan.md rename to shi-yong-gradle-gou-jian/command-line-interface/command-line-completion.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md b/shi-yong-gradle-gou-jian/command-line-interface/common-tasks.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/common-tasks.md rename to shi-yong-gradle-gou-jian/command-line-interface/common-tasks.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md b/shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/continuous-build.md rename to shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md b/shi-yong-gradle-gou-jian/command-line-interface/debugging-options.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/debugging-options.md rename to shi-yong-gradle-gou-jian/command-line-interface/debugging-options.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md b/shi-yong-gradle-gou-jian/command-line-interface/environment-options.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/environment-options.md rename to shi-yong-gradle-gou-jian/command-line-interface/environment-options.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md b/shi-yong-gradle-gou-jian/command-line-interface/executing-tasks.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/executing-tasks.md rename to shi-yong-gradle-gou-jian/command-line-interface/executing-tasks.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md b/shi-yong-gradle-gou-jian/command-line-interface/execution-options.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/execution-options.md rename to shi-yong-gradle-gou-jian/command-line-interface/execution-options.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md b/shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/logging-xuan-xiang.md rename to shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md b/shi-yong-gradle-gou-jian/command-line-interface/performance-options.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/performance-options.md rename to shi-yong-gradle-gou-jian/command-line-interface/performance-options.md diff --git a/shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md b/shi-yong-gradle-gou-jian/command-line-interface/project-reporting.md similarity index 100% rename from shi-yong-gradle-gou-jian/ming-ling-xing-jie-mian/project-reporting.md rename to shi-yong-gradle-gou-jian/command-line-interface/project-reporting.md From a0d82d937567abd0f894d3db0811c66818e5f604 Mon Sep 17 00:00:00 2001 From: DONG Date: Mon, 9 Apr 2018 23:08:39 +0800 Subject: [PATCH 088/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 4 +- .../logging-xuan-xiang.md | 56 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index dc0300b..98c90da 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -6,7 +6,7 @@ ## 开始 * [安装Gradle](installing_gradle/README.md) - * [预备知识](installing_gradle/yu-bei-zhi-shi.md) + * [预备知识](installing_gradle/prerequisites.md) * [通过 Package Manager 安装](installing_gradle/tong-guo-package-manager-an-zhuang.md) * [手动安装](installing_gradle/shou-dong-an-zhuang.md) * [确认是否安装成功](installing_gradle/que-ren-shi-fou-an-zhuang-cheng-gong.md) @@ -29,7 +29,7 @@ * [命令行补全](shi-yong-gradle-gou-jian/command-line-interface/command-line-completion.md) * [Debug 选项](shi-yong-gradle-gou-jian/command-line-interface/debugging-options.md) * [Performance 选项](shi-yong-gradle-gou-jian/command-line-interface/performance-options.md) - * [Logging 选项](shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md) + * [Logging 选项](shi-yong-gradle-gou-jian/command-line-interface/logging-options.md) * [Execution 选项](shi-yong-gradle-gou-jian/command-line-interface/execution-options.md) * [Environment 选项](shi-yong-gradle-gou-jian/command-line-interface/environment-options.md) * [Bootstrapping new projects](shi-yong-gradle-gou-jian/command-line-interface/bootstrapping-new-projects.md) diff --git a/shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md b/shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md index 6b369bc..728fb13 100644 --- a/shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md +++ b/shi-yong-gradle-gou-jian/command-line-interface/logging-xuan-xiang.md @@ -1,12 +1,12 @@ # Logging 选项 -### 设置 log level +### 设置日志级别 -以下为自定义 Gradle logging 相关的选项, 从显示最少的信息到最多的信息. 阅读[logging documentation](https://docs.gradle.org/current/userguide/logging.html)了解更多. +以下为自定义 Gradle 日志相关的选项, 从显示最少的信息到最多的信息. 阅读[logging documentation](https://docs.gradle.org/current/userguide/logging.html)了解更多. `-Dorg.gradle.logging.level=(quiet,warn,lifecycle,info,debug)` -Set logging level via Gradle properties. +通过 Gradle properties 设置日志级别. `-q`,`--quiet` @@ -14,75 +14,75 @@ Set logging level via Gradle properties. `-w`,`--warn` -Set log level to warn. +设置 warn 日志级别. `-i`,`--info` -Set log level to info. +设置 info 日志级别. `-d`,`--debug` -Log in debug mode \(includes normal stacktrace\). +设置日志为 debug 模式 \(包含正常的堆栈跟踪信息\). -Lifecycle is the default log level. +Log 级别默认为 Lifecycle. ### 自定义 log 样式 -You can control the use of rich output \(colors and font variants\) by specifying the "console" mode in the following ways: +你可以通过下列方法指定 "console" 模式来控制输出的样式 \(颜色和字体\): `-Dorg.gradle.console=(auto,plain,rich,verbose)` -Specify console mode via Gradle properties. Different modes described immediately below. +通过 Gradle properties 指定控制台模式. `--console=(auto,plain,rich,verbose)` -Specifies which type of console output to generate. +指定输出的控制台类型. -Set to`plain`to generate plain text only. This option disables all color and other rich output in the console output. This is the default when Gradle is_not_attached to a terminal. +* `plain` 类型只产生纯文本. 所有的颜色和其他样式都被取消. 这也是 Gradle 没和终端连接在一起的默认类型. -Set to`auto`\(the default\) to enable color and other rich output in the console output when the build process is attached to a console, or to generate plain text only when not attached to a console._This is the default when Gradle is attached to a terminal._ +* `auto`\(默认\) 类型是当构建进程显示在控制台的时候会激活控制台输出的颜色和其他样式, 如果未显示在控制台, 那就是纯文本. 这是 Gradle 未连接到终端的默认类型. -Set to`rich`to enable color and other rich output in the console output, regardless of whether the build process is not attached to a console. When not attached to a console, the build output will use ANSI control characters to generate the rich output. +* `rich` 类型是指无论构建进程是否连接到控制台, 都会激活控制台输出的颜色和样式. 当没有连接的时候, 构建输出会使用 ANSI control characters 来生成输出的样式. -Set to`verbose`to enable color and other rich output like the`rich`, but output task names and outcomes at the lifecycle log level, as is done by default in Gradle 3.5 and earlier. +* `verbose` 类型会像 `rich` 一样激活颜色和样式, 但是是输出任务名和结果在 lifecycle log 级别, 就像在 Gradle 3.5 及以前都是如此. -### Showing or hiding warnings +### 显示或者隐藏警告 -By default, Gradle won’t display all warnings \(e.g. deprecation warnings\). Instead, Gradle will collect them and render a summary at the end of the build like: +默认地, Gradle 不会显示所有的警告 \(e.g. deprecation 警告\). 取而代之, Gradle 会在构建结束后收集并生成一个报告: ``` Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0. ``` -You can control the verbosity of warnings on the console with the following options: +你可以控制控制台中显示的警告的日志级别: `-Dorg.gradle.warning.mode=(all,none,summary)` -Specify warning mode via[Gradle properties](https://docs.gradle.org/current/userguide/command_line_interface.html). Different modes described immediately below. +通过 Gradle properties 指定警告模式. `--warning-mode=(all,none,summary)` -Specifies how to log warnings. Default is`summary`. +指定如何在日志中显示警告. 默认是`summary`. -Set to`all`to log all warnings. +* `all` 显示所有警告. -Set to`summary`to suppress all warnings and log a summary at the end of the build. +* `summary` 只在构建结束后显示一个报告. -Set to`none`to suppress all warnings, including the summary at the end of the build. +* `none` 忽略所有警告, 也不在结束后生成报告. -### Rich Console +### 富文本控制台 -Gradle’s rich console displays extra information while builds are running. +Gradle 的富文本控制台可以显示更多额外的信息: ![](https://docs.gradle.org/current/userguide/img/rich-cli.png "Gradle Rich Console") -Features: +特点: -* Logs above grouped by task that generated them +* 上面的日志都是通过生成它们的任务来分组的 -* Progress bar and timer visually describe overall status +* 进度条和计时器非常直观的描述了全局的状态 -* Parallel work-in-progress lines below describe what is happening now +* 进度条下方同步执行的命令行描述当前正在执行的任务 From 66cd771061f1a3cec10f84a39c602500ba960dfe Mon Sep 17 00:00:00 2001 From: DONG Date: Tue, 10 Apr 2018 20:59:46 +0800 Subject: [PATCH 089/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E6=8C=81=E7=BB=AD?= =?UTF-8?q?=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../continuous-build.md | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md b/shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md index 3d11948..73e23d0 100644 --- a/shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md +++ b/shi-yong-gradle-gou-jian/command-line-interface/continuous-build.md @@ -1,58 +1,60 @@ -Continuous Build allows you to automatically re-execute the requested tasks when task inputs change. +# 持续构建 -For example, you can continuously run the`test`task and all dependent tasks by running: +当有任务输入改变的时候, 持续构建 (Continuous Build) 允许你自动重新执行任务. + +通常情况下, 你会指定要执行的任务让 Gradle 来执行. Gradle会分析你给出的任务需要执行的所有任务集合, 按照顺序全部执行它们, 然后停下来等你的下一次指令. 持续构建则不同, 它会按照你给出的任务指令, 不断的分析任务输入是否改变, 如果改变则再次执行,除非你强制让它停下来. 比如你的任务是把 java 的源文件编译为 class 文件, 那么当java源文件改变时, 构建就会自动再次执行. + +举个例子, 你可以通过下面的命令持续运行 `test` 任务以及所有依赖的任务: ``` -❯ gradle test --continuous +> gradle test --continuous ``` -Gradle will behave as if you ran`gradle test`after a change to sources or tests that contribute to the requested tasks. This means that unrelated changes \(such as changes to build scripts\) will not trigger a rebuild. In order to incorporate build logic changes, the continuous build must be restarted manually. - -### Terminating Continuous Build +当源代码改变或者测试的改变都会使 Gradle 自动运行 `gradle test`. 但是和该任务无关的改变 \(比如构建脚本的改变\) 将不会触发重新构建. 如果是构建逻辑的改变, 持续构建必须重新启动才会起作用. -If Gradle is attached to an interactive input source, such as a terminal, the continuous build can be exited by pressing`CTRL-D`\(On Microsoft Windows, it is required to also press`ENTER`or`RETURN`after`CTRL-D`\). If Gradle is not attached to an interactive input source \(e.g. is running as part of a script\), the build process must be terminated \(e.g. using the`kill`command or similar\). If the build is being executed via the Tooling API, the build can be cancelled using the Tooling API’s cancellation mechanism. +### 结束持续构建 -### Limitations and quirks +如果 Gradle 和一个可以交互的输入源关联起来了, 比如终端, 你可以通过按 `CTRL-D` 键来退出持续构建\(在 Windows 上, 还需要在`CTRL-D`之后按`ENTER`或`RETURN`\). 如果 Gradle 没有和任务可以互动的输入源关联 \(e.g. 比如作为一个脚本的一部分在运行\), 构建进程就必须被终止 \(e.g. 使用 `kill` 命令\). 如果构建是通过 Tooling API 执行的, 构建可以通过 Tooling API 取消机制来取消. -Continuous build is an[incubating](https://docs.gradle.org/4.6/userguide/feature_lifecycle.html)feature. +### 限制 -There are several issues to be aware with the current implementation of continuous build. These are likely to be addressed in future Gradle releases. +持续构建是一个正在被[孵化](https://docs.gradle.org/4.6/userguide/feature_lifecycle.html)的功能. 它目前有许多问题. 将会在将来的发布里逐渐修复. -#### Build cycles +#### 构建周期 -Gradle starts watching for changes just before a task executes. If a task modifies its own inputs while executing, Gradle will detect the change and trigger a new build. If every time the task executes, the inputs are modified again, the build will be triggered again. This isn’t unique to continuous build. A task that modifies its own inputs will never be considered up-to-date when run "normally" without continuous build. +Gradle 在一个任务执行之前就会开始观测改变. 如果一个任务执行的时候更改它自己的输入, Gradle 就会检测到改变并触发一个新的构建. 如果每次这个任务执行, 输入都会被改变, 那么这个构建就会一直被重复触发下去. 如果不使用持续构建, 一个任务改变它自己的输入永远都不会认为是一种状态的更新. -If your build enters a build cycle like this, you can track down the task by looking at the list of files reported changed by Gradle. After identifying the file\(s\) that are changed during each build, you should look for a task that has that file as an input. In some cases, it may be obvious \(e.g., a Java file is compiled with`compileJava`\). In other cases, you can use`--info`logging to find the task that is out-of-date due to the identified files. +如果你的构建进入这样一种循环, 你可以追踪 Gradle 显示的变化的文件列表. 在找到文件之后, 你应该继续查找以这个文件作为输入的任务. 在许多情况下, 这非常好找 \(比如, 一个 Java 文件被 `compileJava` 任务编译\). 在其它的情况下, 你可以使用 `--info` 日志来查找过期的文件. -#### Restrictions with Java 9 +#### Java 9 的限制 -Due to class access restrictions related to Java 9, Gradle cannot set some operating system specific options, which means that: +由于 Java 9 的类的进入权限限制, Gradle 不能设置一些操作系统的特殊选项: -* On macOS, Gradle will poll for file changes every 10 seconds instead of every 2 seconds. +* 在 macOS 上, Gradle 将会每 10 秒检查一次文件的改变, 而不是 2 秒. -* On Windows, Gradle must use individual file watches \(like on Linux/Mac OS\), which may cause continuous build to no longer work on very large projects. +* 在 Windows 上, Gradle 必须使用另外的文件观察器 \(就像在 Linux/Mac OS 上\), 这可能会引起在部分大项目中持续构建无法工作. -#### Performance and stability +#### 性能和稳定性 -The JDK file watching facility relies on inefficient file system polling on macOS \(see:[JDK-7133447](https://bugs.openjdk.java.net/browse/JDK-7133447)\). This can significantly delay notification of changes on large projects with many source files. +JDK file watching facility 依赖于 macOS 上效率低下的文件轮询 \(see:[JDK-7133447](https://bugs.openjdk.java.net/browse/JDK-7133447)\). 在大型项目上, 这会严重延迟关于改变的通知. -Additionally, the watching mechanism may deadlock under_heavy_load on macOS \(see:[JDK-8079620](https://bugs.openjdk.java.net/browse/JDK-8079620)\). This will manifest as Gradle appearing not to notice file changes. If you suspect this is occurring, exit continuous build and start again. +另外, 观测机制可能锁死 macOS 系统上的 under_heavy_load \(see:[JDK-8079620](https://bugs.openjdk.java.net/browse/JDK-8079620)\). Gradle 就不能注意到文件的变化. 如果你碰到这种情况, 退出持续构建并重新启动. -On Linux, OpenJDK’s implementation of the file watch service can sometimes miss file system events \(see:[JDK-8145981](https://bugs.openjdk.java.net/browse/JDK-8145981)\). +在 Linux 上, OpenJDK 关于 file watch service 的实现有时候会错过一些文件系统时间\(see:[JDK-8145981](https://bugs.openjdk.java.net/browse/JDK-8145981)\). -#### Changes to symbolic links +#### symbolic links 的改变 -* Creating or removing symbolic link to files will initiate a build. +* 创建或者移除一个会初始化一个构建 -* Modifying the target of a symbolic link will not cause a rebuild. +* 改变 symbolic link 指向的对象不会触发重新构建. -* Creating or removing symbolic links to directories will not cause rebuilds. +* 创建或者移除指向文件夹的 symbolic link 不会触发重新构建. -* Creating new files in the target directory of a symbolic link will not cause a rebuild. +* 在 symbolic link 指向的文件夹中创建新的文件不会触发重新构建. -* Deleting the target directory will not cause a rebuild. +* 删除指向的文件不会引起重新构建. -#### Changes to build logic are not considered +#### 忽略构建逻辑的改变 -The current implementation does not recalculate the build model on subsequent builds. This means that changes to task configuration, or any other change to the build model, are effectively ignored. +现在的实现并没有重新计算执行序列中随后构建上的构建模型. 这意味着任务配置的改变或者一些其它的构建模型的改变都将被忽略. From bb6a75151274be2d3651175abbc434915e820f8a Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 11 Apr 2018 18:55:45 +0800 Subject: [PATCH 090/102] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 658ce37..cad19dd 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ ##### 使用 Gradle 构建 -* [ ] [Command-Line Interface](https://docs.gradle.org/current/userguide/command_line_interface.html) ([@DONGChuan](https://github.com/DONGChuan)) -* [ ] [Customizing Execution](https://docs.gradle.org/current/userguide/userguide.html#customizing-execution) +* [x] [Command-Line Interface](https://docs.gradle.org/current/userguide/command_line_interface.html) ([@DONGChuan](https://github.com/DONGChuan)) +* [ ] [Customizing Execution](https://docs.gradle.org/current/userguide/userguide.html#customizing-execution) ([@DONGChuan](https://github.com/DONGChuan)) * [ ] [Executing Multi-Project Builds](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html) * [ ] [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) * [ ] [Troubleshooting](https://docs.gradle.org/current/userguide/troubleshooting.html) From 18ee4bf8da1bd6b1cbd0c2b31413e86c661144c1 Mon Sep 17 00:00:00 2001 From: DONG Date: Wed, 11 Apr 2018 19:49:48 +0800 Subject: [PATCH 091/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=9E=84=E5=BB=BA=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuring-build-environment.md | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md index 8a793a2..2ee5b71 100644 --- a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md +++ b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md @@ -1,38 +1,40 @@ -Gradle provides multiple mechanisms for configuring behavior of Gradle itself and specific projects. The following is a reference for using these mechanisms. +# 配置构建环境 -When configuring Gradle behavior you can use these methods, listed in order of highest to lowest precedence \(first one wins\): +Gradle 提供数种机制来配置 Gradle 自身以及特殊的项目. -* [Command-line flags](https://docs.gradle.org/4.6/userguide/command_line_interface.html)such as`--build-cache`. These have precedence over properties and environment variables. +但配置 Gradle 的行为的时候, 你可以使用下列方法, 按优先权从高到低排列 \(第一个最高\): -* [System properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_system_properties)such as`systemProp.http.proxyHost=somehost.org`stored in a`gradle.properties`file. +* [Command-line flags](https://docs.gradle.org/4.6/userguide/command_line_interface.html)比如`--build-cache`. 它比属性和环境变量有更高的优先权. -* [Gradle properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_configuration_properties)such as`org.gradle.caching=true`that are typically stored in a`gradle.properties`file in a project root directory or`GRADLE_USER_HOME`environment variable. +* [System 属性](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_system_properties)比如`gradle.properties`文件里的`systemProp.http.proxyHost=somehost.org`. -* [Environment variables](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_environment_variables)such as`GRADLE_OPTS`sourced by the environment that executes Gradle. +* [Gradle 属性](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_configuration_properties)比如项目根目录`gradle.properties`文件里的`org.gradle.caching=true`. -Aside from configuring the build environment, you can configure a given project build using[Project properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:project_properties)such as`-PreleaseType=final`. +* [环境变量](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_environment_variables)比如环境变量`GRADLE_OPTS`. -## Gradle properties +除了配置构建环境, 你可以使用[项目属性]来配置一个给定的项目(https://docs.gradle.org/4.6/userguide/build_environment.html#sec:project_properties), 比如`-PreleaseType=final`. -Gradle provides several options that make it easy to configure the Java process that will be used to execute your build. While it’s possible to configure these in your local environment via`GRADLE_OPTS`or`JAVA_OPTS`, it is useful to store certain settings like JVM memory configuration and Java home location in version control so that an entire team can work with a consistent environment. +## Gradle 属性 -Setting up a consistent environment for your build is as simple as placing these settings into a`gradle.properties`file. The configuration is applied in following order \(if an option is configured in multiple locations the_last one wins_\): +Gradle 提供数种选项来简化配置执行构建的 Java 进程. 当然, 你也可以通过你的本地环境变量`GRADLE_OPTS`或`JAVA_OPTS`来配置, 然后通过 Gradle 属性来设置, 这些设置就可以储存在版本控制里(比如git), 比如 JVM memory 配置和 Java home location, 这样的话, 一整个团队都可以保持一致的构建环境. -* `gradle.properties`in project root directory. +你只需要将这些设置统一放在`gradle.properties`文件里就可以保持一致的构建环境. 所有的配置将会以下列的顺序来实行: -* `gradle.properties`in`GRADLE_USER_HOME`directory. +* 项目根目录的`gradle.properties`. -* system properties, e.g. when`-Dgradle.user.home`is set on the command line. +* `GRADLE_USER_HOME` 目录里的 `gradle.properties`. -The following properties can be used to configure the Gradle build environment: +* system 属性, e.g. 当在命令行设置`-Dgradle.user.home`. + +下列属性可以被用来配置 Gradle 构建环境: `org.gradle.caching=(true,false)` -When set to true, Gradle will reuse task outputs from any previous build, when possible, resulting is much faster builds. Learn more about[using the build cache](https://docs.gradle.org/4.6/userguide/build_cache.html). +当设置为真, Gradle 会重复使用之前任务的输出, 这样执行更加高效. 可以阅读[使用构建缓存](https://docs.gradle.org/4.6/userguide/build_cache.html)了解更多. `org.gradle.caching.debug=(true,false)` -When set to true, individual input property hashes and the build cache key for each task are logged on the console. Learn more about[task output caching](https://docs.gradle.org/4.6/userguide/build_cache.html#sec:task_output_caching). +当设置为真, 每一个独立的输入属性哈希值以及每一个任务的构建缓存的键值都会以日志的形式显示在控制台. 可以阅读[任务输出缓存](https://docs.gradle.org/4.6/userguide/build_cache.html#sec:task_output_caching)了解更多. `org.gradle.configureondemand=(true,false)` @@ -40,23 +42,23 @@ Enables incubating[configuration on demand](https://docs.gradle.org/4.6/userguid `org.gradle.console=(auto,plain,rich,verbose)` -Customize console output coloring or verbosity. Default depends on how Gradle is invoked. See[command-line logging](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_logging)for additional details. +自定义控制台输出的颜色或显示的内容级别. 查看[命令行日志](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_logging)了解更多. `org.gradle.daemon=(true,false)` -When set to`true`the[Gradle Daemon](https://docs.gradle.org/4.6/userguide/gradle_daemon.html)is used to run the build. Default is`true`. +当设置为真, [Gradle 守护进程](https://docs.gradle.org/4.6/userguide/gradle_daemon.html)就会被使用来构建. 默认为真. `org.gradle.daemon.idletimeout=(# of idle millis)` -Gradle Daemon will terminate itself after specified number of idle milliseconds. Default is`10800000`\(3 hours\). +Gradle 守护进程会在空闲指定的毫秒后结束自己. 默认是`10800000`\(3 个小时\). `org.gradle.debug=(true,false)` -When set to`true`, Gradle will run the build with remote debugging enabled, listening on port 5005. Note that this is the equivalent of adding`-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005`to the JVM command line and will suspend the virtual machine until a debugger is attached. Default is`false`. +当设置为真, Gradle 将会激活远程调试来构建, 监听 5005 端口. 注意, 这其实就是添加 `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005` 选项到 JVM 命令行, 将会暂停虚拟机直到一个调试器关联起来. 默认是`false`. `org.gradle.java.home=(path to JDK home)` -Specifies the Java home for the Gradle build process. The value can be set to either a`jdk`or`jre`location, however, depending on what your build does, using a JDK is safer. A reasonable default is used if the setting is unspecified. +为 Gradle 构建进程指定 Java home. 既可以是`jdk`也可以是`jre`的位置, 然后, 根据你的构建要做什么, 使用 JDK 可能更安全. `org.gradle.jvmargs=(JVM arguments)` From 3975318d954832645c6223708a3b525d5b7b0713 Mon Sep 17 00:00:00 2001 From: Burjal Date: Thu, 12 Apr 2018 00:07:43 +0800 Subject: [PATCH 092/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E6=9E=84=E5=BB=BAAnd?= =?UTF-8?q?roid=E5=BA=94=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/gou-jian-android-ying-yong.md | 345 +++++++----------- 1 file changed, 125 insertions(+), 220 deletions(-) diff --git a/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md b/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md index 7a3163c..2da5c80 100644 --- a/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md +++ b/xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md @@ -1,123 +1,97 @@ # 构建Android应用 -Android applications \(known colloquially as_apps_\) use Gradle as their build tool, normally through the only supported IDE, Android Studio. Many resources are available for learning how to build Android applications. This guide, however, focuses on the details of the Gradle build files generated when creating a new Android application, and how to use Gradle to invoke relevant build tasks for them. +Android应用程序(也称为apps)通过唯一支持的IDE(集成开发环境)Android Studio采用Gradle作为编译工具。可以找到许多学习如何构建Android应用程序的资源。然而这篇用户手册,关注于创建新的Android应用程序时Gradle编译生成文件的细节,以及如何通过Gradle执行相关的构建任务(task)。 -Contents +## [编译将产生的内容](#what_you_ll_build) {#what_you_ll_build} -* [What you’ll build](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_build) -* [What you’ll need](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_need) -* [Create a new Android Studio project](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#create_a_new_android_studio_project) -* [Review the list of generated Gradle files](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_list_of_generated_gradle_files) -* [Review the top-level Gradle build file](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_top_level_gradle_build_file) -* [Review the build file in the app module](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_build_file_in_the_app_module) -* [Run standard Gradle tasks](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#run_standard_gradle_tasks) -* [Use the Gradle window](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#use_the_gradle_window) -* [Publish a build scan](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#publish_a_build_scan) -* [Summary](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#summary) -* [Next Steps](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#next_steps) -* [Help improve this guide](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#help_improve_this_guide) +你将创建一个“Hello,World!”Android应用程序,浏览其生成的Gradle构建文件以及执行一些常见任务(task)。 -## [What you’ll build](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_build) {#what_you_ll_build} +## [准备工作](#what_you_ll_need) {#what_you_ll_need} -You’ll create a "Hello, World!" type of Android application, explore its generated Gradle build files, and execute common tasks using them. +* 26分钟左右 -## [What you’ll need](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#what_you_ll_need) {#what_you_ll_need} +* version 2.4或更高版本的Android Studio。可以[下载](https://developer.android.com/studio/index.html) 带有最新版本Android SDK的Android Studio。集成开发环境(IDE)所需的系统配置要求详见上述下载网页 -* About26 minutes +* version 1.7或更高版本的JDK -* Android Studio, version 2.4 or higher. You can download Android Studio, along with the latest Android SDK, from[https://developer.android.com/studio/index.html](https://developer.android.com/studio/index.html). The system requirements for the IDE are also found at that link. +## [创建 Android Studio 项目](#create_a_new_android_studio_project) {#create_a_new_android_studio_project} -* The Java Development Kit \(JDK\), version 1.7 or higher - -## [Create a new Android Studio project](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#create_a_new_android_studio_project) {#create_a_new_android_studio_project} - -After downloading and installing Android Studio, start the application. On the welcome screen, click the link entitled, "Start a new Android Studio project", as shown in the figure. When ready, click_Next_. +下载安装Android Studio后打开应用。在欢迎界面,如下图所示,点击标题链接 `Start a new Android Studio Project` (新建一个Android Studio项目)” 。当应用准备就绪,点击 `Next` 按钮。 ![](https://guides.gradle.org/building-android-apps/images/Welcome-to-Android-Studio.png "Welcome to Android Studio") -On the "Create Android Project" screen, set the application name to "HelloWorldGradle", the company domain to your own \(the domain_gradle.org\_is used in the accompanying figure\), and select any convenient directory for the project location. Then click\_Next_. +在 `Create Android Project` (创建Android项目)页面,设置应用名( `Application name` )为 `HelloWorldGradle` ,设置公司域名(如附图中使用的是 `gradle.org` 域名),并为项目选择方便的目录。然后点击 `Next` 按钮。 ![](https://guides.gradle.org/building-android-apps/images/Create-New-Project.png "Create New Project") -On the "Target Android Devices" screen, select\_Phone and Tablet\_and choose any recent API level from the\_Minimum SDK\_drop-down list. The figure shows API 19, which is common, but the value chose will not affect the rest of this guide. +在 `Target Android Devices` (在目标Android设备)页面,选中 `Phone and Tablet` (手机和平板电脑)并且从 `Minimum SDK` (最低SDK版本)下拉菜单中选择任意一个版本的API。如图选择的是比较通用的 `API 19`,并且选中的值对接下来的引导没有影响。 ![](https://guides.gradle.org/building-android-apps/images/Target-Android-Devices.png "Target Android Devices") -On the "Add an Activity" screen, select_Empty Activity\_and click\_Next_. +在 `Add an Activity` (添加一个活动)页面,选中 `Empty Activity` (空的活动)然后点击 `Next` 按钮。 -Accept all the defaults on the "Configure Activity" screen and click_Finish_. +在 `Configure Activity` (配置活动)页面接收所有默认值,然后点击 `Finish` (完成)按钮。 ![](https://guides.gradle.org/building-android-apps/images/Configure-Activity.png "Configure Activity") -## [Review the list of generated Gradle files](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_list_of_generated_gradle_files) {#review_the_list_of_generated_gradle_files} +## [查看生成的Gradle文件列表](#review_the_list_of_generated_gradle_files) {#review_the_list_of_generated_gradle_files} -By default, Android Studio will start with a "Project View" in "Android" mode, as shown in the figure: +如下图所示,Android Studio默认在 `Project View` (项目视图)中打开 `Android` 模式: ![](https://guides.gradle.org/building-android-apps/images/Project-View-Android.png "Project View Android") -Android projects are Gradle multi-project builds, with a top-level`build.gradle`file and a subdirectory called`app`, with its own`build.gradle`file. The top-level build file is noted as`(Project: HelloWorldGradle)`in the figure, and the`app`build file has`(Module: app)`appended to it. +Android项目是Gradle多项目构建,有一个顶级目录(根目录) `build.gradle` 文件和一个有自己 `build.gradle` 文件的 `app` 子目录。顶级目录构建文件在上图中标记为 `(Project:HelloWorldGradle)` ,`app` 构建文件是附加到它后面的 `Module:app` 。 -There may be two files called`gradle.properties`. One is local to the project. The other, optional file of the same name exists only if you have a global`gradle.properties`file in the`.gradle`sub-directory of your home directory. +项目里可能有两个名为 `gradle.properties` 的文件。一个是项目本地的,另一个是只有在电脑根目录的 `.gradle` 子目录中有一个全局的 `gradle.properties` 文件才存在的相同名称的可选文件。 -The file`settings.gradle`is used by Gradle to configure the multi-project build. It should consist of a single line: +`settings.gradle` 文件被Gradle用来配置多项目构建。它应该由如下线性结构组成: ``` -include -' -:app -' +include ':app' ``` -This tells Gradle that the`app`sub-directory is also a Gradle project. If, at some later time, you were to add an Android Library to this project through the available wizard, another project sub-directory would be created and added to this file. +这个设置告诉Gradle, `app` 子目录也是一个Gradle项目。如果在将来的时间里,你通过向导向该项目添加一个 `Android Library` (Android库),另一个项目的子目录将会被创建并被添加到当前文件(夹)里。 -The last file is called`gradle-wrapper.properties`, which configures the so-called Gradle Wrapper. This allows you to build Android projects without having to install Gradle first. The contents of the file should be similar to: +最后一个文件是 `gradle-wrapper.properties` ,它配置了所谓的 `Gradle Wrapper` 。它允许你不需要现在Gradle就可以编译Android项目。该文件内容应该类似于: -``` +```GROOVY distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https -\ -: -//services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip ``` -The first four lines indicate that when the wrapper runs the first time, it will download a Gradle distribution and store it in the directory`.gradle/wrapper/dists`in your home directory. +前四行表明当wrapper第一次运行时,它会下载Gradle发行版本并将其存储在根目录的 `.gradle/wrapper/dists` 目录中。 -The last line shows the value of the`distributionUrl`, which is the location where Gradle will download the distribution specified. +最后一行显示了 `distributionUrl` (发行版本URL)的值,将要下载指定Gradle发行版本的下载地址。 -| | The specific version number might differ from that shown here \(4.1\), and the URL might refer to a binary version \(`-bin`\) instead of the complete \(`-all`\) version shown in this example. | -| :--- | :--- | +> 项目具体版本号可能于此处显示的版本号(4.1)不同,并且URL可能引用到一个二进制版本( `bin` )而不是上述示例中的完整版本( `all` )。 +## [查看顶级目录Gradle构建文件](#review_the_top_level_gradle_build_file) {#review_the_top_level_gradle_build_file} -## [Review the top-level Gradle build file](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_top_level_gradle_build_file) {#review_the_top_level_gradle_build_file} +项目里顶级目录 `build.gradle` 文件内容应该类似于: -The project`build.gradle`file should have contents similar to: - -``` +```GROOVY +// 可以在顶级目录构建文件添加普适于所有子项目及模块的配置 // Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { +buildscript { // 下载插件代码块 repositories { google() jcenter() } - dependencies { - - classpath -' -com.android.tools.build:gradle:3.0.1 -' -// NOTE: Do not place your application dependencies here; they belong -// in the individual module build.gradle files + dependencies { // 标识Android插件 + classpath 'com.android.tools.build:gradle:3.0.1' + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files } } -allprojects { +allprojects { // 所有项目(顶级和模块项目)的通用配置 repositories { google() @@ -125,184 +99,115 @@ allprojects { } } -task clean( -type -: Delete) { +task clean(type: Delete) { // 一个名叫clean的task delete rootProject.buildDir } ``` -| | Download plugins block | -| :--- | :--- | -| | Identifies the Android plugin | -| | Configuration for top-level and module projects | -| | Ad hoc task | - -Gradle defines a domain-specific language \(DSL\) for builds, used inside the build files. The`buildscript`tag is part of that DSL. It tells Gradle that the build requires a plugin that may not be part of the baseline Gradle distribution, and tells Gradle where to find it. In this case, the required plugin is specified using coordinate syntax "group:name:version", where the group is`com.android.tools.build`, the name is`gradle`, and the version is`3.0.1`. - -| | The version number of the Gradle plugin is updated frequently. Please use the latest plugin, as it will contain all the available bug fixes and performance improvements. | -| :--- | :--- | +Gradle为构建文件定义了用于构建的领域特定语言(DSL)。`buildscript` 标签就是DSL中的一部分。它告诉Gradle编译需要一个可能不在标准Gradle发行版本中的插件,并且告诉Gradle在哪找到它。在上述示例中,所需的插件通过坐标语法“group:name:version”指定,示例中group(依赖分组,Maven中的 `groupId`)是 `com.android.tools.build` ,name(依赖名称,Maven中的artifactId)是 `gradle` ,version(依赖的版本,Maven中的version)是 `3.0.1` 。 +> Gradle插件的版本号经常更新。请使用最新的插件,因为它将包含所有的bug修复和性能优化。 -When Gradle builds this project the first time, the plugin will be downloaded and cached, so this task is only performed once. +当Gradle第一次编译项目的时候,(Gradle)插件会下载下来并缓存到本地,因此这个下载任务只会执行一次。 -The`allprojects`tag holds configuration details that apply to both the top-level project and any sub-projects it contains. In this case, the block specifies that any required dependencies should be downloaded from`google`, or`jcenter`, the public Bintray Artifactory repository at[https://jcenter.bintray.com](https://jcenter.bintray.com/). +`allprojects` 标签持有适用于顶级项目及其包含的任意子项目的配置细节。在上述示例中,代码块声明任何所需的依赖都应该从 `google` 或者 `jcenter` 中下载,其中 `jcenter` 的公共Bintray Artifactory仓储库链接为https://jcenter.bintray.com。 -Finally, the build file contains a custom \(or_ad hoc_\) task, called`clean`. It uses the built-in task type`Delete`and configures it so that the`clean`task will delete the`buildDir`in the`rootProject`. Both are project properties, whose values default to the`build`directory in the project where this app resides. +最后,编译的文件包含一个自定义的(或特定的)任务,任务名叫 `clean` 。它使用并通过配置内建的 `Delete` 任务实现删除项目根目录( `rootProject` )中的编译目录 ( `buildDir` )。两者都是项目属性,它们的默认值是该应用所在项目的构建( `build` )目录。 -## [Review the build file in the app module](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#review_the_build_file_in_the_app_module) {#review_the_build_file_in_the_app_module} +## [查看app模块下的构建文件](#review_the_build_file_in_the_app_module) {#review_the_build_file_in_the_app_module} -Open the`build.gradle`file in the`app`module. The first line is: +打开app模块下的 `buidl.gradle` 文件。第一行是: -``` -apply -plugin -: -' -com.android.application -' +```GROOVY +apply plugin: 'com.android.application' ``` -This "applies" the Android plugin \(referred to in the`buildscript`section of the top-level build file\) to the current project. Plugins in Gradle can add custom tasks, new configurations, dependencies, and other capabilities to Gradle projects. In this case, applying the Android plugin adds a wide variety of tasks, which are configured by the`android`block shown next. +它给当前项目运用了Android插件(在顶级目录构建文件中的 `buildscript` 部分提到的)。Gradle插件可以为Gradle项目添加自定义任务任务,新的配置项,依赖,以及其他的能力。在上述示例中,运用Android插件增加了一批任务,均配置在 `android` 代码块里,如下所示: -``` +```GROOVY android { - compileSdkVersion -26 + compileSdkVersion 26 defaultConfig { - applicationId -" -org.gradle.helloworldgradle -" - - minSdkVersion -19 - - targetSdkVersion -26 - - versionCode -1 - - versionName -" -1.0 -" - - testInstrumentationRunner -" -android.support.test.runner.AndroidJUnitRunner -" + applicationId "org.gradle.helloworldgradle" + minSdkVersion 19 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { - minifyEnabled -false - - proguardFiles getDefaultProguardFile( -' -proguard-android.txt -' -), -' -proguard-rules.pro -' - + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } ``` -These properties are more relevant to Android than the Gradle build system, to they will only be lightly reviewed here. In short: +这些属性同Gradle构建系统相比,与Android关联更大,因为它们只会在这里进行轻微的审查。简言之: -* The`compileSdkVersion`is associated with the Android SDK and should always be the latest available version. +* 编译SDK版本号( `compileSdkVersion` )与Android SDK相关,并且应该保持最新可用的版本。 -* The`defaultConfig`section hold properties that are shared by all variants \(combinations of build types and product flavors\) of the app. +* 默认配置( `defaultConfig` )部分包含应用里所有变体(构建类型和产品风味的组合)共享的属性。 -* The`applicationId`is based on the domain name and project name specified when creating the app, and must be unique in the Google Play store. +* 应用ID( `applicationId` ) 基于创建应用时指定的域名和项目名,并且该值在Google Play商店中必须是唯一的。 -* The value of`minSdkVersion`is the minimum Android API you are willing to support with this app, and the`targetSdkVersion`should be the latest Android version available. +* 支持的最低SDK版本号( `minSdkVersion` )是应用将要支持的最低Android版本,目标SDK版本号( `targetSdkVersion` )应该是最新可用的Android版本。 -* The value of`versionCode`should be an integer that is incremented before uploading a new version of the app into the Google Play store. This value, along with the`applicationId`, tell Google that this is a new version of an existing app, as opposed to a new app. +* 版本号( `versionCode` )应该是一个整数,在将新版本上传到Google Play商店之前需要递增。版本号,和应用ID,告诉Google这是一个已有应用的更新版本,而不是一个新的应用。 -* The`versionName`value is used for your own internal version tracking. +* 版本名称( `versionName` )值用于项目内部的版本跟踪。 -* The`testInstrumentationRunner`property is configured to use the JUnit 4 test runner configured for Android apps. +* `testInstrumentationRunner` 属性指定Android应用采用JUnit 4来测试。 -Below this section is a block called`buildTypes`. By default, Android apps support two build types,`debug`and`release`. This section allows you to configure each however you like. The`debug`section is not shown here, implying that all the default settings for`debug`are being used. +在这部分的下面就是构建类型( `buildTypes` )。Android应用默认有两种构建类型: `debug` 和 `release` 。这个部分允许随意配置。 `debug` 部分并没有展示在上述示例中,这意味着 `debug` 所有设置均使用的默认值。 -After the`android`block, there is a block that shows the libraries used for this app. +在 `android` 代码块后面,展示应用里所使用的库: ``` dependencies { - implementation fileTree( -dir -: -' -libs -' -, -include -: [ -' -*.jar -' -]) - implementation -' -com.android.support:appcompat-v7:26.1.0 -' - - implementation -' -com.android.support.constraint:constraint-layout:1.0.2 -' - - testImplementation -' -junit:junit:4.12 -' - - androidTestImplementation -' -com.android.support.test:runner:1.0.1 -' - - androidTestImplementation -' -com.android.support.test.espresso:espresso-core:3.0.1 -' + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:26.1.0' + + implementation 'com.android.support.constraint:constraint-layout:1.0.2' + + testImplementation 'junit:junit:4.12' + + androidTestImplementation 'com.android.support.test:runner:1.0.1' + + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' } ``` -Configuring dependencies is a fundamental part of building Gradle applications. In this case, the`dependencies`section shows values for the`implementation`,`testImplementation`, and`androidTestImplementation`configurations. +配置依赖关系值构建Gradle应用程序的基础。在上述示例中, `dependencies` (依赖)部分展示了 `implementation` , `testImplementation` 以及 `androidTestImplementation` 部分配置的值。 -Taking the simplest one first, the`testImplementation`dependency consists only of the latest stable JUnit 4 distribution. The JUnit classes and test annotations will then be available at compile time in the`src/test/java`hierarchy. +先从最简单的开始说起, `testImplementation` 依赖项仅包含最新的JUnit 4稳定发行版本。JUnit类和测试的注解将在编译时在 `src/test/java` 层级中可用。 -The`androidTestImplementation`dependency refers to the Espresso testing library, which is used for integration testing of Android apps. In this case, Espresso is requested without the`support-annotations`library that it would normally include, because a different version is already included through other dependencies. In a later step, you’ll see how to find out what version of this library was included and why. +`androidTestImplementation` 依赖是指Espresso测试库,用于Android应用的集成测试。在上述示例中,Espresso没有通常包含的 `support-annotations` 库,因为通过其他依赖已经有了不同的版本( `support-annotations` 库)。在后面的步骤中,你讲看到如何找出依赖该库的版本号以及依赖关系。 -Finally, there are three lines that add dependencies to the`implementation`configuration: +最后,有三行向 `implementation` 添加依赖关系: -* The first,`fileTree(dir: 'libs', include: ['*.jar'])`, is a`fileTree`dependency that adds any jar files in the`libs`folder to the compile classpath +* 首先, `fileTree(dir: 'libs', include: ['*.jar'])` , 是一个文件树( `fileTree` )依赖,将 `libs` 文件里所有jar包添加到编译路径中去 -* The second,`com.android.support:appcompat-v7:26.1.0`adds the Android Compatibility library to the project. This allows you to use the Material design theme and other capabilities in any Android app as old as SDK version 7. +* 其次, `com.android.support:appcompat-v7:26.1.0` 将Android兼容库添加到项目中。它允许你在SDK版本7及以后版本使用Material设计主题以及其他能力。 -* The third,`com.android.support.constraint:constraint-layout:1.0.2`adds the Android Constraint Layout to the project. This allows you to use the ConstraintLayout layout class in any Android app as old as SDK version 9. +* 第三, `com.android.support.constraint:constraint-layout:1.0.2` 将Android约束布局( `Constraint Layout` )添加到项目中。它允许你在SDK9及以后版本中使用 `ConstraintLayout` 布局。 -## [Run standard Gradle tasks](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#run_standard_gradle_tasks) {#run_standard_gradle_tasks} +## [运行标准的Gradle任务](#run_standard_gradle_tasks) {#run_standard_gradle_tasks} -Android Studio makes it easy to build and deploy a debug version of an app through the IDE, but ultimately Gradle is still involved. To see this, open the Terminal window in Android Studio \(or open an external command prompt and navigate to the root directory of your app\). From there you can run the`build`task. +Android Studio通过集成开发环境(IDE)可以轻松构建和部署应用的调试版本,但最终Gradle仍然参与其中。要查看这些信息,打开Android Studio的终端窗口(或打开外部命令窗口并导航至应用所在根目录)。从那你能运行 `build` (编译)任务。 ``` $ ./gradlew build ``` -This will run many tasks and eventually return "Build Successful". To see the resulting APK \(Android package, the deployable version of an Android app\), look in the directory`app/build/outputs/apk`. There you will find a`debug`and a`release`directories. The`debug`directory contains`app-debug.apk`, which is the APK version that will be deployed to an emulator or connected device. If you want to deploy a release APK, you need to create a signing configuration first, which is beyond the scope of this guide, but is a straightforward process described in the resources. +这行命令将要执行许多任务并最终返回"Build Successful"。要查看最终生成的APK(Android包,Android应用的可部署版本), 请查看 `app/build/outputs/apk` 目录。在那你将发现一个 `debug` 和一个 `release` 目录。`debug`目录包含 `app-debug.apk` ,是一个可以部署到模拟器或者已连接设备上的APK版本。如果你想部署一个release APK,首先需要创建一个签名,这部分超出了本指南的范围,但是按照资料描述来只是一个简单的流程。 +从终端你还可以发现 `support-annotations` 模块已经被项目使用了。首先在 `app` 项目里运行 `dependencies` 任务,只查看 `releaseCompileClasspath` 配置的详细信息。 From the terminal, you can also find out the version of the`support-annotations`module being used in the project. To do so, first run the`dependencies`task in the`app`project, asking for the details of the`releaseCompileClasspath`configuration only. ``` @@ -350,9 +255,9 @@ releaseCompileClasspath - Resolved configuration for compilation for variant: re BUILD SUCCESSFUL ``` -From the output, you can see that the`support-annotations`module, version 26.1.0, is a dependency of the`appcompat-v7`library. +从输出你能看见 `support-annotations` 模块,版本号是26.1.0,是 `appcompat-v7` 库的依赖。 -Another way to see the version required is to use the`dependencyInsight`task. Run the following command \(all on one line\). +另一个查看目标的版本号是运行 `dependencyInsight` 任务。执行如下命令(全部在一行)。 ``` $ ./gradlew :app:dependencyInsight --dependency support-annotations --configuration releaseCompileClasspath @@ -389,53 +294,53 @@ com.android.support:support-annotations:26.1.0 BUILD SUCCESSFUL ``` -Both the`dependency`and`dependencyInsight`tasks are available in any Gradle project. They can help you track down and resolve any issues with library version conflicts. +`dependency` 和 `dependencyInsight` 任务在任何Gradle项目中均可使用。它们能帮助你追踪并解决任何库版本冲突问题。 -## [Use the Gradle window](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#use_the_gradle_window) {#use_the_gradle_window} +## [使用Gradle窗口](#use_the_gradle_window) {#use_the_gradle_window} -Android Studio includes a special window for executing Gradle tasks. Android projects provide over 80 different tasks, and this window tries to organize them into categories. +Android Studio有一个执行Gradle任务的特殊窗口。一个Android项目提供了超过80种不同的任务,这个窗口将它们分成不同的类别。 -Open the Tasks folder under`:app`, and look inside the`android`category. The following figure shows an example. +打开 `:app` 下的任务目录,查看 `android` 类别的内容。如下图所示。 ![](https://guides.gradle.org/building-android-apps/images/Gradle-window-signingReport.png "Gradle window signingReport") -Since the`signingReport`task does not require any arguments, you can simply double-click on it to execute it. The results are shown in the next figure. +由于 `signingReport` 任务不需要任何参数,因此你只需要双击就可以执行它。结果如下图所示。 ![](https://guides.gradle.org/building-android-apps/images/Run-and-Gradle-Console.png "Run and Gradle Console") -The`signingReport`task tells you where the public key is stored \(here the`debug.keystore`file in the user’s root directory\), its alias, and its MD5 and SHA1 hashes. +`signingReport` 任务告诉你公钥存储的目录(示例中 `debug.keystore` 在用户的根目录),它的别称,以及它的MD5值和SHA1值。 -Note that there is no release key at the moment. Look at the tasks listed in the Gradle window in the`install`category, as shown the next figure. +请注意目前没有释放键。查看Gradle窗口中 `install` 类别下列出的任务,如下图所示。 ![](https://guides.gradle.org/building-android-apps/images/Gradle-window-install.png "Gradle window install") -You’ll see that there is an`installDebug`task and an`uninstallDebug`task, an`uninstallRelease`task, and even an`uninstallAllTask`. Conspicuous by its absence, however, is an`installRelease`task. That task is only available if you create a signing configuration for a release key, which Gradle can use to create a signed release APK. +你会发现有一个 `installDebug` 任务和一个 `uninstallDebug` 任务,一个 `uninstallRelease` 任务,甚至还有一个 `uninstallAllTask` 任务。然而,可以发现还有一个缺少的 `installRelease` 任务。该任务( `installRelease` )仅在为release版本密钥创建签名配置后才可用。 -If you were now to start up multiple emulators or attach multiple devices, you could deploy the app into all of them by executing the`installDebug`task. +如果你现在需要启动多个模拟器或者连接多台设备,则可以通过执行 `installDebug` 任务将应用部署到设备中。 ``` $ ./gradlew installDebug ``` -This is different from running the app through the IDE. In that case, you would select a single connected device or emulator, and would both install the app and start it up. The`installDebug`task from Gradle will deploy the app in all connected devices in one step, though it will not start the app in any of them. The result will be similar to the next figure. +这与通过IDE运行应用程序不同。在这种情况下,你可以选择一个连接的设备或者模拟器,安装应用并启动它。Gradle中的 `installDebug` 任务将一步完成所有连接设备的应用部署工作,尽管它不会启动任何应用程序。结果与下图相似。 ![](https://guides.gradle.org/building-android-apps/images/Android-Emulator-Pixel_API_25.png "Android Emulator Pixel API 25") ![](https://guides.gradle.org/building-android-apps/images/Android-Emulator-Nexus_9_API_23.png "Android Emulator Nexus 9 API 23") -You can launch the app by double-clicking on the icon, as usual. You can also remove the app by using the`uninstallAll`task. +像往常一样,你可以通过双击图标启动应用程序。你也可以通过 `uninstallAll` 任务卸载应用程序。 ``` $ ./gradlew uninstallAll ``` -This will remove the app from all connected devices. +它将从所有连接的设备中删除应用程序。 -## [Publish a build scan](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#publish_a_build_scan) {#publish_a_build_scan} +## [发布构建审视](#publish_a_build_scan) {#publish_a_build_scan} -[Build scans](https://gradle.com/build-scans)are a persistent, shareable record of what happened when running a build. With build scans, you gain deep insights about your build. +[构建审视(Build scans)](https://gradle.com/build-scans) 是在构建时持久可共享的记录。通过构建审视,你可以对构建有更加深入的了解。 -If you are using Gradle 4.3+, you can easily create a build scan by using the`--scan`command line option, e.g.`gradle build --scan`. For older Gradle versions, see the[Build Scan Plugin User Manual](https://docs.gradle.com/build-scan-plugin/#getting_set_up)on how to enable build scans. +如果你使用的Gradle版本号高于4.3,你可以通过 `--scan` 命令行选项轻松创建一次构建审视,举个栗子, `gradle build --scan` 。对于老版本的Gradle,查看 [构建审视插件用户手册](https://docs.gradle.com/build-scan-plugin/#getting_set_up) 关于如何启用构件扫描。 ``` ./gradlew build --scan @@ -451,47 +356,47 @@ Publishing build scan... https://gradle.com/s/carzirlfjwjlo ``` -The resulting page will resemble: +输出结果如下所示: ![](https://guides.gradle.org/building-android-apps/images/Build-scan-for-HelloWorldGradle.png "Build scan for HelloWorldGradle") -Feel free to explore all the details. The report contains information on many features, including dependencies. If you dig into the dependencies section and open the`releaseCompileClasspath`configuration of the`:app`subproject, inside the`appcompat-v7`library is the`support-annotations`library described earlier. +随意探索所有细节。该报告包含许多功能信息,包括依赖关系。如果你深入依赖部分并打开 `:app` 子项目的 `releaseCompileClasspath` 配置部分,在 `appcompat-v7` 库里面是前面描述过的 `support-annotations` 库。 ![](https://guides.gradle.org/building-android-apps/images/Build-scan-dep-support-annotations.png "Build scan dep support annotations") -Build scans are a powerful way to analyze your build. For more details, see the[Getting Started guide for Creating Build Scans](https://guides.gradle.org/creating-build-scans/)and the[Build Scan Plugin User Manual](https://docs.gradle.com/build-scan-plugin/). +构建审视是分析构建的强有力方法。想查看更多细节,可以浏览 [构建审视入门指南](https://guides.gradle.org/creating-build-scans/) 和 [构建审视插件用户手册](https://docs.gradle.com/build-scan-plugin/)。 -## [Summary](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#summary) {#summary} +## [总结](#summary) {#summary} -In this guide, you created an Android app and examined many of the Gradle capabilities that came with it. Specifically, you learned how to: +在这篇手册中,你新建了一个Android应用程序并查看了许多Gradle功能。特别是,你学会了怎样来: -* Create an Android app using Android Studio +* 通过Android Studio创建一个Android应用 -* View the generated project as a Gradle multi-project build +* 查看Gradle多项目构建的项目 -* Add the Android plugin to the top-level Gradle build file +* 往顶级Gradle构建文件中添加Android插件 -* See which version of Gradle is used in the generated wrapper +* 在生成的wrapper中查看当前Gradle使用的版本号 -* Interpret the settings added in the`android`section of the app +* 阐释应用里 `android` 部分添加的设置 -* Work with the default dependencies added to the app +* 使用添加到应用程序的默认依赖 -* Build the app and see the output APK +* 编译应用并查看生成的APK -* Determine which version of a dependency is being used +* 确定依赖使用的具体版本号 -* Use the Gradle window to execute tasks +* 通过Gradle窗口运行任务 -* Deploy and uninstall the app on multiple devices +* 多设备上的部署及卸载应用 -* Run a build scan on an Android project +* 在Android项目运行构建审视 -## [Next Steps](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#next_steps) {#next_steps} +## [下一步](#next_steps) {#next_steps} -The book_Gradle Recipes for Android_, by Ken Kousen and published by O’Reilly Media, Inc, is available for purchase at[http://shop.oreilly.com/product/0636920032656.do](http://shop.oreilly.com/product/0636920032656.do), but an electronic version can also be downloaded for free at[https://gradle.org/books/](https://gradle.org/books/). +由Ken Kousen编写并由O’Reilly Media, Inc出版的书籍《Gradle Recipes for Android》(《Android Gradle指南》),已经在 [http://shop.oreilly.com/product/0636920032656.do](http://shop.oreilly.com/product/0636920032656.do) 开放购买了,但是电子版可以在 [https://gradle.org/books/](https://gradle.org/books/) 免费下载。 -## [Help improve this guide](https://guides.gradle.org/building-android-apps/?_ga=2.62770159.216844200.1523258211-2050954084.1517482353#help_improve_this_guide) {#help_improve_this_guide} +## [帮助改进本手册](#help_improve_this_guide) {#help_improve_this_guide} -Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/building-android-apps](https://github.com/gradle-guides/building-android-apps/)and we’ll get back to you. +有任何反馈或者疑问?发现错误?就像所有Gradle手册一样,帮助只需要Github上的一个issue。请提交一个issue或者提交PR到 [gradle-guides/building-android-apps](gradle-guides/building-android-apps) ,我们会尽快回复你。 From 0703c026d9fbbf2ba6994957bc695a839ed01e7d Mon Sep 17 00:00:00 2001 From: Burjal Date: Thu, 12 Apr 2018 00:11:49 +0800 Subject: [PATCH 093/102] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cad19dd..13350d5 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ ##### 项目教程 -* [ ] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) ([@BurjalHou](https://github.com/BurjalHou)) -* [ ] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) +* [x] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) ([@BurjalHou](https://github.com/BurjalHou)) +* [ ] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) ([@BurjalHou](https://github.com/BurjalHou)) * [ ] [Groovy](https://docs.gradle.org/current/userguide/userguide.html#building-groovy-projects) * [ ] [Java](https://docs.gradle.org/current/userguide/userguide.html#building-java-projects) * [ ] [JavaScript](https://docs.gradle.org/current/userguide/userguide.html#building-javascript-projects) From 976d08704198159e3cb146ffa4d152b31b7661cd Mon Sep 17 00:00:00 2001 From: BurjalHou Date: Wed, 11 Apr 2018 16:15:42 +0000 Subject: [PATCH 094/102] Creates xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md Auto commit by GitBook Editor --- SUMMARY.md | 2 + xiang-mu-shi-yong-jiao-cheng/c++.md | 0 .../c++/building-c++-executables.md | 218 ++++++++++++++++++ .../c++/building-c++-libraries.md | 0 4 files changed, 220 insertions(+) create mode 100644 xiang-mu-shi-yong-jiao-cheng/c++.md create mode 100644 xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md create mode 100644 xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md diff --git a/SUMMARY.md b/SUMMARY.md index 98c90da..df6c218 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -44,4 +44,6 @@ * [Android](xiang-mu-shi-yong-jiao-cheng/android.md) * [构建Android应用](xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md) +* [C++](xiang-mu-shi-yong-jiao-cheng/c++.md) + * [Building C++ Executables](xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md) diff --git a/xiang-mu-shi-yong-jiao-cheng/c++.md b/xiang-mu-shi-yong-jiao-cheng/c++.md new file mode 100644 index 0000000..e69de29 diff --git a/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md b/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md new file mode 100644 index 0000000..8820e67 --- /dev/null +++ b/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md @@ -0,0 +1,218 @@ +# Building C++ Executables + +This guide demonstrates how to create a minimalist C++ executable using Gradle’s`cpp`plugin. + +Contents + +* [What you’ll need](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#what_you_ll_need) +* [Layout](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#layout) +* [Add source code](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#add_source_code) +* [Build your project](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#build_your_project) +* [Summary](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#summary) +* [Next Steps](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#next_steps) +* [Help improve this guide](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#help_improve_this_guide) + +## [What you’ll need](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#what_you_ll_need) {#what_you_ll_need} + +* About6 minutes + +* A text editor + +* A command prompt + +* The Java Development Kit \(JDK\), version 1.7 or higher + +* A[Gradle distribution](https://gradle.org/install), version 4.6 or better + +* An installed C++ compiler. See which[C++ tool chains](https://docs.gradle.org/4.6/userguide/native_software.html#native-binaries:tool-chain-support)are supported by Gradle and whether you have to do any[installation configuration](https://docs.gradle.org/4.6/userguide/native_software.html#sec:tool_chain_installation)for your platform. + +## [Layout](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#layout) {#layout} + +The first step is to create a folder for the new project and add a[Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html#sec:wrapper_generation)to the project. + +``` +$ mkdir cpp-executable +$ cd cpp-executable +$ gradle wrapper + + +:wrapper + +BUILD SUCCESSFUL +``` + +| | This allows a version of Gradle to be locked to a project and henceforth you can use`./gradlew`instead of`gradle`. | +| :--- | :--- | + + +Create a minimalist`build.gradle`file with the following content: + +build.gradle + +``` +apply plugin : +' +cpp +' + + +model { + + components { + main(NativeExecutableSpec) + + } +} +``` + +| | C++ projects are enabled via the`cpp`plugin | +| :--- | :--- | +| | All native build definitions are done within a`model`block. | +| | A native executable component is defined by a name -`main`in this case. This will determine the default location of source code, as well as the final name of the executable. | +| | An executable is specified by using[NativeExecutableSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.NativeExecutableSpec.html). | + +If you run + +``` +$ ./gradlew tasks +``` + +you will see in the output that Gradle has added a number of tasks + +``` +installMainExecutable - Installs a development image of executable 'main:executable' +mainExecutable - Assembles executable 'main:executable'. + +Build Dependents tasks +---------------------- +assembleDependentsMain - Assemble dependents of native executable 'main'. +assembleDependentsMainExecutable - Assemble dependents of executable 'main:executable'. +buildDependentsMain - Build dependents of native executable 'main'. +buildDependentsMainExecutable - Build dependents of executable 'main:executable'. +``` + +Note the use of`Main`in the task names which are a direct deriviative of the component being called`main`. + +## [Add source code](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#add_source_code) {#add_source_code} + +By convention, C++ projects in Gradle will follow a more contemporary layout. This can be troublesome for you if you are used to building C++ code with build tools that do not use a convention-over-configuration approach. Rest assured that Gradle is very configurable in this regard and should you need to migrate a C++ project to Gradle you can consult the[C++ sources](https://docs.gradle.org/4.6/userguide/native_software.html#sec:cpp_sources)section of the User Guide. + +In the`build.gradle`you have previsouly defined the executable component to be called`main`. By convention, this will means that Gradle will look in`src/main/cpp`for source files and non-exported header files. Create this folder + +``` +$ mkdir -p src/main/cpp +``` + +and place a`main.cpp`an a`greeting.hpp`within. + +src/main/cpp/main.cpp + +``` +#include +< +iostream +> +#include +"greeting.hpp" +int + main( +int + argc, +char +** argv) { + std::cout +< +< + greeting +< +< + std::endl; + +return +0 +; +} +``` + +| | The standard C++ headers wil be located via the compiler toolchain that Gradle uses | +| :--- | :--- | +| | Non-exported headers will be searched for relative to the specified C++ source folders. \(In this case`src/main/cpp`\). | + +src/main/cpp/greeting.hpp + +``` +#ifndef + GRADLE_GUIDE_EXAMPLE_GREETING_HPP__ + +#define + GRADLE_GUIDE_EXAMPLE_GREETING_HPP__ + + +namespace + { + +const +char + * greeting = +" +Hello, World +" +; +} + + +#endif +``` + +## [Build your project](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#build_your_project) {#build_your_project} + +To build your project you can simply do`./gradlew build`as per usual, but if you specifically want to build the executable, run the task that Gradle has created for you: + +``` +$ ./gradlew mainExecutable + +:compileMainExecutableMainCpp + +:linkMainExecutable + +:mainExecutable + +BUILD SUCCESSFUL +``` + +| | To keep things tidy on the console, Gradle does not display compiler output. If you need to ever diagnose a compilation issue, the output from the compiler is stored in`build/tmp/compileMainExecutableMainCpp/output.txt`. | +| :--- | :--- | +| | In a similar fashion the output from the linker is written to`build/tmp/linkMainExecutable/output.txt` | + +Look inside the`build`folder and you will notice the appearance of a`exe`folder. By convention Gradle will place all executables in subfolders named according to the component name. In this case you will find your assembled executable in`build/exe/main`and it will be called`main`\(or`main.exe`under Windows\). + +Now run your newly built executable. + +``` +$ ./build/exe/main/main + +Hello World +``` + +Congratulations! You have just built a C++ executable with Gradle. + +## [Summary](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#summary) {#summary} + +You have created an C++ project that can be used as a foundation for something more substantial. In the process you saw: + +* How to create a build script for C++ executables. + +* Where to add source code by convention. + +* How to build the executable without building the full project. + +## [Next Steps](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#next_steps) {#next_steps} + +* Testing using[CUnit](http://cunit.sourceforge.net/)or[GoogleTest](https://github.com/google/googletest)is supported. Gradle will respectively create a matching[CUnitTestSuiteSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.test.cunit.CUnitTestSuiteSpec.html)or[GoogleTestTestSuiteSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.test.googletest.GoogleTestTestSuiteSpec.html)component for the executable you have defined in this guide. See the[CUnit support](https://docs.gradle.org/4.6/userguide/native_software.html#native_binaries:cunit)and[GoogleTest support](https://docs.gradle.org/4.6/userguide/native_software.html#native_binaries:google_test)sections in the User Guide for more details. + +* As there is no 'standard' way of creating documentation for C++ projects, the`cpp`plugin does not offer a task to generate documentation. If you do use the popular Doxygen tool for documenting C++ code, you may want to have a look at the[Doxygen plugin](https://plugins.gradle.org/plugin/org.ysb33r.doxygen)for Gradle + +## [Help improve this guide](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#help_improve_this_guide) {#help_improve_this_guide} + +Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/building-cpp-executables](https://github.com/gradle-guides/building-cpp-executables/)and we’ll get back to you. + diff --git a/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md b/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md new file mode 100644 index 0000000..e69de29 From 0929fad3e24051e11673065692d25bf22f6b652e Mon Sep 17 00:00:00 2001 From: DONG Date: Thu, 12 Apr 2018 22:33:29 +0800 Subject: [PATCH 095/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=9E=84=E5=BB=BA=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuring-build-environment.md | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md index 2ee5b71..79085dc 100644 --- a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md +++ b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md @@ -62,29 +62,28 @@ Gradle 守护进程会在空闲指定的毫秒后结束自己. 默认是`1080000 `org.gradle.jvmargs=(JVM arguments)` -Specifies the JVM arguments used for the Gradle Daemon. The setting is particularly useful for[configuring JVM memory settings](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:configuring_jvm_memory)for build performance. +指定 Gradle 守护进程使用的 JVM 参数. 这个设置对于[配置 JVM memory 设置](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:configuring_jvm_memory)在构建性能方面是十分有用的. `org.gradle.logging.level=(quiet,warn,lifecycle,info,debug)` -When set to quiet, warn, lifecycle, info, or debug, Gradle will use this log level. The values are not case sensitive. The`lifecycle`level is the default. See[the section called “Choosing a log level”](https://docs.gradle.org/4.6/userguide/logging.html#sec:choosing_a_log_level). +设置 Gradle 日志级别. 参数大小写都可以. 默认是`lifecycle`级别. 查阅[选择一个日志级别](https://docs.gradle.org/4.6/userguide/logging.html#sec:choosing_a_log_level)了解更多. `org.gradle.parallel=(true,false)` -When configured, Gradle will fork up to`org.gradle.workers.max`JVMs to execute projects in parallel. To learn more about parallel task execution, see[the Gradle performance guide](https://guides.gradle.org/performance/#parallel_execution). +设置是否并行执行多个项目. 查看[Gradle 性能指南](https://guides.gradle.org/performance/#parallel_execution)了解更多关于并行任务执行的知识. `org.gradle.warning.mode=(all,none,summary)` -When set to`all`,`summary`or`none`, Gradle will use different warning type display. See[the section called “Logging options”](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_logging)for details. +设置 Gradle 不同的警告类型. 查看[日志选项了解更多](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_logging). `org.gradle.workers.max=(max # of worker processes)` -When configured, Gradle will use a maximum of the given number of workers. Default is number of CPU processors. See also[performance command-line options](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_performance). +设置 Gradle 可以使用的最大 workers 数量. 默认是 CPU 处理器的数量.查看[性能命令行选项](https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_performance)了解更多. -The following example demonstrates usage of various properties. +下面列举几个使用这些属性的例子 - -**Example: Setting properties with a gradle.properties file** +**Example: gradle.properties 文件中设置属性** `gradle.properties` @@ -113,11 +112,10 @@ task printProps { ``` -Output of**`gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps`** +**`gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps`**的输出: ``` -> - gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps +> gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps commandLineProjectPropValue gradlePropertiesValue systemPropertyValue @@ -126,12 +124,11 @@ systemValue ``` -## System properties - -Using the`-D`command-line option, you can pass a system property to the JVM which runs Gradle. The`-D`option of the`gradle`command has the same effect as the`-D`option of the`java`command. +## 系统属性 -You can also set system properties in`gradle.properties`files with the prefix`systemProp.` +通过使用`-D`命令行选项, 你可以传递一个系统属性给运行 Gradle 的 JVM. 这个 Gradle 的`-D`选项的效果其实和`java`命令的`-D`是一样的. +你可以在`gradle.properties`文件中通过前缀`systemProp.`来使用系统属性 **Example: Specifying system properties in`gradle.properties`** From 32e1b27399c6413a73911e38a6a4045f7bf4afef Mon Sep 17 00:00:00 2001 From: DONG Date: Mon, 16 Apr 2018 22:10:24 +0800 Subject: [PATCH 096/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=92=8C=E7=B3=BB=E7=BB=9F=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuring-build-environment.md | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md index 79085dc..ab4a907 100644 --- a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md +++ b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md @@ -104,9 +104,7 @@ task printProps { println gradlePropertiesProp println systemProjectProp println envProjectProp - println System.properties[ -'system' -] + println System.properties['system'] } } @@ -131,78 +129,75 @@ systemValue 你可以在`gradle.properties`文件中通过前缀`systemProp.`来使用系统属性 -**Example: Specifying system properties in`gradle.properties`** +**Example: 在`gradle.properties`文件中设置系统属性** ``` systemProp.gradle.wrapperUser=myuser systemProp.gradle.wrapperPassword=mypassword ``` -The following system properties are available. Note that command-line options take precedence over system properties. +有下列可用的系统属性. 请注意, 命令行选项的优先级是在系统属性之上的. `gradle.wrapperUser=(myuser)` -Specify user name to download Gradle distributions from servers using HTTP Basic Authentication. Learn more in[the section called “Authenticated Gradle distribution download”](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html#sec:authenticated_download). +指定使用 HTTP Basic Authentication 从服务器上下载 Gradle 发布所使用的用户名. 查阅[Authenticated Gradle distribution download](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html#sec:authenticated_download)了解更多. `gradle.wrapperPassword=(mypassword)` -Specify password for downloading a Gradle distribution using the Gradle wrapper. +指定使用 Gradle wrapper 下载 Gradle 发布的密码. `gradle.user.home=(path to directory)` -Specify the Gradle user home directory. +指定 Gradle 用户 home 文件夹. -In a multi project build, “`systemProp.`” properties set in any project except the root will be ignored. That is, only the root project’s`gradle.properties`file will be checked for properties that begin with the “`systemProp.`” prefix. +在一个多项目构建当中, “`systemProp.`” 属性只有在根项目中才会起作用. 也就是说只有在`gradle.properties`文件的根项目中才会检查有 “`systemProp.`” 前缀的属性. -## Environment variables +## 环境变量 -The following environment variables are available for the`gradle`command. Note that command-line options and system properties take precedence over environment variables. +下面的环境变量可以在 Gradle 命令中使用. 请注意, 命令行选项以及系统选项的优先级在环境变量之上. `GRADLE_OPTS` -Specifies[command-line arguments](https://docs.gradle.org/4.6/userguide/command_line_interface.html)to use when starting the Gradle client. This can be useful for setting the properties to use when running Gradle. +指定要使用的[命令行参数](https://docs.gradle.org/4.6/userguide/command_line_interface.html). `GRADLE_USER_HOME` -Specifies the Gradle user home directory \(which defaults to`$USER_HOME/.gradle`if not set\). +指定 Gradle 用户 home 文件夹 \(如果没有设置的话, 默认`$USER_HOME/.gradle`\). `JAVA_HOME` -Specifies the JDK installation directory to use. +指定 JDK 安装目录. -## Project properties +## 项目属性 -You can add properties directly to your[`Project`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html)object via the`-P`command line option. +你可以通过`-P`命令行选项直接在你的[`项目`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html)中添加属性. -Gradle can also set project properties when it sees specially-named system properties or environment variables. If the environment variable name looks like`ORG_GRADLE_PROJECT`_`_prop`_`=somevalue`, then Gradle will set a`prop`property on your project object, with the value of`somevalue`. Gradle also supports this for system properties, but with a different naming pattern, which looks like`org.gradle.project.`_`prop`_. Both of the following will set the`foo`property on your Project object to`"bar"`. +当 Gradle 发现特殊命名的系统属性或者环境变量, 就会将它们设置为项目属性. 比如环境变量的名称为`ORG_GRADLE_PROJECT`_`_prop`_`=somevalue`, Gradle 就会设置一个`prop`属性到你的项目上, 并赋值为`somevalue`. 对于系统属性, Gradle 也会做类似的处理, 但是使用不同的名称模式, 有点像`org.gradle.project.`_`prop`_. 下面的 2 个列子都会设置一个 `foo` 属性到你的项目的 `"bar"` 对象上. - -**Example: Setting a project property via gradle.properties** +**Example: 通过 gradle.properties 设置项目属性*** ``` org.gradle.project.foo=bar ``` - - -**Example: Setting a project property via environment variable** +**Example: 通过环境变量设置项目属性*** ``` ORG_GRADLE_PROJECT_foo=bar ``` -The properties file in the user’s home directory has precedence over property files in the project directories. +用户 home 文件夹下的属性文件优先级要比项目文件夹下的属性文件优先级高. -This feature is very useful when you don’t have admin rights to a continuous integration server and you need to set property values that should not be easily visible. Since you cannot use the`-P`option in that scenario, nor change the system-level configuration files, the correct strategy is to change the configuration of your continuous integration build job, adding an environment variable setting that matches an expected pattern. This won’t be visible to normal users on the system. +这个特点在某些场合下十分有用, 比如你没有 ADMIN 权限, 没法操作一个持续集成的服务器, 而你需要设置一个不可见或者说不是那么容易可见的属性值. 这种情况下, 你既不能使用 `-P` 选项, 也不能改变系统级别的配置文件, 正确的方式是改变你的持续集成构建工作的配置, 添加一个环境变量. 对于系统上的普通用户是不可见的. -You can access a project property in your build script simply by using its name as you would use a variable. +你可以轻易的使用你的构建脚本里的一个项目属性, 只需要使用它的名称作为变量即可. -If a project property is referenced but does not exist, an exception will be thrown and the build will fail. +如果一个项目属性被引用了却不存在, 构建就会失败并抛出一个异常. -You should check for existence of optional project properties before you access them using the[`Project.hasProperty(java.lang.String)`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html#org.gradle.api.Project:hasProperty%28java.lang.String%29)method. +你应该在使用可选的项目属性之前使用[`Project.hasProperty(java.lang.String)`](https://docs.gradle.org/4.6/dsl/org.gradle.api.Project.html#org.gradle.api.Project:hasProperty%28java.lang.String%29)方法检查它们是否存在. -## Configuring JVM memory +## 配置 JVM 内存 Gradle defaults to 1024 megabytes maximum heap per JVM process \(`-Xmx1024m`\), however, that may be too much or too little depending on the size of your project. There are many JVM options \(this[blog post on Java performance tuning](https://dzone.com/articles/java-performance-tuning)and[this reference](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)may be helpful\). From c41feb9d3b66c3752a87e1620dfc98a01649a5ee Mon Sep 17 00:00:00 2001 From: DONG Date: Tue, 17 Apr 2018 21:36:59 +0800 Subject: [PATCH 097/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=9E=84=E5=BB=BA=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuring-build-environment.md | 64 +++++++------------ 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md index ab4a907..2526e54 100644 --- a/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md +++ b/shi-yong-gradle-gou-jian/customizing-execution/configuring-build-environment.md @@ -199,12 +199,11 @@ ORG_GRADLE_PROJECT_foo=bar ## 配置 JVM 内存 -Gradle defaults to 1024 megabytes maximum heap per JVM process \(`-Xmx1024m`\), however, that may be too much or too little depending on the size of your project. There are many JVM options \(this[blog post on Java performance tuning](https://dzone.com/articles/java-performance-tuning)and[this reference](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)may be helpful\). +Gradle 默认提供最大 1024 MB 的内存给 JVM 进程 \(`-Xmx1024m`\), 然而, 1024MB 对于你的项目来说可能太大了或者完全不够. JVM 提供了许多选项, 阅读 \([blog post on Java performance tuning](https://dzone.com/articles/java-performance-tuning)和[this reference](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)\)了解更多. -You can adjust JVM options for Gradle in the following ways: - -The`JAVA_OPTS`environment variable is used for the Gradle client, but not forked JVMs. +你可以通过下列方法调整 JVM 选项: +环境变量 `JAVA_OPTS` is used for the Gradle client, but not forked JVMs. **Example: Changing JVM settings for Gradle client JVM** @@ -213,8 +212,7 @@ The`JAVA_OPTS`environment variable is used for the Gradle client, but not forked JAVA_OPTS="-Xmx2g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" ``` -You need to use the`org.gradle.jvmargs`Gradle property to configure JVM settings for the[Gradle Daemon](https://docs.gradle.org/4.6/userguide/gradle_daemon.html). - +你需要使用 `org.gradle.jvmargs` 来配置 JVM [保护进程](https://docs.gradle.org/4.6/userguide/gradle_daemon.html)的设置. **Example: Changing JVM settings for forked Gradle JVMs** @@ -223,14 +221,13 @@ You need to use the`org.gradle.jvmargs`Gradle property to configure JVM settings org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 ``` -Many settings \(like the Java version and maximum heap size\) can only be specified when launching a new JVM for the build process. This means that Gradle must launch a separate JVM process to execute the build after parsing the various`gradle.properties`files. +许多设置 \(比如 Java 版本和最大的堆栈大小\) 只能在启动一个新的 JVM 来构建的时候才能指定. 这意味着 Gradle 必须启动一个独立的 JVM 进程来分析新改变的`gradle.properties`文件去构建. -When running with the[Gradle Daemon](https://docs.gradle.org/4.6/userguide/gradle_daemon.html), a JVM with the correct parameters is started once and reused for each daemon build execution. When Gradle is executed without the daemon, then a new JVM must be launched for every build execution, unless the JVM launched by the Gradle start script happens to have the same parameters. +当运行[保护进程](https://docs.gradle.org/4.6/userguide/gradle_daemon.html)的时候, 只要参数正确, JVM 启动一次后就可以给每一个保护进程的构建重复使用. 如果 Gradle 没有使用保护进程执行, 那么一个新的 JVM 就必须被启用来执行每一个构建, 除非被 Gradle 开始脚本启动的 JVM 有完全一样的参数. Certain tasks in Gradle also fork additional JVM processes, like the`test`task when using[`Test.setMaxParallelForks(int)`](https://docs.gradle.org/4.6/javadoc/org/gradle/api/tasks/testing/Test.html#setMaxParallelForks-int-)for JUnit or TestNG tests. You must configure these through the tasks themselves. - **Example: Set Java compile options for**[**`JavaCompile`**](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.compile.JavaCompile.html)**tasks** ``` @@ -247,60 +244,44 @@ See other examples in the[`Test`](https://docs.gradle.org/4.6/dsl/org.gradle.api [![](https://docs.gradle.org/4.6/userguide/img/build-scan-infrastructure.png "Build Environment in build scan")](https://scans.gradle.com/s/sample/cpp-parallel/infrastructure) -## Configuring a task using project properties +## 使用项目属性配置任务 -It’s possible to change the behavior of a task based on project properties specified at invocation time. +可以在调用时通过项目属性来改变任务的行为. -Suppose you’d like to ensure release builds are only triggered by CI. A simple way to handle this is through an`isCI`project property. +假设你想要确保发布构建只会被 CI 触发. 最简单的方法就是使用项目属性 `isCI`. - -**Example: Prevent releasing outside of CI** +**Example: 防止 CI 之外的发布** `build.gradle` ``` task performRelease { doLast { - -if - (project.hasProperty( -"isCI" -)) { - println( -"Performing release actions" -) - } -else - { - -throw -new - InvalidUserDataException( -"Cannot perform release outside of CI" -) + if (project.hasProperty("isCI")) { + println("Performing release actions") + } else { + throw new InvalidUserDataException("Cannot perform release outside of CI") } } } ``` -Output of**`gradle performRelease -PisCI=true --quiet`** +**`gradle performRelease -PisCI=true --quiet`**的输出: ``` -> - gradle performRelease -PisCI=true --quiet +> gradle performRelease -PisCI=true --quiet Performing release actions ``` -## Accessing the web through a HTTP proxy - -Configuring an HTTP or HTTPS proxy \(for downloading dependencies, for example\) is done via standard JVM system properties. These properties can be set directly in the build script; for example, setting the HTTP proxy host would be done with`System.setProperty('http.proxyHost', 'www.somehost.org')`. Alternatively, the properties can be[specified in gradle.properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_configuration_properties). +## 通过 HTTP 代理进入网页 +配置一个 HTTP 或 HTTPS 代理 \(比如为了下载依赖\), 可以通过标准的 JVM 系统属性来实现. 这些属性都可以直接在构建脚本里设置, 通过 `System.setProperty('http.proxyHost', 'www.somehost.org')` 来设置 HTTP 代理. 另外一种选择, 请阅读[specified in gradle.properties](https://docs.gradle.org/4.6/userguide/build_environment.html#sec:gradle_configuration_properties). -**Example: Configuring an HTTP proxy using`gradle.properties`** +**Example: 使用`gradle.properties`配置 HTTP 代理** ``` systemProp.http.proxyHost=www.somehost.org @@ -310,11 +291,10 @@ systemProp.http.proxyPassword=password systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost ``` -There are separate settings for HTTPS. - +对于 HTTPS: -**Example: Configuring an HTTPS proxy using`gradle.properties`** +**Example: 使用`gradle.properties`配置 HTTPS 代理** ``` systemProp.https.proxyHost=www.somehost.org @@ -324,7 +304,7 @@ systemProp.https.proxyPassword=password systemProp.https.nonProxyHosts=*.nonproxyrepos.com|localhost ``` -You may need to set other properties to access other networks. Here are 2 references that may be helpful: +你也许需要设置其他的属性来进入其他特别的网络, 下面 2 篇文章将非常有帮助: * [ProxySetup.java in the Ant codebase](https://git-wip-us.apache.org/repos/asf?p=ant.git;a=blob;f=src/main/org/apache/tools/ant/util/ProxySetup.java;hb=HEAD) From 02b44589851f50ce8df769528b89b7a58432019e Mon Sep 17 00:00:00 2001 From: Burjal Date: Wed, 18 Apr 2018 23:25:09 +0800 Subject: [PATCH 098/102] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E3=80=8A=E6=9E=84?= =?UTF-8?q?=E5=BB=BAC++=E5=8F=AF=E6=89=A7=E8=A1=8C=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../c++/building-c++-executables.md | 175 ++++++------------ .../c++/building-c++-libraries.md | 0 2 files changed, 55 insertions(+), 120 deletions(-) delete mode 100644 xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md diff --git a/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md b/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md index 8820e67..24cb4be 100644 --- a/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md +++ b/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md @@ -1,34 +1,24 @@ -# Building C++ Executables +# 构建C++可执行文件 -This guide demonstrates how to create a minimalist C++ executable using Gradle’s`cpp`plugin. +本指南演示了如何使用Gradle的 `cpp` 插件创建一个简洁的C++可执行文件。 -Contents +## [你需要什么](#what_you_ll_need) {#what_you_ll_need} -* [What you’ll need](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#what_you_ll_need) -* [Layout](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#layout) -* [Add source code](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#add_source_code) -* [Build your project](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#build_your_project) -* [Summary](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#summary) -* [Next Steps](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#next_steps) -* [Help improve this guide](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#help_improve_this_guide) +* 大约6分钟的空闲时间 -## [What you’ll need](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#what_you_ll_need) {#what_you_ll_need} +* 一个文本编辑器 -* About6 minutes +* 一个命令提示窗口 -* A text editor +* 不低于1.7版本的JDK -* A command prompt +* 一个不低于4.6版本的 [Gradle发行版本](https://gradle.org/install) -* The Java Development Kit \(JDK\), version 1.7 or higher +* 一个已经安装的C++编译器。查看Gradle支持哪些 [C++工具链](https://docs.gradle.org/4.6/userguide/native_software.html#native-binaries:tool-chain-support) ,以及针对当前平台所需要下载的 [安装配置](https://docs.gradle.org/4.6/userguide/native_software.html#sec:tool_chain_installation) 。 -* A[Gradle distribution](https://gradle.org/install), version 4.6 or better +## [布局](#layout) {#layout} -* An installed C++ compiler. See which[C++ tool chains](https://docs.gradle.org/4.6/userguide/native_software.html#native-binaries:tool-chain-support)are supported by Gradle and whether you have to do any[installation configuration](https://docs.gradle.org/4.6/userguide/native_software.html#sec:tool_chain_installation)for your platform. - -## [Layout](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#layout) {#layout} - -The first step is to create a folder for the new project and add a[Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html#sec:wrapper_generation)to the project. +第一步,为新项目新建一个文件夹并添加 `[Gradle Wrapper](https://docs.gradle.org/4.6/userguide/gradle_wrapper.html#sec:wrapper_generation)` 。 ``` $ mkdir cpp-executable @@ -41,43 +31,29 @@ $ gradle wrapper BUILD SUCCESSFUL ``` -| | This allows a version of Gradle to be locked to a project and henceforth you can use`./gradlew`instead of`gradle`. | -| :--- | :--- | - +上述 `gradle wrapper` 命令行:将一个Gradle版本与一个项目进行绑定,以后就可以用 `./gradlew` 替代 `gradle` 命令行了。 -Create a minimalist`build.gradle`file with the following content: +新建一个最简单的 `buidl.gradle` 文件,该文件有如下内容: -build.gradle +`build.gradle` ``` -apply plugin : -' -cpp -' - - -model { +apply plugin : 'cpp' // C++项目通过 cpp 插件启用 +model { // 所有原生构建定义都在 model 代码块内完成 components { - main(NativeExecutableSpec) - + main(NativeExecutableSpec) // 通过名称定义本地可执行文件,当前示例是 main 。决定着代码的默认路径,以及最终可执行文件名。 通过 [NativeExecutableSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.NativeExecutableSpec.html) 指定一个可执行文件。 } } ``` -| | C++ projects are enabled via the`cpp`plugin | -| :--- | :--- | -| | All native build definitions are done within a`model`block. | -| | A native executable component is defined by a name -`main`in this case. This will determine the default location of source code, as well as the final name of the executable. | -| | An executable is specified by using[NativeExecutableSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.NativeExecutableSpec.html). | - -If you run +如果运行如下命令: ``` $ ./gradlew tasks ``` -you will see in the output that Gradle has added a number of tasks +你将会在输出中看到Gradle已经添加了许多任务: ``` installMainExecutable - Installs a development image of executable 'main:executable' @@ -91,102 +67,61 @@ buildDependentsMain - Build dependents of native executable 'main'. buildDependentsMainExecutable - Build dependents of executable 'main:executable'. ``` -Note the use of`Main`in the task names which are a direct deriviative of the component being called`main`. +注意在任务名称中使用 `Main` ,它是被 `main` 的组件直接派生的。 -## [Add source code](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#add_source_code) {#add_source_code} +## [添加代码](#add_source_code) {#add_source_code} -By convention, C++ projects in Gradle will follow a more contemporary layout. This can be troublesome for you if you are used to building C++ code with build tools that do not use a convention-over-configuration approach. Rest assured that Gradle is very configurable in this regard and should you need to migrate a C++ project to Gradle you can consult the[C++ sources](https://docs.gradle.org/4.6/userguide/native_software.html#sec:cpp_sources)section of the User Guide. +通常,Gradle编译的C++项目将遵循更现代的布局。如果你习惯于通过不适用常规配制方法配置的构建工具来构建C++代码,那么这会对你造成麻烦。可以放心的是,Gradle在这方面是灵活配置的,如果你需要将C++项目迁移到Gradle,你可以参考用户指南的 [C++源码](https://docs.gradle.org/4.6/userguide/native_software.html#sec:cpp_sources) 部分。 -In the`build.gradle`you have previsouly defined the executable component to be called`main`. By convention, this will means that Gradle will look in`src/main/cpp`for source files and non-exported header files. Create this folder +在 `build.gradle` 中,你已经提前定义了可执行组件 `main` 。按照惯例,这意味着Gradle将在 `src/main/cpp` 目录中查找源文件和非导出的头文件。新建目录: ``` $ mkdir -p src/main/cpp ``` -and place a`main.cpp`an a`greeting.hpp`within. - -src/main/cpp/main.cpp - -``` -#include -< -iostream -> -#include -"greeting.hpp" -int - main( -int - argc, -char -** argv) { - std::cout -< -< - greeting -< -< - std::endl; - -return -0 -; -} -``` +并在 `main.cpp` 放置在 `greeting.hpp` 中。 -| | The standard C++ headers wil be located via the compiler toolchain that Gradle uses | -| :--- | :--- | -| | Non-exported headers will be searched for relative to the specified C++ source folders. \(In this case`src/main/cpp`\). | - -src/main/cpp/greeting.hpp +`src/main/cpp/main.cpp` ``` -#ifndef - GRADLE_GUIDE_EXAMPLE_GREETING_HPP__ +#include // 标准的C++头文件可以通过Gradle使用的编译器工具链定位 +#include "greeting.hpp" // 非导出头文件可以通过相对指定的C++源文件夹搜索 (示例中是 src/main/cpp) +int main(int argc, char ** argv) { + std::cout greeting std::endl; + return 0; +} +``` -#define - GRADLE_GUIDE_EXAMPLE_GREETING_HPP__ +`src/main/cpp/greeting.hpp` +``` +#ifndef GRADLE_GUIDE_EXAMPLE_GREETING_HPP__ +#define GRADLE_GUIDE_EXAMPLE_GREETING_HPP__ -namespace - { - -const -char - * greeting = -" -Hello, World -" -; +namespace { + const char * greeting = "Hello, World"; } - #endif ``` -## [Build your project](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#build_your_project) {#build_your_project} +## [构建项目](#build_your_project) {#build_your_project} -To build your project you can simply do`./gradlew build`as per usual, but if you specifically want to build the executable, run the task that Gradle has created for you: +为了构建项目,你可以简单的照常通过执行 `./gradlew build` ,但是如果你指明想要编译可执行文件,执行Gradle为你创建的任务: ``` $ ./gradlew mainExecutable -:compileMainExecutableMainCpp - -:linkMainExecutable - +:compileMainExecutableMainCpp // 为了保持命令行的整洁,Gradle不在编译器输出上显示。如果你需要定位编译问题,编译器输出内容存储在 build/tmp/compileMainExecutableMainCpp/output.txt +:linkMainExecutable // 以类似的方式写入链接器的输出内容到 build/tmp/linkMainExecutable/output.txt :mainExecutable BUILD SUCCESSFUL ``` -| | To keep things tidy on the console, Gradle does not display compiler output. If you need to ever diagnose a compilation issue, the output from the compiler is stored in`build/tmp/compileMainExecutableMainCpp/output.txt`. | -| :--- | :--- | -| | In a similar fashion the output from the linker is written to`build/tmp/linkMainExecutable/output.txt` | - -Look inside the`build`folder and you will notice the appearance of a`exe`folder. By convention Gradle will place all executables in subfolders named according to the component name. In this case you will find your assembled executable in`build/exe/main`and it will be called`main`\(or`main.exe`under Windows\). +查看 `build` 文件夹可以看到一个 `exe` 文件夹。通常,Gradle会将所有可执行文件放置在根据组件命名的子文件夹中。在上述示例中,你会发现你的汇编可执行文件位于 `build/exe/main` 文件夹中,它会被 `main` 调用(或者在Windows下 `main.exe`)。 -Now run your newly built executable. +现在运行你新构建好的可执行文件。 ``` $ ./build/exe/main/main @@ -194,25 +129,25 @@ $ ./build/exe/main/main Hello World ``` -Congratulations! You have just built a C++ executable with Gradle. +恭喜!你已经通过Gradle编译了一个C++可执行文件。 -## [Summary](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#summary) {#summary} +## [总结](#summary) {#summary} -You have created an C++ project that can be used as a foundation for something more substantial. In the process you saw: +你已经创建了一个C++项目,并可以将其作为更丰富项目的基础。在这个过程中你学会了: -* How to create a build script for C++ executables. +* 如何为C++可执行文件创建编译脚本 -* Where to add source code by convention. +* 添加源码的位置 -* How to build the executable without building the full project. +* 如何编译可执行文件,而不是编译整个项目 -## [Next Steps](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#next_steps) {#next_steps} +## [下一步](#next_steps) {#next_steps} -* Testing using[CUnit](http://cunit.sourceforge.net/)or[GoogleTest](https://github.com/google/googletest)is supported. Gradle will respectively create a matching[CUnitTestSuiteSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.test.cunit.CUnitTestSuiteSpec.html)or[GoogleTestTestSuiteSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.test.googletest.GoogleTestTestSuiteSpec.html)component for the executable you have defined in this guide. See the[CUnit support](https://docs.gradle.org/4.6/userguide/native_software.html#native_binaries:cunit)and[GoogleTest support](https://docs.gradle.org/4.6/userguide/native_software.html#native_binaries:google_test)sections in the User Guide for more details. +* 支持通过[CUnit](http://cunit.sourceforge.net/) 或者 [GoogleTest](https://github.com/google/googletest) 进行测试。Gradle将会分别为本手册中定义的可执行文件创建一个匹配 [CUnitTestSuiteSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.test.cunit.CUnitTestSuiteSpec.html) 或 [GoogleTestTestSuiteSpec](https://docs.gradle.org/4.6/dsl/org.gradle.nativeplatform.test.googletest.GoogleTestTestSuiteSpec.html) 的组件。在用户手册中查看 [CUnit support](https://docs.gradle.org/4.6/userguide/native_software.html#native_binaries:cunit) 和 [GoogleTest support](https://docs.gradle.org/4.6/userguide/native_software.html#native_binaries:google_test) 部分查看更多细节。 -* As there is no 'standard' way of creating documentation for C++ projects, the`cpp`plugin does not offer a task to generate documentation. If you do use the popular Doxygen tool for documenting C++ code, you may want to have a look at the[Doxygen plugin](https://plugins.gradle.org/plugin/org.ysb33r.doxygen)for Gradle +* 由于没有所谓的为C++项目创建文档的“标准”方法, `cpp` 插件不提供生成文档。如果你使用流行的Doxygen工具来为C++代码添加文档,你可能需要看看 [Doxygen plugin for Gradle](https://plugins.gradle.org/plugin/org.ysb33r.doxygen)。 -## [Help improve this guide](https://guides.gradle.org/building-cpp-executables/?_ga=2.250331334.1925742538.1523455841-1807434561.1523282416#help_improve_this_guide) {#help_improve_this_guide} +## [帮助改进本手册](#help_improve_this_guide) {#help_improve_this_guide} -Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/building-cpp-executables](https://github.com/gradle-guides/building-cpp-executables/)and we’ll get back to you. +有任何反馈或者疑问?或者发现任何错误?就像所有Gradle手册一样,帮助我们只需要Github上的一个issue。请提交一个issue或者提交PR到 [https://github.com/gradle-guides/building-cpp-executables/](https://github.com/gradle-guides/building-cpp-executables/) ,我们会尽快回复你。 diff --git a/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md b/xiang-mu-shi-yong-jiao-cheng/c++/building-c++-libraries.md deleted file mode 100644 index e69de29..0000000 From fdfad36c7b882c9ec082c5db1df11e7e52d4c3ab Mon Sep 17 00:00:00 2001 From: Burjal Date: Wed, 18 Apr 2018 23:27:34 +0800 Subject: [PATCH 099/102] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13350d5..95d37aa 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ ##### 项目教程 * [x] [Android](https://docs.gradle.org/current/userguide/userguide.html#building-android-projects) ([@BurjalHou](https://github.com/BurjalHou)) -* [ ] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) ([@BurjalHou](https://github.com/BurjalHou)) -* [ ] [Groovy](https://docs.gradle.org/current/userguide/userguide.html#building-groovy-projects) +* [x] [C++](https://docs.gradle.org/current/userguide/userguide.html#building-cpp-projects) ([@BurjalHou](https://github.com/BurjalHou)) +* [ ] [Groovy](https://docs.gradle.org/current/userguide/userguide.html#building-groovy-projects) ([@BurjalHou](https://github.com/BurjalHou)) * [ ] [Java](https://docs.gradle.org/current/userguide/userguide.html#building-java-projects) * [ ] [JavaScript](https://docs.gradle.org/current/userguide/userguide.html#building-javascript-projects) * [ ] [Kotlin](https://docs.gradle.org/current/userguide/userguide.html#building-kotlin-projects) From c615dab2bba443d37823a4d3138609e60d1bb0ff Mon Sep 17 00:00:00 2001 From: BurjalHou Date: Wed, 18 Apr 2018 15:31:36 +0000 Subject: [PATCH 100/102] Updates xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md Auto commit by GitBook Editor --- SUMMARY.md | 4 +- xiang-mu-shi-yong-jiao-cheng/groovy.md | 0 .../groovy/building-groovy-libraries.md | 288 ++++++++++++++++++ 3 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 xiang-mu-shi-yong-jiao-cheng/groovy.md create mode 100644 xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md diff --git a/SUMMARY.md b/SUMMARY.md index df6c218..bd1a98e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -45,5 +45,7 @@ * [Android](xiang-mu-shi-yong-jiao-cheng/android.md) * [构建Android应用](xiang-mu-shi-yong-jiao-cheng/android/gou-jian-android-ying-yong.md) * [C++](xiang-mu-shi-yong-jiao-cheng/c++.md) - * [Building C++ Executables](xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md) + * [构建C++可执行文件](xiang-mu-shi-yong-jiao-cheng/c++/building-c++-executables.md) +* [Groovy](xiang-mu-shi-yong-jiao-cheng/groovy.md) + * [构建Groovy库](xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md) diff --git a/xiang-mu-shi-yong-jiao-cheng/groovy.md b/xiang-mu-shi-yong-jiao-cheng/groovy.md new file mode 100644 index 0000000..e69de29 diff --git a/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md b/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md new file mode 100644 index 0000000..0f0998f --- /dev/null +++ b/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md @@ -0,0 +1,288 @@ +This guide demonstrates how to create a[Groovy](http://groovy-lang.org/)library in the standard form using Gradle’s Build Init plugin. + +## [What you’ll need](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#what_you_ll_need) {#what_you_ll_need} + +* About8 minutes + +* A text editor + +* A command prompt + +* The Java Development Kit \(JDK\), version 1.7 or higher + +* A[Gradle distribution](https://gradle.org/install), version 4.6 or better + +## [Check the user manual](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#check_the_user_manual) {#check_the_user_manual} + +Gradle comes with a built-in plugin called the Build Init plugin. It is documented in the[Gradle User Manual](https://docs.gradle.org/current/userguide/build_init_plugin.html). The plugin has one task, called`init`, that generates the project. The`init`task calls the \(also built-in\)`wrapper`task to create a Gradle wrapper script,`gradlew`. + +The first step is to create a folder for the new project and change directory into it. + +``` +$ mkdir building-groovy-libraries +$ cd building-groovy-libraries +``` + +## [Run the init task](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#run_the_init_task) {#run_the_init_task} + +From inside the new project directory, run the`init`task with the`groovy-library`argument. + +``` +$ gradle init --type groovy-library +:wrapper +:init + +BUILD SUCCESSFUL in 4s +2 actionable tasks: 2 executed +``` + +The`init`task runs the`wrapper`task first, which generates the`gradlew`and`gradlew.bat`wrapper scripts. Then it creates the new project with the following structure: + +``` +├── build.gradle +├── gradle +│   └── wrapper + +│   ├── gradle-wrapper.jar +│   └── gradle-wrapper.properties +├── gradlew +├── gradlew.bat +├── settings.gradle +└── src + ├── main + │   └── groovy + + │   └── Library.groovy + └── test + └── groovy + + └── LibraryTest.groovy +``` + +| | Generated folder for wrapper files | +| :--- | :--- | +| | Default Groovy source folder | +| | Default Groovy test folder | + +## [Review the generated project files](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#review_the_generated_project_files) {#review_the_generated_project_files} + +The`settings.gradle`file is heavily commented, but has only one active line: + +Generated settings.gradle + +``` +rootProject.name = +' +gradleRunner +' +``` + +| | This assigns the name of the root project. | +| :--- | :--- | + + +The generated`build.gradle`file also has many comments. The active portion is reproduced here \(note version numbers for the dependencies may be updated in later versions of Gradle\): + +Generated build.gradle + +``` +plugins { + id +' +groovy +' + +} + +dependencies { + compile +' +org.codehaus.groovy:groovy-all:2.4.13 +' + + + testCompile +' +org.spockframework:spock-core:1.0-groovy-2.4 +' + +} + +repositories { + jcenter() + +} +``` + +| | Public Bintray Artifactory repository | +| :--- | :--- | +| | Groovy version that this project will include as dependency | +| | Spock Framework testing library | +| | JUnit testing library | + +The build file adds the`groovy`plugin. This is an extension of the`java`plugins and adds additional tasks for compiling Groovy source code. It also allows for joint compilation of Groovy and Java files if found in the appropriate`groovy`source folders. + +The file`src/main/groovy/Library.groovy`is shown here: + +Generated src/main/groovy/Library.groovy + +``` +class +Library + { + +boolean + someLibraryMethod() { + +true + + } +} +``` + +The generated Spock specification,`src/test/groovy/LibraryTest.groovy`is shown next: + +Generated src/test/groovy/LibraryTest.groovy + +``` +import +spock.lang.Specification +class +LibraryTest +extends + Specification { + +def +" +someLibraryMethod returns true +" +() { + +setup +: + +def + lib = +new + Library() + + +when +: + +def + result = lib.someLibraryMethod() + + +then +: + result == +true + + } +} +``` + +The generated test class has a single[Spock specification](http://spockframework.org/). The test instantiates the`Library`class, invokes the`someLibraryMethod`method, and checks that the returned value is`true`. + +## [Execute the build](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#execute_the_build) {#execute_the_build} + +To build the project, run the`build`task. You can use the regular`gradle`command, but when a project includes a wrapper script, it is considered good form to use it instead. + +``` +$ ./gradlew build +:compileJava NO-SOURCE +:compileGroovy +:processResources NO-SOURCE +:classes +:jar +:assemble +:compileTestJava NO-SOURCE +:compileTestGroovy +:processTestResources NO-SOURCE +:testClasses +:test +:check +:build + +BUILD SUCCESSFUL in 8s +4 actionable tasks: 4 executed +``` + +| | The first time you run the wrapper script,`gradlew`, there may be a delay while that version of`gradle`is downloaded and stored locally in your`~/.gradle/wrapper/dists`folder. | +| :--- | :--- | + + +The first time you run the build, Gradle will check whether or not you already have the Groovy, Spock Framework and JUnit libraries in your cache under your`~/.gradle`directory. If not, the libraries will be downloaded and stored there. The next time you run the build, the cached versions will be used. The`build`task compiles the classes, runs the tests, and generates a test report. + +You can view the test report by opening the HTML output file, located at`build/reports/tests/test/index.html`. + +A sample report is shown here: + +![](https://guides.gradle.org/building-groovy-libraries/images/Test-Summary.png "Test Summary") + +Congratulations, you have just completed the step from creating a Groovy library! You can can now customise this to your own project needs. + +## [Adding API documentation](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#adding_api_documentation) {#adding_api_documentation} + +The`groovy`plugin has built-in support for Groovy’s API documentation tool`groovydoc`. + +Annotate the`Library.groovy`file with Groovydoc markup. + +src/main/groovy/Library.groovy + +``` +/** This Groovy source file was generated by the Gradle 'init' task. + */ +class +Library + { + +boolean + someLibraryMethod() { + +true + + } +} +``` + +Run the`groovydoc`task. + +``` +$ ./gradlew groovydoc +:compileJava NO-SOURCE +:compileGroovy +:processResources NO-SOURCE +:classes +:groovydoc +[ant:groovydoc] /home/travis/build/gradle-guides/building-groovy-libraries/build/runners/gradleRunner/build/tmp/groovydoc contains source files in the default package, you must specify them as source files not packages. + +BUILD SUCCESSFUL in 5s +2 actionable tasks: 2 executed +``` + +You can view the generated Groovydoc by opening the HTML file, located at`build/docs/groovydoc/index.html`. + +## [Summary](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#summary) {#summary} + +You now have a new Groovy project that you generated using Gradle’s build init plugin. In the process, you saw: + +* How to generate a Groovy library + +* How the generated build file and sample Groovy files are structured + +* How to run the build and view the test report + +* Generating API documentation. + +## [Next Steps](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#next_steps) {#next_steps} + +* Read about the[Groovy Plugin](https://docs.gradle.org/4.6/userguide/groovy_plugin.html) + +* Get to know the configurations for the[GroovyCompile](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.compile.GroovyCompile.html)and[Groovydoc](https://docs.gradle.org/4.6/dsl/org.gradle.api.tasks.javadoc.Groovydoc.html)task types. + +## [Help improve this guide](https://guides.gradle.org/building-groovy-libraries/?_ga=2.20469688.1895311821.1524060450-1807434561.1523282416#help_improve_this_guide) {#help_improve_this_guide} + +Have feedback or a question? Found a typo? Like all Gradle guides, help is just a GitHub issue away. Please add an issue or pull request to[gradle-guides/building-groovy-libraries](https://github.com/gradle-guides/building-groovy-libraries/)and we’ll get back to you. + From 4f0abce178e0ee8edb1a9e06ead7366fa019d5d9 Mon Sep 17 00:00:00 2001 From: BurjalHou Date: Wed, 18 Apr 2018 15:34:02 +0000 Subject: [PATCH 101/102] Updates xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md Auto commit by GitBook Editor --- .../groovy/building-groovy-libraries.md | 102 +++++------------- 1 file changed, 26 insertions(+), 76 deletions(-) diff --git a/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md b/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md index 0f0998f..48ef90f 100644 --- a/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md +++ b/xiang-mu-shi-yong-jiao-cheng/groovy/building-groovy-libraries.md @@ -41,18 +41,18 @@ The`init`task runs the`wrapper`task first, which generates the`gradlew`and`gradl ``` ├── build.gradle ├── gradle -│   └── wrapper +│ └── wrapper -│   ├── gradle-wrapper.jar -│   └── gradle-wrapper.properties +│ ├── gradle-wrapper.jar +│ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main - │   └── groovy + │ └── groovy - │   └── Library.groovy + │ └── Library.groovy └── test └── groovy @@ -71,10 +71,7 @@ The`settings.gradle`file is heavily commented, but has only one active line: Generated settings.gradle ``` -rootProject.name = -' -gradleRunner -' +rootProject.name = 'gradleRunner' ``` | | This assigns the name of the root project. | @@ -87,30 +84,17 @@ Generated build.gradle ``` plugins { - id -' -groovy -' - + id 'groovy' } dependencies { - compile -' -org.codehaus.groovy:groovy-all:2.4.13 -' - - - testCompile -' -org.spockframework:spock-core:1.0-groovy-2.4 -' + compile 'org.codehaus.groovy:groovy-all:2.4.13' + testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' } repositories { jcenter() - } ``` @@ -127,15 +111,9 @@ The file`src/main/groovy/Library.groovy`is shown here: Generated src/main/groovy/Library.groovy ``` -class -Library - { - -boolean - someLibraryMethod() { - -true - +class Library { + boolean someLibraryMethod() { + true } } ``` @@ -145,40 +123,18 @@ The generated Spock specification,`src/test/groovy/LibraryTest.groovy`is shown n Generated src/test/groovy/LibraryTest.groovy ``` -import -spock.lang.Specification -class -LibraryTest -extends - Specification { - -def -" -someLibraryMethod returns true -" -() { - -setup -: - -def - lib = -new - Library() - - -when -: - -def - result = lib.someLibraryMethod() - - -then -: - result == -true +import spock.lang.Specification + +class LibraryTest extends Specification { + def "someLibraryMethod returns true"() { + setup: + def lib = new Library() + when: + def result = lib.someLibraryMethod() + + then: + result == true } } ``` @@ -234,15 +190,9 @@ src/main/groovy/Library.groovy ``` /** This Groovy source file was generated by the Gradle 'init' task. */ -class -Library - { - -boolean - someLibraryMethod() { - -true - +class Library { + boolean someLibraryMethod() { + true } } ``` From 679bd73c6467c65ecc2db87c281cee503ec5120a Mon Sep 17 00:00:00 2001 From: yangxiaobin Date: Mon, 8 Oct 2018 10:36:31 +0800 Subject: [PATCH 102/102] Update README.md Take a chapter. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95d37aa..73a2d25 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ ##### Authoring Gradle Builds -* [ ] [Groovy DSL Reference](https://docs.gradle.org/current/dsl/) +* [x] [Groovy DSL Reference](https://docs.gradle.org/current/dsl/)([@yangxiaobin](https://github.com/yangxiaobinhaoshuai)) * [ ] [Gradle API Javadoc](https://docs.gradle.org/current/javadoc/) * [ ] [Gradle Feature Lifecycle](https://docs.gradle.org/current/userguide/feature_lifecycle.html) * [ ] [Best Practices](https://docs.gradle.org/current/userguide/userguide.html#best-practices) @@ -91,6 +91,6 @@ Gitbook 提供了非常棒的在线编辑功能, 所以想贡献的同学可以 | 张扬 | zhangyang911120@gmail.com | [Github](https://github.com/dreamkidd) | | d0048 | d0048@foxmail.com | [Github](https://github.com/D0048) | | BurjalHou | burjalhou@gmail.com | [Github](https://github.com/BurjalHou) | - +| yangxiaobin | yangxiaobinn@gmail.com | [Github](https://github.com/yangxiaobinhaoshuai) |