使用命令行

在前面的部分中,您在命令行上执行了任务 helloWorld 和 groupTherapy,这将是您运行本书中大多数示例的首选工具。 尽管使用 IDE 对于新手来说似乎更方便,但从长远来看,深入了解 Gradle 的命令行选项和帮助器任务将使您更加高效和富有成效。

列出项目的可用任务

在上一节中,我向您展示了如何使用 gradle 命令运行特定任务。 运行任务需要您知道确切的名称。 如果 Gradle 能够告诉您哪些任务可用,而无需您查看源代码,那不是很棒吗? Gradle 提供了一个名为 tasks 的帮助器任务来内省您的构建脚本并显示每个可用任务,包括其用途的描述性消息。 在安静模式下运行 gradle 任务会产生以下输出:

$ gradle -q tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
setupBuild - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Help tasks
----------
dependencies - Displays the dependencies of root project 'grouptherapy'.
dependencyInsight - Displays the insight into a specific dependency in root
➥ project 'grouptherapy'.
help - Displays a help message
projects - Displays the sub-projects of root project 'grouptherapy'.
properties - Displays the properties of root project 'grouptherapy'.
tasks - Displays the tasks runnable from root project 'grouptherapy' (some of
➥ the displayed tasks may belong to subprojects).

Other tasks
-----------
groupTherapy
To see all tasks and more detail, run with --all.

关于输出结果,有几点需要注意。Gradle 提供了任务组的概念,可以将其视为分配给该组的任务群。开箱即用的每个构建脚本都会显示任务组帮助任务,开发者无需做任何额外工作。如果某个任务不属于某个任务组,则会显示在 "其他任务" 下。这就是任务组治疗的位置。我们将在第 4 章中介绍如何将任务添加到任务组。

你可能想知道在构建脚本中定义的其他任务发生了什么。在输出结果的底部,你会发现一条提示:使用 --all 选项可以获得项目任务的更多详细信息。运行它以获取更多信息:

$ gradle -q tasks --all
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
setupBuild - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Help tasks
----------
dependencies - Displays the dependencies of root project 'grouptherapy'.
help - Displays a help message
projects - Displays the sub-projects of root project 'grouptherapy'.
properties - Displays the properties of root project 'grouptherapy'.
tasks - Displays the tasks runnable from root project 'grouptherapy' (some of
➥ the displayed tasks may belong to subprojects).

Other tasks
-----------
groupTherapy
startSession
yayGradle0
yayGradle1
yayGradle2

--all 选项是在实际执行任务图之前确定任务图的执行顺序的好方法。 为了减少噪音,Gradle 足够聪明,可以隐藏充当根任务依赖项的任务。 为了更好的可读性,相关任务在根任务下方显示缩进和排序。

任务执行

在前面的示例中,您通过将一项特定任务添加为命令 gradle 的参数来告诉 Gradle 执行该任务。 Gradle 的命令行实现将反过来确保任务及其所有依赖项都被执行。 您还可以通过将多个任务定义为命令行参数来在一次构建运行中执行多个任务。 运行 gradle yayGradle0 groupTherapy 将首先执行任务 yayGradle0,然后执行任务 groupTherapy。

任务总是只执行一次,无论它们是在命令行上指定还是充当另一个任务的依赖项。 让我们看看输出是什么样的:

$ gradle yayGradle0 groupTherapy
:startSession
[ant:echo] Repeat after me...
:yayGradle0
Gradle rocks
:yayGradle1
Gradle rocks
:yayGradle2
Gradle rocks
:groupTherapy

这里没有什么惊喜。 您会看到与刚刚运行 gradle groupTherapy 相同的输出。 保留了正确的顺序,并且每个任务仅执行一次。

任务名称缩写

Gradle 的生产力工具之一是在命令行中缩写驼峰字母任务名。如果你想以缩写形式运行前面的例子,只需输入 gradle yG0 gT 即可。这在处理很长的任务名或多个任务参数时尤其有用。请记住,任务名称缩写必须是唯一的,这样 Gradle 才能识别相应的任务。考虑以下情况:

task groupTherapy << {
...
}
task generateTests << {
...
}

在定义任务 groupTherapy 和 generateTests 的构建中使用缩写 gT 会导致 Gradle 显示错误:

$ gradle yG0 gT

FAILURE: Could not determine which tasks to execute.

* What went wrong:
Task 'gT' is ambiguous in root project 'grouptherapy'. Candidates are:
➥ 'generateTests', 'groupTherapy'.

* Try:
Run gradle tasks to get a list of available tasks.

BUILD FAILED

从执行中排除任务

有时您想从构建运行中排除特定任务。 Gradle 提供了命令行选项 –x 来实现这一点。 假设您要排除任务 yayGradle0:

$ gradle groupTherapy -x yayGradle0
:yayGradle1
Gradle rocks
:yayGradle2
Gradle rocks
:groupTherapy

Gradle 排除了任务 yayGradle0 及其依赖任务 startSession,Gradle 将这一概念称为智能排除。 现在您已经熟悉了命令行,让我们探索一些更有用的功能。

命令行选项

