Gradle 8.5中如何以配置缓存兼容方式转换Exec输出
解决Gradle 8.5中Git标签版本提取+配置缓存兼容问题
核心问题拆解
你现在用Gradle的providers.exec执行git describe --tags生成Android版本名,但输出带一堆附加内容(比如1.0.0-foo-bar-20230101-ea32549d),只想要1.0.0这部分。而且Git提交后输出变了会导致配置缓存失效,还要兼顾Windows系统的兼容性。
最优解决方案(跨平台+缓存友好)
直接用Gradle的Provider API在内部处理字符串,不用依赖外部shell工具,完美适配多系统,还能让配置缓存正常工作。
示例代码
// 先拿到最近的纯标签(不带提交哈希),再提取主版本号 def gitBaseVersion = providers.exec { commandLine 'git', 'describe', '--tags', '--abbrev=0' }.standardOutput.asText.map { rawOutput -> // 去掉换行,按-或+分割取第一部分,再去掉可能的v前缀 rawOutput.trim().split(/[-+]/)[0].replaceFirst(/^v/, '') } // 把提取到的版本号应用到Android配置 android { defaultConfig { versionName gitBaseVersion.get() } }
关键细节说明
--abbrev=0的作用:让Git直接返回最近的标签名,不会带后面的提交哈希和附加信息,减少后续处理的麻烦。map操作的优势:完全在Gradle的Provider链里做字符串转换,没有外部依赖,跨Windows/Linux/macOS都能用。而且Gradle配置缓存会把这个转换当成纯计算,只有当git describe --tags --abbrev=0的输出真的变了(比如打了新标签),才会更新缓存,不会因为普通Git提交就失效。- 处理标签前缀:如果你的标签习惯加
v前缀(比如v1.0.0),replaceFirst(/^v/, '')会自动去掉,不影响纯版本号提取;如果没有前缀,这一步也不会破坏结果。
为什么不用其他方案
- shell脚本+sed:Windows上没法直接用,而且调用外部进程会让Gradle配置缓存没法正确追踪依赖,更容易失效。
- 只加
--abbrev=0:只能去掉哈希,对付不了标签本身带的附加部分(比如1.0.0-foo这种标签)。
内容的提问来源于stack exchange,提问作者mreichelt
相关产品推荐
相关产品推荐

