- 介绍
- 介绍 - 关于这本指南
- 概述
- 概述 - 特点
- 概述 - 为什么用 Groovy?
- 教程
- 安装Gradle
- 安装Gradle - 准备阶段
- 安装Gradle - 下载与安装
- 安装Gradle - JVM选项
- 排除故障
- 构建脚本基础
- 构建脚本基础 - Projects 和 tasks
- 构建脚本基础 - Hello world
- 构建脚本基础 - 快捷的任务定义
- 构建脚本基础 - 构建脚本代码
- 构建脚本基础 - 任务依赖
- 构建脚本基础 - 动态任务
- 构建脚本基础 - 使用已经存在的任务
- 构建脚本基础 - 短标记法
- 构建脚本基础 - 自定义任务属性
- 构建脚本基础 - 调用 Ant 任务
- 构建脚本基础 - 使用方法
- 构建脚本基础 - 默认任务
- 构建脚本基础 - 通过 DAG 配置
- Java 构建入门
- Java 构建入门 - Java 插件
- Java 构建入门 - 一个基础的 Java 项目
- 一个基础的 Java 项目 - 建立项目
- 一个基础的 Java 项目 - 外部的依赖
- 一个基础的 Java 项目 - 定制项目
- 一个基础的 Java 项目 - 发布 JAR 文件
- 一个基础的 Java 项目 - 创建 Eclipse 项目
- 一个基础的 Java 项目 - 总结
- Java 构建入门 - 多项目的 Java 构建
- 多项目的 Java 构建 - 定义一个多项目构建
- 多项目的 Java 构建 - 通用配置
- 多项目的 Java 构建 - 项目之间的依赖
- 多项目的 Java 构建 - 创建一个发行版本
- 依赖管理的基础知识
- 依赖管理的基础知识 - 什么是依赖管理
- 依赖管理的基础知识 - 声明你的依赖
- 依赖管理的基础知识 - 依赖配置
- 依赖管理的基础知识 - 外部的依赖
- 依赖管理的基础知识 - 仓库
- 依赖管理的基础知识 - 发布 artifacts
- 依赖管理的基础知识 - 下一步?
- Groovy 快速入门
- Groovy 快速入门 - 一个基本的 Groovy 项目
- Groovy 快速入门 - 总结
- 网页应用快速入门
- 网页应用快速入门 - 构建一个 WAR 文件
- 网页应用快速入门 - 运行 Web 应用
- 网页应用快速入门 - 总结
- 使用 Gradle 命令行
- 使用 Gradle 命令行 - 多任务调用
- 使用 Gradle 命令行 - 排除任务
- 使用 Gradle 命令行 - 失败后继续执行构建
- 使用 Gradle 命令行 - 简化任务名
- 使用 Gradle 命令行 - 选择文件构建
- 使用 Gradle 命令行 - 获取构建信息
- 获取构建信息 - 项目列表
- 获取构建信息 - 任务列表
- 获取构建信息 - 获取任务具体信息
- 获取构建信息 - 获取依赖列表
- 获取构建信息 - 查看特定依赖
- 获取构建信息 - 获取项目属性列表
- 获取构建信息 - 构建日志
- 使用 Gradle 图形界面
- 使用 Gradle 图形界面 - 任务树
- 使用 Gradle 图形界面 - 收藏夹
- 使用 Gradle 图形界面 - 命令行
- 使用 Gradle 图形界面 - 设置
- 编写构建脚本 - Gradle 构建语言
- 编写构建脚本 - 项目 API
- 项目 API - 标准项目属性
- 编写构建脚本 - 脚本 API
- 编写构建脚本 - 声明变量
- 声明变量 - 局部变量
- 声明变量 - 扩展属性
- 编写构建脚本 - Groovy 基础
- Groovy 基础 - Groovy JDK
- Groovy 基础 - 属性存取器
- Groovy 基础 - 可有可无的圆括号
- Groovy 基础 - List 和 Map 集合
- Groovy 基础 - 闭合作为方法的最后一个参数
- Groovy 基础 - 闭合委托对象
- 深入了解 Tasks
- 深入了解 Tasks - 定义 tasks
- 深入了解 Tasks - 定位 tasks
- 深入了解 Tasks - 配置 tasks
- 深入了解 Tasks - 给 task 加入依赖
- 深入了解 Tasks - 给 tasks 排序
- 深入了解 Tasks - 给 task 加入描述
- 深入了解 Tasks - 替换 tasks
- 深入了解 Tasks - 跳过 tasks
- 深入了解 Tasks - 跳过 up-to-date 的任务
- 深入了解 Tasks - Task 规则
- 深入了解 Tasks - 终止 tasks
- 深入了解 Tasks - 补充
- 补充 - Gradle 属性 和 system 属性
- 补充 - 使用其他的脚本配置项目
- 补充 - 使用其他的脚本配置任意对象
- 补充 - 配置任意对象
- 补充 - 缓存
- 文件操作
- 文件操作 - 定位文件
- 文件操作 - 文件集合
- 文件操作 - 文件树
- 文件操作 - 使用一个归档文件的内容作为文件树
- 文件操作 - 指定一组输入文件
- 文件操作 - 复制文件
- 文件操作 - 使用同步任务
- 文件操作 - 创建归档文件
- 使用 Ant 插件
- 使用 Ant 插件 - 使用 Ant 任务和 Ant 类型的构建
- 使用 Ant 任务和 Ant 类型的构建 - 在构建中使用自定义 Ant 任务
- 使用 Ant 插件 - 导入一个 Ant 构建
- 使用 Ant 插件 - Ant 的属性与引用
- 使用 Ant 插件 - API
- Logging
- Logging - 选择日志等级
- Logging - 编写自己的日志信息
- Logging - 外部工具和库的log
- Logging - 改变 Gradle 记录的内容
- Gradle的守护进程
- Gradle的守护进程 - 什么是Gradle的守护进程
- Gradle的守护进程 - 管理和配置
- 管理和配置 - 如何启用的摇篮守护进程
- 管理和配置 - 如何禁用Gradle的守护进程
- 管理和配置 - 怎样抑制“please consider using the Gradle Daemon”消息
- 管理和配置 - 为什么会在机器上出现不只一个守护进程
- 管理和配置 - 守护进程占用多大内存并且能不能给它更大的内存?
- 管理和配置 - 如何停止守护进程
- 管理和配置 - 守护进程何时会出错
- Gradle的守护进程 - 什么时候使用Gradle守护进程
- Gradle的守护进程 - 工具和集成开发环境
- Gradle的守护进程 - 摇篮守护进程如何使构建速度更快
- 摇篮守护进程如何使构建速度更快 - 未来可能的改进
- Gradle Plugins
- Gradle Plugins - 插件的作用
- Gradle Plugins - 插件的类型
- Gradle Plugins - 应用插件
- 应用插件 - 脚本插件
- 应用插件 - 二进制插件
- 二进制插件 - 二进制插件的位置
- Gradle Plugins - 使用构建脚本块应用插件
- Gradle Plugins - 使用插件的插件DSL
- 使用插件的插件DSL - 插件DSL的限制
- 使用插件的插件DSL - 约束语法
- 使用插件的插件DSL - 只能在构建脚本中使用
- 使用插件的插件DSL - 不能与subjects{},allprojects{}等结合使用
- Gradle Plugins - 查找社区插件
- Gradle Plugins - 更多关于插件
- Gradle插件规范
- Gradle插件规范 - 语言插件
- Gradle插件规范 - 孵化中的语言插件
- Gradle插件规范 - 集成插件
- Gradle插件规范 - 孵化中的集成插件
- Gradle插件规范 - 软件开发插件
- Gradle插件规范 - 孵化中的软件开发插件
- Gradle插件规范 - 基础插件
- Gradle插件规范 - 第三方插件
- Java 插件
- Java 插件 - 使用
- Java 插件 - 资源集
- Java 插件 - 任务
- Java 插件 - 项目布局
- Java 插件 - 依赖管理
- Java 插件 - 公共配置
- Java 插件 - 使用资源集工作
- 使用资源集工作 - 资源集属性
- 使用资源集工作 - 定义新的资源集
- 使用资源集工作 - 资源集例子
- Java 插件 - Javadoc
- Java 插件 - 清除
- Java 插件 - 资源
- Java 插件 - 编译 Java
- Java 插件 - 增量 Java 编译
- Java 插件 - 测试
- 测试 - 测试执行
- 测试 - 测试调试
- 测试 - 测试过滤
- 测试 - 通过系统属性执行单独测试
- 测试 - 测试检测
- 测试 - 测试分组
- 测试 - 测试报告
- 测试报告 - TestNG 的参数化方法和报告
- 测试 - 公共值
- Java 插件 - Jar
- Jar - Manifest
- Java 插件 - 上传
- War插件
- War插件 - 使用
- War插件 - 任务
- War插件 - 项目布局
- War插件 - 依赖管理
- War插件 - 公共配置
- War插件 - War
- War插件 - 定制War
- Ear插件
深入了解 Tasks - 跳过 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 类型. 任务的输出属性是 TaskOutputs 类型.
一个任务如果没有定义输出的话, 那么它永远都没用办法判断 up-to-date. 对于某些场景, 比如一个任务的输出不是文件, 或者更复杂的场景, TaskOutputs.upToDateWhen()) 方法会计算任务的输出是否应被视为最新.
总而言之, 如果一个任务只定义了输出, 如果输出不变的话, 它就会被视为 up-to-date.
2. 它是如何工作的?
当一个任务是首次执行时, Gradle 会取一个输入的快照 (snapshot). 该快照包含组输入文件和每个文件的内容的散列. 然后当 Gradle 执行任务时, 如果任务成功完成,Gradle 会获得一个输出的快照. 该快照包含输出文件和每个文件的内容的散列. Gradle 会保留这两个快照用来在该任务的下一次执行时进行判断.
之后, 每次在任务执行之前, Gradle 都会为输入和输出取一个新的快照, 如果这个快照和之前的快照一样, Gradle 就会假定这个任务已经是最新的 (up-to-date) 并且跳过任务, 反之亦然.
需要注意的是, 如果一个任务有指定的输出目录, 自从该任务上次执行以来被加入到该目录的任务文件都会被忽略, 并且不会引起任务过时 (out of date). 这是因为不相关任务也许会共用同一个输出目录. 如果这并不是你所想要的情况, 可以考虑使用 TaskOutputs.upToDateWhen())
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论