遗失的源代码之回归之路的探索与实践

背景

最近比较突然被安排接手一个项目,该项目的情况如下

  • 原生和RN结合的混合开发模式
  • 组件化开发,有很多基础组件以及业务组件

但是在梳理项目依赖时发现了个别组件源码不全的情况,于是写了个cli用于对比两个版本产物文件,生成差异结果以便于快速进行源码找回恢复。
结果如下:
找回前的对比:
在这里插入图片描述

找回后对比:

在这里插入图片描述


遗失的源代码

在梳理项目时,我发现几个比较核心的组件依赖的版本跟git源码仓库的tag和发布版本不一致。

我尼玛顿时惊出一身冷汗,怕不是有些代码没提交吧!

经过核实,的确是部分代码没提交,判断依据如下:

  • 以核心组件A举例说明,它在壳子依赖的版本是2.0.0,但是源码仓库里发布配置的版本是1.0.0,并且找不到2.0.0版本的tag。
  • 源码仓库最新分支的最后一次提交时间比在maven私有仓库中2.0.0版本产物上传的时间早
  • 壳子对该组件的依赖时间从1.0.0变更为2.0.0的时间跟2.0.0版本产物上传的时间一致

由此可以确认,1.0.0到2.0.0之间的代码变更是没有提交到git仓库的,但是产物是打包并上传到私有仓库里了,所以壳子可以正常依赖使用。

找出问题

出现这种问题的原因是我们的组件打包上传流程并没有规范化,而是大家约定了一个打包上传的规范如下:

  1. 先提交代码,并打对应版本tag
  2. 然后再执行gradle打包上传脚本将对应版本的aar或者jar上传到maven私有仓库

但是这种靠人为执行约定流程是不可控的,有时候开发图省事直接自己在项目中执行一个gradle打包上传脚本把产物上传到maven私有仓库,然后壳子工程就可以依赖使用了,但是本地代码忘记提交到git仓库,也不会去打tag,这样就导致了可能出现产物版本是最新的,但是仓库源码并非最新的情况。

解决问题
出现这个问题的根本原因在于没有一个规范的管理流程,解决这个问题也比较简单,就是把开发直接打包上传到maven的权限收回,把打包操作后置例如放到CI上执行。
大致流程如下:

  1. 提供一个入口例如网页,网页上把git仓库管理起来
  2. 需要打包就在网页上选择对应的git仓库,网页把打包相关的配置展示出来,点击确定按钮触发CI打包流程
  3. CI去对应的git仓库执行内部对应的打包上传脚本即可

由于CI是直接去git仓库拉代码打包的,这样就避免出现了代码没提交,但是产物能出来的问题了。
当然,实现这个打包管理的流程设计到前后端以及CI,整体的细节和工作量还是不少的,上面只是一个大致流程。

实际上如何管理打包流程都是后话了,当务之急是要把新版本的代码找回来。
在梳理的时候其实发现了一个更严重的问题是,当时的项目RN升级一个大版本,做法是基于RN的源码做了些修改然后重新打包成aar给壳子工程依赖的,但是,那个基于RN源码定制的git仓库都找不到了,也就是我要先基于RN的源码编译出产物,然后还要找回已有aar和RN源码编译出来的aar之间的代码变更。本来我对RN就不熟悉,又出了这一档子事情,这不是给我加难度吗…
在这里插入图片描述


回归之路的探索

上面也说到了,当务之急是先把源码给恢复好,因为后续还需要基于恢复后的代码继续开发迭代,经过沟通过后得知是不可能再找到之前的开发看看能不能把没提交的代码给提交一下了。

那就只剩下一条路,自己尝试着恢复,那怎么恢复呢?
先来梳理一下现有的东西。

  • git仓库里有旧版本的源码,RN的话github上找对应版本的源码即可,
  • 有新版本的aar文件

思路一

很自然的一个思路就是Android Studio不是能直接看到依赖产物的的代码吗?
例如在这里插入图片描述
那我直接找到对应的产物,跟源码文件一个一个进行内容对比不就可以了。
当然这样理论上是可以实现的,但实际落地下来很难执行,原因如下:

  • 在打包成产物后的源码进行处理过后的,一些注释啊,空格啊,变量名啊,代码的顺序啊都会有变更,AS上显示的产物里的代码是对已经处理过的源码编译后的class文件进行反编译显示,那这样一来,跟原本的源代码就会产生很大的差异。

以RN的源码举例说明,下面是在AS上看的RN源码中的一个类

在这里插入图片描述

再来看下实际的源码
在这里插入图片描述

可以明显的看出从代码行数以及变量名都有变化,这还是一个非常简单的类,这种我们可以肉眼对比出来,RN源码中负责的类有非常多,这种我们如果一个一个对比肉眼去看,那简直是个灾难。

