最近比较突然被安排接手一个项目,该项目的情况如下
但是在梳理项目依赖时发现了个别组件源码不全的情况,于是写了个cli用于对比两个版本产物文件,生成差异结果以便于快速进行源码找回恢复。
结果如下:
找回前的对比:
找回后对比:
在梳理项目时,我发现几个比较核心的组件依赖的版本跟git源码仓库的tag和发布版本不一致。
我尼玛顿时惊出一身冷汗,怕不是有些代码没提交吧!
经过核实,的确是部分代码没提交,判断依据如下:
由此可以确认,1.0.0到2.0.0之间的代码变更是没有提交到git仓库的,但是产物是打包并上传到私有仓库里了,所以壳子可以正常依赖使用。
找出问题
出现这种问题的原因是我们的组件打包上传流程并没有规范化,而是大家约定了一个打包上传的规范如下:
但是这种靠人为执行约定流程是不可控的,有时候开发图省事直接自己在项目中执行一个gradle打包上传脚本把产物上传到maven私有仓库,然后壳子工程就可以依赖使用了,但是本地代码忘记提交到git仓库,也不会去打tag,这样就导致了可能出现产物版本是最新的,但是仓库源码并非最新的情况。
解决问题
出现这个问题的根本原因在于没有一个规范的管理流程,解决这个问题也比较简单,就是把开发直接打包上传到maven的权限收回,把打包操作后置例如放到CI上执行。
大致流程如下:
由于CI是直接去git仓库拉代码打包的,这样就避免出现了代码没提交,但是产物能出来的问题了。
当然,实现这个打包管理的流程设计到前后端以及CI,整体的细节和工作量还是不少的,上面只是一个大致流程。
实际上如何管理打包流程都是后话了,当务之急是要把新版本的代码找回来。
在梳理的时候其实发现了一个更严重的问题是,当时的项目RN升级一个大版本,做法是基于RN的源码做了些修改然后重新打包成aar给壳子工程依赖的,但是,那个基于RN源码定制的git仓库都找不到了,也就是我要先基于RN的源码编译出产物,然后还要找回已有aar和RN源码编译出来的aar之间的代码变更。本来我对RN就不熟悉,又出了这一档子事情,这不是给我加难度吗…
上面也说到了,当务之急是先把源码给恢复好,因为后续还需要基于恢复后的代码继续开发迭代,经过沟通过后得知是不可能再找到之前的开发看看能不能把没提交的代码给提交一下了。
那就只剩下一条路,自己尝试着恢复,那怎么恢复呢?
先来梳理一下现有的东西。
很自然的一个思路就是Android Studio不是能直接看到依赖产物的的代码吗?
例如
那我直接找到对应的产物,跟源码文件一个一个进行内容对比不就可以了。
当然这样理论上是可以实现的,但实际落地下来很难执行,原因如下:
以RN的源码举例说明,下面是在AS上看的RN源码中的一个类
可以明显的看出从代码行数以及变量名都有变化,这还是一个非常简单的类,这种我们可以肉眼对比出来,RN源码中负责的类有非常多,这种我们如果一个一个对比肉眼去看,那简直是个灾难。
到这里实际上肉眼比较的方案其实已经执行不下去了,原因如下:
3. 心智负担巨大,这种明显是属于吃力也不讨好的方案,最后人家问你确定恢复的没有问题吗?你真的敢说没问题吗?
基于思路一我们来看一下有什么问题
对于查看反编译后的产物跟源码比较差异大的问题,想办法让他们俩尽量在状态比较一致的情况下再次对比。
我们可以把源码也打包编译成产物,然后对比两个版本产物反编译后的代码内容确定是否有变更。实际操作下来这种方式确实能够极大的减少代码差异大的情况
上面也说到了,人工对比的心智负担比较大,例如RN源码有700多个类文件,一个一个对比下来先不说时间问题,准确度也没办法保证,毕竟,我们不能仅仅靠代码行数是否一致就去判断代码有没有变更。
可以通过程序计算对比文件的md5值,给出最终的结果输出,保证最终还原的正确性
可以做一个工具,把新老版本的产物丢进去,程序帮我们进行解压,遍历,反编译等操作,然后对反编译后的java文件进行md5值计算,最后输出结果,把md5值不同的文件输出出来,这样依赖,既可以保证每个文件都能对比到,还能确保最终的结果是稳定可靠的。
大致流程如下
确定好方案之后,就可以动手开发了,这里我选择是做一个cli工具。
CLI工具可下载直接使用:下载地址 component-diff-1.0.0.jar
使用方式如下:
java -jar jar包路径 true --old 旧版本产物 --new新版本产物 --output 结果输出目录
参数说明
--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