有赞电商移动代码 VCS 的演进

栏目: 编程工具 · 发布时间: 9年前

内容简介:有赞电商移动代码 VCS 的演进

我们有幸在一个毫无疑问以 git 作为 VCS 的开发时代,git 为我们提供了太多想象力,解放了我们许多的生产力。

有赞使用自搭 git 服务器的方式为所有的项目提供版本管理,而我们现在的产品——微商城/微小店/有赞买家版,都是基于我们的 git 仓库进行管理的。

开天辟地

随着公司规模和产品的发展,我们的仓库变得越来越大,feature 越来越多,2016 年我们团队在评估现有的代码之后,决定开始模块化的改造。

模块化首当其冲的就是对 VCS 的需求产生变化,一个看上去非常简单的 repo 可能已经不再满足我们的需求,因为我们需要不同的模块能足够产品化,能够进行独立维护,能够为我们的新需求提供强有力的支持,顺便还能帮我们快速定位到问题转到相关负责人的手中,这是我们的愿景。

我们为模块化做的第一件事(以 Android 为例),就是在当前的项目中,为不同的业务模块,新建好不同的文件夹(Project),把不同业务的代码,从一个巨大的代码库中,慢慢剥离开,一点一点的落地到相应的 Sub Project 里面,好让我们对各个业务的边界有明确的认识。

有赞电商移动代码 VCS 的演进

莱克星顿的第一声枪响

在这个时候,我们花了很大的时间完成这项工作,在第一阶段完成之后,看见清晰的目录结构不禁沾沾自喜,但是,挖坑的弊端接踵而至——首先,Gradle 编译的时间大大的加长了,一次编译完成的时间足够你去喝一杯热气腾腾的咖啡。每一次的产品迭代中,产品一个新需求,我们会使用 Git Flow 的标准新建一个新的 feature 分支,在 feature 分支下实现新需求,写完代码,等待编译,安装到手机上,自测,然后改 Bug,再循环。

没错,在没有 TDD,暂没办法进行自动化测试的条件下,我们活的非常艰难,实现业务很像是在浪费生命,我们的时间如此值钱,怎么能荒废在天书…啊呸, compile 里面?于是我们渴望把我们的生产力继续解放,不能为了头脑清楚而捆绑了手脚。

同时,我们的仓库在业务模块分支的开发中,分支表现的混乱不堪,经常需要一堆人聚在一块解决合并的时候模块的冲突的问题,现在这个样子,好像根本没有解决问题嘛。

巨大仓库的改造

我们这时候维护了一个非常巨大的仓库,每一次的分支提交,都有潜在的可能对对方造成影响。你可能在这个分支上“不小心”改了某一行别人分支的代码,这并不是符合预期的(unexpected),结果在合并代码的时候,就得问对方,这块是不是你改过的,我应该选择哪一

块的代码,这样的分支合并,在比较小的项目里,可能问题表现的不明显,因为就算变动,也是有限的几行代码,但是在代码数量级高许多的项目中,它就有可能是一种灾难了。我们这个时候希望把仓库拆出来,这样使用 VCS 去统一管理各个模块,而不是让他们都寄宿在一个大 repo 里。

在这之前,我们已经了解过 git submodules 的优缺点,如果使用 git submodules 进行改造的话,成本的确是非常小的,它的整个模型如下:

有赞电商移动代码 VCS 的演进

