如何写出兼容Configuration Cache的Gradle插件?以modules-graph-assert任务设计为例

发布时间:2026/8/27 17:28:15

如何写出兼容Configuration Cache的Gradle插件?以modules-graph-assert任务设计为例
如何写出兼容Configuration Cache的Gradle插件以modules-graph-assert任务设计为例【免费下载链接】modules-graph-assertGradle plugin to keep your modules graph healthy and lean.项目地址: https://gitcode.com/gh_mirrors/mo/modules-graph-assertmodules-graph-assert是一个帮你守护模块依赖图谱的 Gradle 插件Gradle plugin它能通过assertModuleGraph任务校验模块依赖的高度、白名单与限制规则让模块图保持健康、精简。这篇文章以它的任务设计为例拆解如何写出兼容Configuration Cache的 Gradle 插件核心思路是配置期算好数据任务期只拿可序列化的纯数据全文约 10 分钟读完。为什么 Configuration Cache 兼容对 Gradle 插件很重要从 Gradle 7 开始Configuration Cache 成为官方主推的性能优化把配置阶段的成果缓存下来后续构建跳过重复配置。但代价是——任务Task在执行时不能再访问Project对象所有传给任务的东西必须可序列化。对插件作者来说常见踩坑点有四个任务字段里持有Project、Configuration、TaskContainer等对象在TaskAction里调用project.property(...)等 API任务用tasks.create()提前创建导致配置期就执行了大量逻辑输入值Input包含不可序列化的对象modules-graph-assert 针对这四点都有明确的设计取舍下面逐个拆解。整体设计把重活放在配置阶段输出纯数据插件入口是ModuleGraphAssertionsPlugin源码见plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleGraphAssertionsPlugin.kt。它的骨架逻辑是apply时只做两件事创建moduleGraphAssert扩展配置 DSL 的载体以及挂afterEvaluate回调真正的依赖图构建被放进lazy属性private val moduleGraph by lazy { GradleDependencyGraphFactory.create(evaluatedProject, configurationsToLook).serializableGraph() }关键点在于serializableGraph()——工厂类plugin/src/main/kotlin/com/jraska/module/graph/assertion/GradleDependencyGraphFactory.kt遍历所有子项目的api/implementation依赖构建出完整依赖图后立即把它压缩成一个只含字符串的轻量对象DependencyGraph.SerializableGraph。关键点一任务只接收 Serializable 的纯数据看断言任务的定义plugin/src/main/kotlin/com/jraska/module/graph/assertion/tasks/AssertGraphTask.ktopen class AssertGraphTask : DefaultTask() { Input lateinit var assertion: GraphAssert Input lateinit var dependencyGraph: DependencyGraph.SerializableGraph TaskAction fun run() { val modulesTree DependencyGraph.create(dependencyGraph) assertion.assert(modulesTree) } }注意这个任务没有任何 Project 字段。Input只有两个assertion规则校验器实现了GraphAssert接口而该接口继承java.io.Serializable见plugin/src/main/kotlin/com/jraska/module/graph/assertion/GraphAssert.ktdependencyGraph前面提到的可序列化图结构是模块对列表 根模块名全是字符串再看SerializableGraph的定义plugin/src/main/kotlin/com/jraska/module/graph/DependencyGraph.ktclass SerializableGraph( val dependencyPairs: ArrayListPairString, String, val firstModule: String ) : Serializable这就是兼容 Configuration Cache 的核心模式配置期访问Project获取依赖信息允许此时配置缓存还没生效然后把结果转成纯数据快照传给任务任务执行期只反序列化快照、计算断言完全不知道Project的存在。关键点二用 tasks.register 延迟创建任务插件注册任务全部走tasks.register(...)而不是tasks.create(...)project.tasks.register(Tasks.ASSERT_MAX_HEIGHT, AssertGraphTask::class.java) { it.assertion moduleTreeHeightAssert(graphRules) it.dependencyGraph moduleGraph it.outputs.upToDateWhen { true } it.group VERIFICATION_GROUP }register是惰性的——配置期只登记任务不实例化只有用户真的执行assertModuleGraph它会被挂到check任务上成为./gradlew check的一部分时才触发。这带来两个好处未执行的构建完全不触发依赖图构建moduleGraph也是lazy双保险即使执行也只在该任务真的要跑时才访问配置期数据另外断言类任务没有文件输出插件用it.outputs.upToDateWhen { true }明确告知 Gradle输入没变就视为最新让增量构建直接显示 UP-TO-DATE。关键点三属性在配置期读取而不是 TaskAction 里读GenerateModulesGraphTaskplugin/src/main/kotlin/com/jraska/module/graph/assertion/tasks/GenerateModulesGraphTask.kt需要支持-Pmodules.graph.output.gv这类项目参数。正确姿势是在任务注册的配置回调里就读完tasks.register(Tasks.GENERATE_GRAPHVIZ, GenerateModulesGraphTask::class.java) { it.outputFilePath GenerateModulesGraphTask.outputFilePath(this) it.onlyModuleToPrint GenerateModulesGraphTask.onlyModule(this) }读到的值被转成普通String?字段Input存进任务。任务执行时run()里只读自己的字段绝不再碰project.property(...)。这是新手最常犯的错误以为只是读个属性没大事结果 Configuration Cache 直接报错。还有个容易忽视的场景assertOnAnyBuild true模式要在任何构建时直接跑断言。插件用的是project.gradle.projectsEvaluated { ... }回调里直接执行断言逻辑复用同一份moduleGraph快照而不是试图在任务动作里访问 Project。如何验证兼容性两个测试用例这个项目值得学习的还有它把兼容性写进了测试集成测试plugin/src/test/kotlin/com/jraska/module/graph/assertion/ConfigurationAvoidanceTest.kt用 GradleRunner 真实构建测试工程参数带上--configuration-cache跑assertModuleGraph并断言第二次运行出现 4 个 UP-TO-DATE。这同时验证了缓存兼容和增量有效两件事。单元测试plugin/src/test/kotlin/com/jraska/module/graph/DependencyGraphSerializationTest.kt把图走一遍ObjectOutputStream→ObjectInputStream的序列化/反序列化往返断言统计结果不变——提前暴露任何漏写Serializable的字段。想在自己的插件里做同样的验证把--configuration-cache加进你的 TestKit 用例就够了。兼容 Configuration Cache 的插件检查清单把 modules-graph-assert 的做法归纳成 6 条写插件时可以逐条对照 ✅#实践对应示例1任务Input只用可序列化纯数据SerializableGraph字符串列表2任务中不持有Project引用AssertGraphTask无 Project 字段3用tasks.register惰性创建任务全部任务走register4项目参数在配置期读取为普通字段outputFilePath注册时读一次5无输出任务声明upToDateWhen { true }三个断言任务均如此6用 TestKit 序列化往返测试兜底ConfigurationAvoidanceTest小结一句话总结这套设计配置期做数据收集任务期做纯计算。modules-graph-assert 把遍历所有模块依赖的脏活封装在GradleDependencyGraphFactory里产出可序列化的图快照后任务就变成了无状态的计算单元——这正是 Gradle 官方推荐的 Configuration Cache 兼容模式。理解这一个插件的任务设计你写自己的插件尤其是涉及依赖、多项目聚合的时就已经避开了 90% 的坑。【免费下载链接】modules-graph-assertGradle plugin to keep your modules graph healthy and lean.项目地址: https://gitcode.com/gh_mirrors/mo/modules-graph-assert创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

