CocoaPods 历险记这个专题是 Edmond 和 冬瓜 共同撰写,对于 iOS / macOS 工程中版本管理工具 CocoaPods 的实现细节、原理、源码、实践与经验的分享记录,旨在帮助大家能够更加了解这个依赖管理工具,而不仅局限于
pod install
和pod update
。
本文知识目录
背景
CocoaPods
作为业界标准,各位 iOS 开发同学应该都不陌生。不过很多同学对 CocoaPods
的使用基本停留在 pod install
和 pod update
上。一旦项目组件化,各业务线逻辑拆分到独立的 Pod
中后,光了解几个简单 Pod
命令是无法满足需求的,同时还面临开发环境的一致性,Pod
命令执行中的各种异常错误,都要求我们对其有更深层的认知和 ????。
关于 CocoaPods
深入的文章有很多,推荐 ObjC China 的这篇,深入理解 CocoaPods[1],而本文希望从依赖管理工具的角度来谈谈 CocoaPods
的管理理念。
Version Control System (VCS)
Version control systems are a category of software tools that help a software team manage changes to source code over time. Version control software keeps track of every modification to the code in a special kind of database.
软件工程中,版本控制系统是敏捷开发的重要一环,为后续的持续集成提供了保障。Source Code Manager
(SCM) 源码管理就属于 VCS 的范围之中,熟知的工具有如 Git
。而 CocoaPods
这种针对各种语言所提供的 Package Manger (PM)
也可以看作是 SCM 的一种。
而像 Git
或 SVN
是针对项目的单个文件的进行版本控制,而 PM 则是以每个独立的 Package 作为最小的管理单元。包管理工具都是结合 SCM
来完成管理工作,对于被 PM 接管的依赖库的文件,通常会在 Git
的 .ignore
文件中选择忽略它们。
例如:在 Node
项目中一般会把 node_modules
目录下的文件 ignore 掉,在 iOS / macOS 项目则是 Pods
。
Git Submodule
Git submodules allow you to keep a git repository as a subdirectory of another git repository. Git submodules are simply a reference to another repository at a particular snapshot in time. Git submodules enable a Git repository to incorporate and track version history of external code.
Git Submodules
可以算是 PM 的“青春版”,它将单独的 git 仓库以子目录的形式嵌入在工作目录中。它不具备 PM 工具所特有的语义化版本[2]管理、无法处理依赖共享与冲突等。只能保存每个依赖仓库的文件状态。
Git
在提交更新时,会对所有文件制作一个快照并将其存在数据库中。Git 管理的文件存在 3 种状态:
working director: 工作目录,即我们肉眼可见的文件
stage area: 暂存区 (或称
index area
),存在.git/index
目录下,保存的是执行git add
相关命令后从工作目录添加的文件。commit history: 提交历史,存在
.git/
目录下,到这个状态的文件改动算是入库成功,基本不会丢失了。
Git submodule 是依赖 .gitmodules
文件来记录子模块的。
[submodule "ReactNative"]
path = ReactNative
url = https://github.com/facebook/ReactNative.git
.gitmodules
仅记录了 path 和 url 以及模块名称的基本信息, 但是我们还需要记录每个 Submodule Repo 的 commit 信息,而这 commit 信息是记录在 .git/modules
目录下。同时被添加到 .gitmodules
中的 path 也会被 git 直接 ignore 掉。
Package Manger
作为 Git Submodule 的强化版,PM 基本都具备了语义化的版本检查能力,依赖递归查找,依赖冲突解决,以及针对具体依赖的构建能力和二进制包等。简单对比如下:
Key File | Git submodule | CocoaPods | SPM | npm |
---|---|---|---|---|
描述文件 | .gitmodules | Podfile | Package.swift | Package.json |
锁存文件 | .git/modules | Pod |