行业焦点
自动删除旧代码?Uber 开源利器“食人鱼”
浏览量:11339
整理代码是一件艺术,对于一些过时的陈旧代码,如何优雅又快速地删除,是一件让无数人伤神的事情,但在最近, Uber 给出了一种解决的方案。
近日,Uber 推出了一款可以扫描源代码并删除过时代码的工具,形象地命名为 了 Piranha(食人鱼)。
Piranha 可以在 Uber 的 Android 和 iOS 代码库中运行,目前支持 Objective-C、Swift 和 Java 三种编程语言。
功能标志引发的陈旧代码之痛
Piranha 删除过时代码,究竟是如何实现的呢?这还要从 Uber 代码的一个标准说起。
为了方便系统的更新的开发,Uber 采用了功能标志(Feature Flag),也称为功能切换,这是一种允许控制线上功能开启或关闭的方法,在互联网大厂中被广泛采用。
使用这个方式拥有诸多优点,它可以将新功能测试完善之后,再将其发布为全面可用,还能够针对不同用户定制差异化服务(A/B 测试),当出现 Bug 时支持回滚,工程师还可以远程禁用应用程序的故障部分。
据介绍,在 Uber 所有的程序代码库中,就有超过 6000 个功能标志。
但功能标志的增多,也会导致代码库的复杂性增加,一旦该标志过时,则需要将其删除,否则会带来技术层面的负担。
过时的标志会造成编程负担
但这个看似简单的清理步骤,往往会被很多开发者忽略,进而在代码容量、测试周期等多个维度上影响软件的开发。
为了解决这个问题,Uber 设计并推出了代码优化工具 Piranha。它可以分析并找出过时的代码标志,将可删除的部分反馈给原作者,配合其他的工具进行处理或删除。
用 Piranha 自动检测并删除
具体来说,Piranha 需要自动检测出过时标志,并删除其关联代码,这个过程的难点在于,要确定标志是否被人使用,以及该标志的所有者,并且要了解代码的具体细节。
考虑到 Piranha 的应用背景,Uber 采用了应用静态分析,即通过代码审查,来查找因过时标志遗留下来的废旧代码。
其中可清理的三个关键维度分别是:
删除紧邻功能标志 API 的代码。
删除由于执行上一步而无法访问的代码,称为深度清洁。
删除与功能标志有关的测试代码。
其中的关键在于,根据在代码库中观察到的编码模式,选择了迭代设计技术的实用方法,以观察和锁定三种标志 API:
返回布尔值的布尔型 API ,用于确定执行所采用的控制路径。
更新 API ,用于更新正在运行的系统中的功能标志值。
返回非布尔值原始值(整数、双精度等)的参数 API 。
通过重构技术解析输入源代码的 AST(抽象语法树),以检测使用功能标志 API 的存在。
如果标记注释与输入处理行为匹配,只需删除测试的注释,如果不匹配,则要丢弃整个测试以处理标记注释测试。
通过这套方案的实施,能够从代码中找出过时的功能标志,并进行删除或者重构。
这个方法在 Uber 的代码库中被证明是广泛有效的,已经用来删除了 2000 多个功能标志及相关的代码。
Piranha 已经在 Objective-C、Swift 和 Java 程序中运行良好,但为了让其工作更高效,以实现 Piranha 自动进行标志清除,还需要搭建一个更完善的系统。
于是 Uber 建立了工作流 pipeline,该 pipeline 可定期生成差异和任务,以清除陈旧的功能标志。
Piranha pipeline 在标志管理系统中,自动查询陈旧标志列表,并对每个标志,通过输入陈旧标志的名称、其所有人以及预期的输出行为(处理或控制),以启动 Piranha。
经过算法分析和处理之后,Piranha 生成一个 diff (即拉取请求),并将其放入代码审阅系统中,该标志的原始作者为默认审阅者。
作者可以接受 diff ,或者根据需要对其进行修改,也可以拒绝修改并将该标志标记为未过期。pipeline 还在任务管理系统中生成了一个清理任务,以跟踪每个生成 diff 的状态。
此外,系统该配备了提醒机器人 PiranhaTidy,可定期添加打开 Piranha 相关任务的提醒。目前使用 Piranha 自动生成 diff 的时间不超过 3 分钟。
通过这一系列的操作,即可轻松实现对代码的审阅和处理,将过时的代码一网打尽。
删除旧代码,就用食人鱼吧
当然,在上述的介绍中可知,要使用 Piranha,代码需满足以下条件:
广泛使用功能标志;
具有特定的 API 以控制功能标志的行为;
代码用 Java、Swift 或 Objective-C 实现;
此外,Piranha 还有一些计划正在进行中,比如改进 Piranha 产生的重构代码,扩充 Piranha 以支援 Kotlin 和 Go 等其他语言。
目前项目已经开源,可在以下地址获取,你想要试试吗?