CompreFace人脸识别模型实测:低光侧脸场景下的选型指南

CompreFace人脸识别模型实测:低光侧脸场景下的选型指南

2026/8/27 17:28:15

CompreFace人脸识别模型实测:低光侧脸场景下的选型指南 【免费下载链接】CompreFace Leading free and open-source face recognition system 项目地址: https://gitcode.com/gh_mirrors/co/CompreFace CompreFace是一套免费的开源人脸识别系统,支…

打造私人文献库:ScienceFair本地收藏、下载与标签管理完全教程

打造私人文献库:ScienceFair本地收藏、下载与标签管理完全教程

2026/8/27 17:18:15

打造私人文献库:ScienceFair本地收藏、下载与标签管理完全教程 【免费下载链接】sciencefair The futuristic, fabulous and free desktop app for working with scientific literature :microscope: :book: 项目地址: https://gitcode.com/gh_mirrors/sc/science…

AutoScientists快速上手:10分钟从零搭建到启动你的第一个AI科研团队(附完整环境配置)

AutoScientists快速上手:10分钟从零搭建到启动你的第一个AI科研团队(附完整环境配置)

2026/8/27 17:18:15

AutoScientists快速上手:10分钟从零搭建到启动你的第一个AI科研团队(附完整环境配置) 【免费下载链接】AutoScientists AutoScientists: Self-Organizing Agent Teams for Long-Running Scientific Experimentation 项目地址: https://gitc…

