Contents

Gradle中的自定义任务

1. 概述

在本文中,我们将介绍如何在 Gradle 中创建自定义任务。我们将使用构建脚本或自定义任务类型展示新的任务定义。

Gradle 的介绍请看这篇文章 。它包含 Gradle 的基础知识以及对本文最重要的内容——Gradle 任务的介绍。

2. build.gradle内部的自定义任务定义

要创建一个简单的 Gradle 任务,我们需要将其定义添加到我们的build.gradle文件中:

task welcome {
    doLast {
        println 'Welcome in the Blogdemo!'
    }
}

上述任务的主要目标只是打印文本“Welcome in the Blogdemo!”。我们可以通过运行gradle tasks –all命令来检查这个任务是否可用:

gradle tasks --all

该任务在其他任务组下的列表中:

## Other tasks
welcome

它可以像任何其他 Gradle 任务一样执行:

gradle welcome

输出如预期 - “欢迎来到Blogdemo!” 信息。

备注:如果选项*–all*未设置,则属于“其他”类别的任务不可见。自定义 Gradle 任务可以属于与“其他”不同的组,并且可以包含描述。

3. 设置组和描述

有时按功能对任务进行分组很方便,因此它们在一个类别下可见。我们可以为我们的自定义任务快速设置组,只需定义一个组属性

task welcome {
    group 'Sample category'
    doLast {
        println 'Welcome on the Blogdemo!'
    }
}

现在,当我们运行 Gradle 命令列出所有可用任务时(不再需要*–all*选项),我们将在新组下看到我们的任务:

## Sample category tasks
welcome

但是,其他人看到任务负责什么也是有益的。我们可以创建一个包含简短信息的描述:

task welcome {
    group 'Sample category'
    description 'Tasks which shows a welcome message'
    doLast {
        println 'Welcome in the Blogdemo!'
    }
}

当我们打印可用任务的列表时,输出将如下所示:

## Sample category tasks
welcome - Tasks which shows a welcome message

这种任务定义称为ad-hoc 定义

更进一步,创建可重复使用定义的可自定义任务是有益的。我们将介绍如何从一个类型创建一个任务,以及如何为这个任务的用户提供一些自定义。

4. 在build.gradle 中定义 Gradle 任务类型

上述“欢迎”任务无法自定义,因此在大多数情况下,它不是很有用。我们可以运行它,但是如果我们在不同的项目(或子项目)中需要它,那么我们需要复制并粘贴它的定义。

我们可以通过创建任务类型来快速启用任务的自定义。只是,在构建脚本中定义了一个任务类型:

class PrintToolVersionTask extends DefaultTask {
    String tool
    @TaskAction
    void printToolVersion() {
        switch (tool) {
            case 'java':
                println System.getProperty("java.version")
                break
            case 'groovy':
                println GroovySystem.version
                break
            default:
                throw new IllegalArgumentException("Unknown tool")
        }
    }
}

定义任务类型是一个简单的 Groovy 类,它扩展了DefaultTask——定义标准任务实现的类。我们可以扩展其他任务类型,但在大多数情况下,DefaultTask类是合适的选择。

PrintToolVersionTask 任务包含可以通过此任务的实例自定义的工具属性:

String tool

我们可以根据需要添加任意数量的属性——请记住,它只是一个简单的 Groovy 类字段。

此外,它还包含用*@TaskAction*注释的方法。它定义了这个任务正在做什么。在这个简单的示例中,它打印已安装 Java 或 Groovy 的版本——取决于给定的参数值。

要根据创建的任务类型运行自定义任务,我们需要创建一个这种类型的新任务实例

task printJavaVersion(type : PrintToolVersionTask) {
    tool 'java'
}

最重要的部分是:

  • 我们的任务是一个PrintToolVersionTask类型,所以在执行时它会触发在使用*@TaskAction*注解的方法中定义的动作
  • 我们添加了一个自定义工具属性值 ( java ), PrintToolVersionTask将使用它

当我们运行上述任务时,输出如预期(取决于安装的 Java 版本):

> Task :printJavaVersion 
9.0.1

现在让我们创建一个打印已安装版本的 Groovy 的任务:

task printGroovyVersion(type : PrintToolVersionTask) {
    tool 'groovy'
}

它使用与我们之前定义的相同的任务类型,但它具有不同的工具属性值。当我们执行这个任务时,它会打印 Groovy 版本:

> Task :printGroovyVersion 
2.4.12

如果我们没有太多的自定义任务,那么我们可以直接在build.gradle文件中定义它们(就像我们上面所做的那样)。但是,如果有多个,那么我们的构建。gradle 文件变得难以阅读和理解。

幸运的是,Gradle 提供了一些解决方案。

5. 在buildSrc文件夹中定义任务类型

我们可以在位于根项目级别的buildSrc文件夹中定义任务类型。Gradle 编译内部的所有内容并将类型添加到类路径中,以便我们的构建脚本可以使用它。

我们之前定义的任务类型(PrintToolVersionTask)可以移动到buildSrc/src/main/groovy/com/blogdemo/PrintToolVersionTask.groovy中。我们只需要从 Gradle API 中添加一些导入到移动的类中。

我们可以在buildSrc文件夹中定义无限数量的任务类型。它更易于维护、阅读,并且任务类型声明与任务实例化不在同一个地方。

我们可以像使用在构建脚本中直接定义的类型一样使用这些类型。我们必须记住只添加适当的导入。

6. 在插件中定义任务类型

我们可以在自定义 Gradle 插件中定义自定义任务类型。请参考这篇文章 ,它描述了如何定义一个自定义的 Gradle 插件,定义在:

  • build.gradle文件
  • buildSrc文件夹作为其他 Groovy 类

当我们定义对这个插件的依赖时,这些自定义任务将可用于我们的构建。请注意,临时任务也可用——不仅是自定义任务类型。