在本节中,我们将探讨最重要的通用选项、控制构建脚本日志级别的标志,以及为项目提供属性的方法。gradle 命令允许你同时定义一个或多个选项。比方说,你想使用 -i 选项将日志级别改为 INFO,并在执行过程中出现错误时使用 -s 选项打印出堆栈跟踪。为此,请像这样执行 groupTherapy 命令:gradle groupTherapy -is 或 gradle groupTherapy -i -s。正如你所看到的,组合多个选项非常简单。要了解全套选项,请使用 -h 参数运行构建,或参看本书附录 A。我不会详述所有可用选项,但最重要的选项如下:

  • -?, -h, --help:打印所有可用的命令行选项,包括描述性信息。

  • -b,--build-file:Gradle 构建脚本的默认命名约定是 build.gradle。使用该选项可以执行不同名称的构建脚本(例如,gradle -b test.gradle)。

  • --offline: 通常情况下,您的联编会声明依赖库,但这些库只能在网络之外的软件源中找到。如果这些依赖库尚未存储在本地缓存中,在没有网络连接到这些库的情况下运行联编将导致联编失败。使用此选项可在离线模式下运行联编,并只检查本地依赖库缓存中的依赖库。

PROPERTY 选项

  • -D, --system-prop:Gradle 作为JVM 进程运行。 与所有 Java 进程一样,您可以提供如下系统属性:–Dmyprop=myvalue。

  • -P、--project-prop:项目属性是构建脚本中可用的变量。 您可以使用此选项直接从命令行将属性传递给构建脚本(例如,-Pmyprop=myvalue)。

LOGGING 选项

  • -i, --info:在默认设置下,Gradle 构建不会输出大量信息。 使用此选项可通过将 Gradle 的记录器更改为 INFO 日志级别来获取更多信息性消息。 如果您想了解更多有关幕后情况的信息,这会很有帮助。

  • -s, --stacktrace:如果您在构建中遇到错误,您会想知道它们源自何处。 如果抛出异常,选项 –s 会打印出简短的堆栈跟踪,使其非常适合调试损坏的构建。

  • -q、--quiet:将构建运行的日志消息减少为仅错误消息。

HELP 任务

  • tasks:显示项目的所有可运行任务,包括其描述。 应用于您的项目的插件可能会提供额外的任务。

  • properties:发出项目中所有可用属性的列表。 其中一些属性由 Gradle 的项目对象(构建的内部表示)提供。 其他属性是源自属性文件或属性命令行选项的用户定义属性,或者直接在构建脚本中声明。

Gradle 守护进程

日常使用 Gradle 时,您会发现自己必须重复运行构建。 如果您正在开发 Web 应用程序,则尤其如此。 您更改类、重建 Web 应用程序存档、启动服务器并在浏览器中重新加载 URL 以查看您的更改是否得到反映。 许多开发人员更喜欢使用测试驱动开发来实现他们的应用程序。 为了持续反馈代码质量,他们一遍又一遍地运行单元测试,以便及早发现代码缺陷。 在这两种情况下,您都会注意到生产力的显着下降。 每次启动构建时,都必须启动 JVM,将 Gradle 的依赖项加载到类加载器中,并构建项目对象模型。 此过程通常需要几秒钟。 Gradle 守护进程来救援!

该守护进程将 Gradle 作为后台进程运行。 一旦启动,gradle 命令将重用分叉的守护进程进行后续构建,从而完全避免启动成本。 让我们回到之前的构建脚本示例。 在我的机器上,大约需要三秒钟才能成功完成运行任务 groupTherapy。 希望我们能够改进启动和执行时间。 在命令行上启动 Gradle 守护进程很容易:只需将选项 --daemon 添加到 gradle 命令中即可。 您可能会注意到,我们还为启动守护进程添加了一些额外的时间。 要验证守护进程是否正在运行,您可以检查操作系统上的进程列表:

  • Mac OS X 和*nix:在 shell 中运行命令 ps | grep gradle 列出包含名称 gradle 的进程。

  • Windows:使用键盘快捷键 Ctrl+Shift+Esc 打开任务管理器,然后单击 “进程” 选项卡。

gradle 命令的后续调用现在将重用守护进程。 尝试一下并尝试运行 gradle groupTherapy --daemon。 哇,您的启动和执行时间减少到了大约一秒! 请记住,即使您添加了命令行选项 --daemon,守护进程也只会分叉一次。 守护进程将在三小时空闲时间后自动终止。 您可以随时选择通过添加命令行选项 --no-daemon 来执行构建而不使用守护进程。 要停止守护进程,请手动运行 gradle --stop。 简而言之,这就是 Gradle 守护进程。 要深入了解所有配置选项和复杂性,请参阅 Gradle 在线文档: http://gradle.org/docs/current/userguide/gradle_daemon.html

总结

现有工具无法满足当今行业的构建需求。 Gradle 改进了竞争对手的最佳想法,提供了按惯例构建的方法、可靠的依赖关系管理以及对多项目构建的支持,而无需牺牲构建的灵活性和描述性。

在本章中,我们探讨了如何使用 Gradle 在持续交付的背景下在部署管道的每个阶段进行交付。 在整本书中,我们将通过提供实际示例来了解每个阶段。

接下来,您将初步体验 Gradle 的强大功能。 您安装了运行时,编写了第一个简单的构建脚本,并执行了它。 通过实现更复杂的构建脚本,您发现使用 Gradle 的 DSL 定义任务依赖项是多么容易。 了解 Gradle 命令行的机制及其选项是提高工作效率的关键。 Gradle 提供了各种命令行开关,用于更改运行时行为、将属性传递到项目以及更改日志记录级别。 我们探讨了如果您必须连续执行任务(例如在测试驱动开发期间),运行 Gradle 如何能够节省大量时间。

在第 3 章中,我将展示如何使用 Gradle 构建一个成熟的、支持 Web 的应用程序。 从简单的独立 Java 应用程序开始,您将通过添加 Web 组件来扩展代码库,并使用 Gradle 的容器内 Web 开发支持来高效地实施解决方案。 我们不会就此止步。 我将展示如何增强您的 Web 存档,使其可供企业使用,并使构建可以跨机器传输,而无需安装 Gradle 运行时。