ABAP:Visual Studio Code->ABAP FS開發ABAP教程

ABAP:Visual Studio Code->ABAP FS開發ABAP教程

2026/8/27 18:28:17

和GUI相比其實沒有很大的好處,我覺得還是GUI寫代碼更方便一些,但是這裡多了可以編輯那些需要使用ECLIPSE開發的元素:CDS視圖 教程如下: 1.下載Visual Studio Code,官方連接如下: Download Visual Studio …

基于SpringCloud的分布式演唱会抢票系统(毕业设计项目源码+文档)

基于SpringCloud的分布式演唱会抢票系统(毕业设计项目源码+文档)

2026/8/27 18:28:17

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

EV 驱动电机零转速满转矩起步(Align→OpenLoop→FOC)Simulink 建模

EV 驱动电机零转速满转矩起步(Align→OpenLoop→FOC)Simulink 建模

2026/8/27 18:28:17

目录 一、为什么“零转速满转矩起步”要单独做 二、起步控制原理简述 2.1 预定位(Align / Pre‑Excite) 2.2 开环旋转(Open‑Loop Voltage‑Oriented) 2.3 切闭环 FOC 三、关键参数 四、Simulink 建模(手把手) 4.1 Step 1️⃣ —— PMSM + Inverter + 坐标变换(同…

为什么滤波器电容必须做真空注胶滤波器电容是变频器、新能源逆变器、车载充电机(OBC)、UPS、光伏储能、通信电源等高压设备的关键元件

为什么滤波器电容必须做真空注胶滤波器电容是变频器、新能源逆变器、车载充电机(OBC)、UPS、光伏储能、通信电源等高压设备的关键元件

2026/8/27 18:28:17

一、为什么滤波器电容必须做真空注胶滤波器电容是变频器、新能源逆变器、车载充电机(OBC)、UPS、光伏储能、通信电源等高压设备的关键元件。它长期工作在高电压、高频率、高温升环境下,对内部绝缘性、抗振性、散热性能、防潮等级有极高要求。…

Level 4自动驾驶系统设计46——L2/L3 级软硬件架构 2

Level 4自动驾驶系统设计46——L2/L3 级软硬件架构 2

2026/8/27 18:28:17

8.3 片外高刚性独立安全 MCU(如英飞凌 TC 系列)的接口分配与底软窗口看门狗(WWD)硬核防御 8.3.1 跨芯片级故障蔓延与 MCU “最后一道防线”的物理刚性 在 8.2 节关于 Level 3 级单芯片方案性能瓶颈的白盒解耦中,我们证实了在单片大算力 SoC 挂载 32G/64G 内存的商业包络…

分布式共识实现的分层测试

分布式共识实现的分层测试

2026/8/27 18:18:17

分布式共识实现的分层测试共识测试要验证安全性和活性,单节点通过不能说明选主和日志复制正确。 针对协议分层 单元测试覆盖任期与日志规则,集成测试模拟网络分区,场景测试检查成员加入和恢复后的状态。 记录可重放条件 保存消息顺序、随机种…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/27 11:10:02

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/27 7:25:23

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/26 17:50:58

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

2026/8/27 0:07:12

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

LeetCode Hot100(51-60)算法精解与面试技巧

LeetCode Hot100(51-60)算法精解与面试技巧

2026/8/27 0:07:12

1. 题目背景与核心价值"hot100(51-60)"这个标题看起来像是某个编程题库或算法练习集中的一组题目编号。在技术社区中,类似命名通常指向LeetCode、牛客网等平台的热门题目集合。作为刷过300题的算法老手,我理解这类题目的核心价值在于&#xff…

CRC校验实战:从模2除法到HJ212协议排错

CRC校验实战:从模2除法到HJ212协议排错

2026/8/27 0:07:12

1. 为什么一个“校验码”能扛住工业现场90%的数据 corruption? 你有没有遇到过这样的场景:嵌入式设备通过RS-485上传温湿度数据,上位机偶尔收到一帧乱码——温度显示成-273℃,湿度跳到999%,但串口波形看起来完全正常&a…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/26 18:07:30

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/26 17:57:52

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…