到这里实际上肉眼比较的方案其实已经执行不下去了,原因如下:

  1. 对于源码数量非常多的组件,工作量巨大,因为我们要对比每一个文件还有资源文件,确保找出增,删,改的文件
  2. 人工去对比最终的结果质量无法保证,基本可以遇见的是花了一上午对比了几个文件后就开始心情烦躁,情绪波动,最后直接开摆,扫一眼没啥问题就过。

在这里插入图片描述
3. 心智负担巨大,这种明显是属于吃力也不讨好的方案,最后人家问你确定恢复的没有问题吗?你真的敢说没问题吗?

思路二

基于思路一我们来看一下有什么问题

  • 直接看产物反编译后的代码跟旧版本源码比较差异大,难以确定是否变更
  • 对于代码量多的组件,工作量大,人工对比效率太低
  • 靠人工判断无法保证最终结果的正确性
代码差异大的问题

对于查看反编译后的产物跟源码比较差异大的问题,想办法让他们俩尽量在状态比较一致的情况下再次对比。
我们可以把源码也打包编译成产物,然后对比两个版本产物反编译后的代码内容确定是否有变更。实际操作下来这种方式确实能够极大的减少代码差异大的情况

效率低的问题

上面也说到了,人工对比的心智负担比较大,例如RN源码有700多个类文件,一个一个对比下来先不说时间问题,准确度也没办法保证,毕竟,我们不能仅仅靠代码行数是否一致就去判断代码有没有变更。

准确度的问题

可以通过程序计算对比文件的md5值,给出最终的结果输出,保证最终还原的正确性

解决方案

可以做一个工具,把新老版本的产物丢进去,程序帮我们进行解压,遍历,反编译等操作,然后对反编译后的java文件进行md5值计算,最后输出结果,把md5值不同的文件输出出来,这样依赖,既可以保证每个文件都能对比到,还能确保最终的结果是稳定可靠的。

大致流程如下

  1. 将已有源码编译成产物aar
  2. 设计一个cli工具,用于处理两个版本的产物
  3. 对产物进行解压,先处理资源文件,计算文件的md5值
  4. 针对代码文件进行反编译,随后遍历反编译后的java文件,计算md5值
  5. 新老版本结果进行对比,找出增,删,改的文件
  6. 输出结果

回归之路的实践

确定好方案之后,就可以动手开发了,这里我选择是做一个cli工具。

初步实现

CLI工具可下载直接使用:下载地址 component-diff-1.0.0.jar
使用方式如下:

java -jar jar包路径 true --old 旧版本产物 --new新版本产物 --output 结果输出目录

参数说明

  • jar包路径:就是你下载的jar文件在你的电脑的绝对路径
  • true表示打印执行日志
  • --old后面跟你的旧版本的产物文件路径
  • --new 后面跟你的新版本的产物文件路径
  • --output 后面跟输出结果目录

示例:

java -jar /Users/yuzhiqiang/Documents/组件对比/component-diff-1.0.0.jar true --old //Users/yuzhiqiang/Documents/组件对比/rn_source/old/react-native-0.68.5.aar --new /Users/yuzhiqiang/Documents/组件对比/rn_source/new/react-native-0.68.513.aar --output /Users/yuzhiqiang/Documents/组件对比/r

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【lesson9】高并发内存池Page Cache层释放内存的实现

文章目录 Page Cache层释放内存的流程Page Cache层释放内存的实现 Page Cache层释放内存的流程 如果central cache释放回一个span,则依次寻找span的前后page id的没有在使用的空闲span,看是否可以合并,如果合并继续向前寻找。这样就可以将切…

05、全文检索 -- Solr -- Solr 全文检索之图形界面的文档管理(文档的添加、删除,如何通过关键字等参数查询文档)

目录 Solr 全文检索之文档管理添加文档使用 JSON 添加文档:使用 XML 添加文档: 删除文档使用 JSON 删除文档:使用 XML 删除文档: 查询文档查询文档的详细参数fq(Filter Query):过滤sort:排序sta…

[Linux 进程(六)] 写时拷贝 - 进程终止

文章目录 1、写时拷贝2、进程终止2.1 进程退出场景2.1.1 退出码2.1.2 错误码错误码 vs 退出码2.1.3 代码异常终止引入 2.2 进程常见退出方法2.2.1 exit函数2.2.2 _exit函数 本片我们主要来讲进程控制,讲之前我们先把写时拷贝理清,然后再开始讲进程控制。…

[office] 在Excel2010中设定某些单元格数据不参与排序的方法介绍 #其他#知识分享#笔记

在Excel2010中设定某些单元格数据不参与排序的方法介绍 在Excel中排序,相信大家都会了,直接将一组数据按照从小到大或者从大到小进行排序,但是,现在要求我们规定其中几组数据不进行排序,只排序其余的部分。又该如何操作…

ruoyi(若依)(el-menu也可参考)菜单栏过长显示省略号才显示气泡

一、背景 若依前后端分离的版本,新版本中优化了菜单名称过长悬停显示标题,但是是悬浮所有长度大于5的标题。可以查看提交记录:https://gitee.com/y_project/RuoYi-Cloud/commit/99932d91c0144da9f34f5bb05683cc0b86303217 但是我希望是只悬浮…

