栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

gradle构建工具学习系列–010编写和使用自定义task

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

gradle构建工具学习系列–010编写和使用自定义task


gradle构建工具学习系列


上一章当中的makeReleaseVersion中的动作逻辑相当简单。当前代码的可维护性显然不是问题。然而,随着项目的增长,原本简单的task需要增加更多的逻辑,此时就有了对类和方法中的代码的结构化需求。应该使用像在常规的产品源代码中习惯使用的编码管理。Gradle不建议使用某种特殊方法编写task。完全可以根据熟悉程度,选择熟悉的编程语法,比如Java、Groovy等基于JVM的语言。

自定义task包含两个组件:
- 自定义的task类,封装了逻辑思维,也被称为任务类型,
- 真实的task,提供了用于配置行为的task类所暴露的属性值。Gradle把这些task称为增强的task.

可维护性和可重用性是自定义task类的优势

编写自定义的task类

Gradle为构建脚本中的每个简单的task都创建了一个DefaultTask类型的实例,当创建一个自定义的task时,需要做的是,创建一个继承DefaultTask的类。比如以下为使用Groovy编写的自定义类ReleaseVersionTask。

class ReleaseVersionTask extends DefaultTask {
    @Input Boolean release
    @OutputFile File destFile

    ReleaseVersionTask() {
        group = 'versioning'
        description = 'Makes project a release version.'
    }

    @TaskAction
    void start() {
        project.version.release = true
        ant.propertyfile(file: destFile) {
            entry(key: 'release', type: 'string', operation: '=', value: 'true')
        }
    }
}

在这个类当中,没有使用DefaultTask的属性来声明它的输入和输出,而是使用org.gradle.api.tasks包下的注解。它们不仅与TaskInputs和TaskOutputs方法由相同的效果。在自定义的task当中,使用@Input注解声明输入属性release,使用@outputFile注解定义输出文件。为属性添加输入和输出注解并不是唯一的选择,你也可以为getter方法添加注解。

task输入验证:@Input注解会在配置期间验证属性值,如果值为null,Gradle会抛出TaskValidationException异常。为了允许输入null值,可以添加@Optional注解。

使用自定义task

通过创建一个动作方法暴露它的配置属性,实现了一个自定义的task类。那么该如何使用它呢?在构建脚本当中,需要创建一个ReleaseVersionTask类型的task,并且通过为它的属性赋值来设置输入和输出,如下所示

task makeReleaseVersion(type: ReleaseVersionTask) {
    release = version.release
    destFile = versionFile
}

构建脚本build.gradle中其他代码如下所示,在上一章都已经讲解过

ext.versionFile = file('version.properties')

task loadVersion {
    project.version = readVersion()
}

ProjectVersion readVersion() {
    logger.quiet 'Reading the version file.'

    if (!versionFile.exists()) {
        throw new GradleException("Required version file does not exit: $versionFile.canonicalPath")
    }

    Properties versionProps = new Properties()

    versionFile.withInputStream { stream ->
        versionProps.load(stream)
    }

    new ProjectVersion(versionProps.major.toInteger(), versionProps.minor.toInteger(), versionProps.release.toBoolean())
}

class ProjectVersion {
    Integer major
    Integer minor
    Boolean release

    ProjectVersion(Integer major, Integer minor) {
        this.major = major
        this.minor = minor
        this.release = Boolean.FALSE
    }

    ProjectVersion(Integer major, Integer minor, Boolean release) {
        this(major, minor)
        this.release = release
    }

    @Override
    String toString() {
        "$major.$minor${release ? '' : '-SNAPSHOT'}"
    }
}

以及同目录下的version.properties文件

major=0
minor=1
release=false

在控制台执行任务

而version.properties文件被修改了

任务起效了。

自定义task的可重用性

假设你想要在另一个项目当中使用自定义task,在那个项目中,需求是不同的。其版本POJO通过暴露不同的属性来表示版本管理方案,如下所示

class ProjectVersion {
    Integer min
    Integer maj
    Boolean prodReady

    @Override
    String toString() {
        "$maj.$min${prodReady ? '' : '-SNAPSHOT'}"
    }
}

而且此时项目所有者决定命名版本文件为project-version.properties而不是version.properties。如何让增强的task满足这些需求呢?其实你只需要给所暴露的属性赋予不同的值就可以了。自定义的task类可以灵活得处理需求的变化。

task makeReleaseVersion(type: ReleaseVersionTask) {
    release = version.prodReady
    destFile = new File('project-version.properties')
}

结果如下

以下为完整的代码

ext.versionFile = file('project-version.properties')

task loadVersion {
    project.version = readVersion()
}

ProjectVersion readVersion() {
    logger.quiet 'Reading the version file.'

    if (!versionFile.exists()) {
        throw new GradleException("Required version file does not exit: $versionFile.canonicalPath")
    }

    Properties versionProps = new Properties()

    versionFile.withInputStream { stream ->
        versionProps.load(stream)
    }

    new ProjectVersion(min: versionProps.major.toInteger(), maj: versionProps.minor.toInteger(), prodReady: versionProps.release.toBoolean())
}

task makeReleaseVersion(type: ReleaseVersionTask) {
    release = version.prodReady
    destFile = new File('project-version.properties')
}

class ReleaseVersionTask extends DefaultTask {
    @Input Boolean release
    @OutputFile File destFile

    ReleaseVersionTask() {
        group = 'versioning'
        description = 'Makes project a release version.'
    }

    @TaskAction
    void start() {
        project.version.prodReady = true
        ant.propertyfile(file: destFile) {
            entry(key: 'release', type: 'string', operation: '=', value: 'true')
        }
    }
}

class ProjectVersion {
    Integer min
    Integer maj
    Boolean prodReady

    @Override
    String toString() {
        "$maj.$min${prodReady ? '' : '-SNAPSHOT'}"
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678529.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号