但是我们知道,git submodules 是在 父 repo 中维护一个对 submodules 的一些指针,如果子 module 代码发生了更改,除了父 module 提交代码外,还需要对子 module 的指针进行更新,这种 contains 的操作在我们的场景里,无疑对项目增加了许多的复杂性,经过一些综合的考虑,我们最终放弃了使用 submodules 的方式,使用 repo ( https://gerrit.googlesource.com/git-repo/)进行管理。

repo 的使用

首先,非常推荐微店的梁志涛在知乎上关于 【为什么android使用repo而不是直接使用git管理工程呢】的回答 ,感谢他的一些技术指导,给我们对 repo 和 git submoudle 的认知提高了好多个档次。

repo 的一些特性可以让你在没有插件化之前,就能用上它,用上它之后,我们现在的模型是这样的

app 壳工程和业务模块工程并行了,更新各个模块的代码再也不会对其他工程有影响。如果把业务模块转换成坐标依赖,我们还可以选择性地把需要的代码拉到本地,不需要的代码不用去动,连 compile 的时间都省了好多,我们的愿望有多么的美好,那么现实就会有多么的残酷。

首先,按照 Android 的目录结构来看,如果我们不进行较大的配置的话,我们许多的文件,必须放到外部工程的根目录下。

大概像这样

有赞电商移动代码 VCS 的演进

为了图中红色字文件的正确路径,我们一开始把这些文件打入了一个叫 wsc 的 repo 里,repo 下拉代码的时候,会在根目录下写入 wsc 这个 repo 里的所有的文件,且在根目录下面,继续加入其它模块,这样我们发现,其它模块又变成了 wsc 的子模块了,虽然没有 git submodule 恶心,但是整体的组织结构还是很奇怪,为了保证其它模块不被打入 wsc 仓库,我们只好在这个 repo 下面的 .gitignore 中,把其他模块的管理都去掉了。

.gitignore 如下:

# 省略其他

# 业务模块的 ignore
wsc_login
wsc_customer
wsc_shop
....

我们可以看到,gitignore 居然和业务耦合在了一块,也就是说,我再抽出一个业务,如果我忘了在 wsc 里面把这个业务文件夹 ignore 掉,就会被 push 到仓库里,这不和 git submodule 一样了么?我们使用 repo 不是就是要解决这样的问题么?

于是我们参考了 Android Source 提供的方案,看看它是怎么管理这种文件的。

有赞电商移动代码 VCS 的演进

我们可以看到,这里面有两个非常有用的指令就是 linkfile , copyfile ,给我的启发就是,我们可以创建一个包含构建文件的 repo,用这个 repo 去管理 Make 相关的逻辑,同时,repo 的颗粒度要足够小,让各个 repo 各司其职,这样 repo 之间的互相耦合就更小了,我们把这个 repo 取名为 gradle_files ,本来想取名叫 build ,但是可能会和 Gradle 生成出来的文件夹冲突,所以只好换了一个名字,名字解决后,我们整个文件夹的结构就是这样的:

有赞电商移动代码 VCS 的演进

带箭头的都是软连接。截图里没有把其他业务模块拉下来。如果我们需要更改业务代码,就把 app 下的 build.gradle 中改成 project 依赖,否则使用坐标依赖。

使用 repo 的出发点,就是为了我们后续的快速开发,模块代码级的分离,和更标准化的打包流程。

目前痛点

在现在这个阶段,我们暂时解决了模块间的版本管理问题和编译速度的问题,我们秉承一条原则:不要过度设计,不要一开始就想着完美,出发比思考更重要。

因此,正因为不完美,我们的整个解决方案还有许多的改进空间,目前的痛点还有如下:

  1. 打包系统功能暂不完整,离我们的设想还有一段距离。
  2. 模块的发布尚未标准化,我们目前依赖于清除本地 Gradle Cache 的方式,让开发中的代码进行更新。
  3. 打包和 Code Freeze 需要人工去介入。
  4. 对于 TDD 和 BDD,得益于模块的解耦,可以开始探索,但是尚未出成果。

总结

使用 repo 算是一种走出舒适区的尝试,我们热衷于把我们的基础设施建设得更加现代化和标准化,我们所做的一切,都期望我们自己能更专注于业务,把我们从痛苦的打包和版本管理中解放出来。幸好,一切都开始了,并没有踌躇不前,革命尚未成功,同志仍需努力。


以上所述就是小编给大家介绍的《有赞电商移动代码 VCS 的演进》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

白话区块链

白话区块链

蒋勇 / 文延、嘉文 / 机械工业出版社 / 2017-10-1 / 59.00

由浅入深:从比特币开始,到区块链技术的骨骼(密码算法)和灵魂(共识算法),再到目前知名的区块链框架介绍,到最后从零构建一个微型区块链系统(微链),循序渐进。 多图多表:各种示例以及图表,通过流程图与示意图介绍比特币的源码编译、以太坊智能合约的开发部署、超级账本Fabric的配置使用、模拟比特币的微型区块链系统的设计实现等,形象而直观。 白话通俗:通过“村民账本记账”、“百花村选举记账”......一起来看看 《白话区块链》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具