VC++中使用OpenCV绘制直线、矩形、圆和文字

VC中使用OpenCV绘制直线、矩形、圆和文字 在VC中使用OpenCV绘制直线、矩形、圆和文字非常简单,分别使用OpenCV中的line、rectangle、circle、putText这四个函数即可。具体可以参考OpenCV官方文档:https://docs.opencv.org/4.x/index.html 下面的代码展…

nodejs express中使用连接池或者MySQL链接数据库出现Cannot read property ‘query‘ of undefined报错

1.如果你已经排除了数据库的启动状态原因和本地服务是否启动的原因 2.不妨看看你是否没有排查其他的数据库,我就是一直在排查第一个主数据库,却忘了我还连接了第二个数据库,就是第二个数据库的原因,出现这个错误。 3.我们可以通…

「 CISSP学习笔记 」08. 安全运营

该知识领域涉及如下考点,具体内容分布于如下各个子章节: 理解并遵守调查执行记录和监控活动执行配置管理 (CM)(例如,预配、基线、自动化)应用基本的安全操作概念应用资源保护执行事故管理执行和维护检测和预防措施实施…

我们使用的IPv4耗尽(We‘re running out of IPv4)

IPv4(Internet Protocol version 4)是互联网上使用最广泛的网络层协议之一,于1981年在 RFC 791 中发布,它定义了 32 位的IP地址结构和基本的协议操作。 由于 IPv4 使用 32 位的地址,因此只有四十亿(4,294,967,296,2^32)个地址。 这就导致随着地址不断被分配,IPv4 地…

未来电话呼叫技术的社会影响与发展趋势----云微呼

未来电话呼叫技术将以更为智能化、便捷化和个性化为主要发展趋势,其所带来的社会影响也将是多层面的。以下将探讨未来电话呼叫技术可能的发展趋势以及对社会的影响: 智能化助力生活便捷: 未来电话呼叫技术将更加智能化,通过人工智…

uniapp 组件封装

1. uniapp 组件封装时间戳格式化为星期 1.1. components/m-week.vue <template><text>{{week}}</text> </template> <script>export default {props: {time: String},mounted(e) {this.week this.getWeek(Number(this.time))},data() {return …

车载测试Vector工具——基于DoIP的ECU/车辆的连接故障排除

车载测试Vector工具——基于DoIP的ECU/车辆的连接故障排除 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和…

【考研408】计算机网络笔记

文章目录 计算机网络体系结构计算机网络概述计算机网络的组成计算机网络的功能计算机网络的分类计算机网络的性能指标课后习题 计算机网络体系结构与参考模型计算机网络协议、接口、服务的概念ISO/OSI参考模型和TCP/IP模型课后习题 物理层通信基础基本概念奈奎斯特定理与香农定…

PyCharm / DataSpell 导入WSL2 解析器,实现GPU加速

PyCharm / DataSpell 导入WSL2 解析器的实现 Windows的解析器不好么&#xff1f;设置WSL2和实现GPU加速为PyCharm / DataSpell 设置WSL解析器设置Interpreter Windows的解析器不好么&#xff1f; Windows上的解析器的确很方便&#xff0c;也省去了我们很多的麻烦。但是WSL2的解…

cesium-水平测距

cesium测量两点间的距离 <template><div id"cesiumContainer" style"height: 100vh;"></div><div id"toolbar" style"position: fixed;top:20px;left:220px;"><el-breadcrumb><el-breadcrumb-item&…

React16源码: React中处理hydrate的核心流程源码实现

hydrate 1 &#xff09;概述 hydrate 在react当中不算特别重要, 但是很多时候会用到的一个API这个 API 它主要作用就是在进入第一次渲染的时候&#xff0c;如果本身 dom 树上面已经有一个dom结构存在是否可以去利用这一部分已经存在的dom&#xff0c;然后去避免掉在第一次渲染…

[晓理紫]CCF系列会议截稿时间订阅

关注{晓理紫|小李子}&#xff0c;每日更新CCF系列会议信息&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持&#xff01;&#xff01; 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新会议信息。 SAC (CCF C) Select…

物流平台架构设计与实践

随着电商行业的迅猛发展&#xff0c;物流行业也得到了极大的发展。从最初的传统物流到现在的智慧物流&#xff0c;物流技术和模式也在不断的更新与升级。物流平台作为连接电商和物流的重要媒介&#xff0c;其架构设计和实践显得尤为重要。 一、物流平台架构设计 1. 前端架构设…

京东广告算法架构体系建设--高性能计算方案最佳实践 | 京东零售广告技术团队

1、前言 推荐领域算法模型的在线推理是一个对高并发、高实时有较强要求的场景。算法最初是基于Wide & Deep相对简单的网络结构进行建模&#xff0c;容易满足高实时、高并发的推理性能要求。但随着广告模型效果优化进入深水区&#xff0c;基于Transformer用户行为序列和Att…