代码规范那点事

最近这个月,从制作 CocoaPods 私有库,到搭建 Git 服务器,大多数时间都花在了调研和试错上。不过调研试错这个事总是能让你感觉到自己懂的只是皮毛这个事实(所以当你觉得天下无敌的时候那就去调研,TA 会让你爆棚的自信心损失殆尽 💔💔)。以下文字就先记录下关于团队统一代码风格这件事。

正文

对于团队统一代码风格的好处想必大家都应该清楚,以下我就罗列几点相对比较重要的:

  1. 促进团队合作,提高代码的可读性;
  2. 有助于 Code Review ;
  3. 甚至可以降低 Bug 出现的概率;
  4. 自行 YY .....;

代码规范想必有部分同学会把它和个人习惯混为一谈,其实代码规范和个人习惯压根不是一个层面上的东西。代码规范针对的是团队,而个人习惯仅仅针对你自己。制定代码规范的目的是为了提高团队协作的效率以及代码的可维护性。因此,个人习惯和代码规范擦出火花的时候,很明显你应该遵守规范而不是你自己所谓的那些习惯。当然规范并不是一尘不变的,当产生火花的时候完全可以提议修改代码规范,但是在规范修改之前,你必须要遵守旧的规范。因为团队利益大于一切。

举个栗子,
A 习惯写 single line 的条件语句。

if (a) return;     

而 B 自己的习惯是这样,并且 B 还会使用一些格式化代码(Xcode 的 clang-format,js 的 jsFormat 等)的插件来提升开发效率。

if (a) {
    return ;
}   

那么当 B 去修改 A 的代码时,看着不顺眼,就会把 A 的所有 single line 都消灭掉,因为 B 有插件,秒秒钟解决战斗。这就会导致 A 和 B 冲突的概率大大增加,甚至会造成很多不必要代码合并的成本。想必大家看完这个栗子应该很清楚一个团队制定代码规范的重要性了。

一个团队的代码规范首先需要制定一份文档,当出现任何风格冲突的时候,以文档为准。因此团队在开始之初就制定了一份规范

制定规范文档这是第一步,在这个基础上能不能再提高些效率呢?
大多数 iOS 开发者应该都知道 Xcode 的插件 Clang Format。它是基于 clang-format 命令行工具的一个 Xcode 插件。

clang-format是基于clang的一个命令行工具。这个工具能够自动化格式C/C++/Obj-C代码,支持多种代码风格:Google, Chromium, LLVM, Mozilla, WebKit,也支持自定义风格(通过编写.clang-format文件)。

我们可以通过自定义 .clang-format 文件来实现自定义代码风格。这是目前使用的一份配置文件。具体每项参数可以查阅这份文档

通过这个插件已经可以实现通过快捷键或者在文件保存时格式化代码了,其实做到这一步已经节省了很多开发成本,但是这种方案也是存在一定缺陷。如果通过快捷键去格式化,容易遗漏;保存的时候去格式化,对于像我这样时不时会按 Command + S 的人来说,Xcode 会变得稍显卡顿。那么有没有现成的方案可以进一步优化体验?既然之前的方案有问题,就有必要继续寻找更优解。

一轮 Google 之后,spacecommander 貌似符合大部分需求。它利用 Git Hooks 可以在 commit 之前验证代码风格符合规范,只有符合规范的代码才允许提交,同时也提供 Shell 脚本来格式化一个文件,或者一整个 Git 仓库。我猜想通过 spacecommander ,可以在不改变自己编码风格(当然只限于格式,具体的命名规范,注释规范还得参照具体规范文档)的前题下,可以实现代码风格统一。因为你开发过程中可以按照个人习惯来,commit 之前使用 spacecommander 提供的脚本对文件进行格式化。这样只需要所有开发人员统一 spacecommander 的 .clangformat 配置文件就可以了。看到这里是不是发现这个轮子是不是刚好命中痛点。那么接下来我就简单描述下使用步骤:

  1. fork spacecommander
  2. 修改其中的 .clangformat 文件以满足自己团队的编码风格,当然有能力也可以修改其中的 Shell 脚本,自定义一些功能;
  3. clone 到本地一个较为安全的目录(别一不小心删掉了...);
  4. 为了之后方便使用,可以把几个脚本对应设置一个 alias;
  5. cd 到项目根目录,执行 clangformatinit ,进行初始化(添加了一个指向本地 spacecommander 仓库的 .clangformat 替身以及在 .git/hooks 中的 pre-commit, hook 相关的可以参见 Pro Git
  6. 在提交代码之前,spacecommander 都会通过 pre-commit 这个 Hook 来校验修改过的文件,校验通过才允许提交。

如何设置 alias 简化命令

// 使用zsh 则修改 ~/.zshrc;bash 则修改~/.bash_profile
// 初始化
alias clangformatinit="/Users/SpaceCommander_iOS/setup-repo.sh"
// 格式化对应文件
alias clangformat="/Users/SpaceCommander_iOS/format-objc-file.sh"
// 格式化整个仓库
alias clangformatall="/Users/SpaceCommander_iOS/format-objc-files-in-repo.sh    

如果需要 spacecommander 忽略某个目录下的文件的格式,则可以通过修改 spacecommander/lib/common-lib.sh 脚本来实现。默认它已经忽略了 Pods 和 Carthage 目录。

// common-lib.sh 简化版

function objc_files_to_format() {
    optional_base_sha="$1"
    directories_to_check
    files=$(git diff --cached --name-only $optional_base_sha --diff-filter=ACM -- $locations_to_diff | grep -e '\.m$' -e '\.mm$' -e '\.h$' -e '\.hh$')
    directories_to_ignore
    echo "$files" | grep -v 'Pods/' | grep -v 'Carthage/' >&1
}
 
function all_valid_objc_files_in_repo() {
    directories_to_check
    files=$(git ls-tree --name-only --full-tree -r HEAD -- $locations_to_diff | grep -e '\.m$' -e '\.mm$' -e '\.h$' -e '\.hh$')
    directories_to_ignore
    echo "$files" | grep -v 'Pods/' | grep -v 'Carthage/' >&1
}    

就此初步解决了 iOS 开发的代码风格问题 ———— 一份代码规范以及自定义的 spacecommander。

小结

这个问题看似有点微不足道,但的确花了毛一天的时间,才找到了较为合适的解决方案。但是在我看来是很值的。不仅能减少后续开发维护过程中由于代码风格引起的麻烦(感谢 spacecommander 这个轮子),而且在调研的过程中,也接触到了一些新的知识,比如 Shell 脚本语言。所以我很喜欢去干这种事情 🙄🙄。 接下来有时间会整理一篇 CocoaPods 私有库相关的博客 ⛳️⛳️。

有其它的解决方案,欢迎分享 🖐🖐

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 23,798评论 8 183
  • 今天老婆给我分享了一篇文章,说的是31岁的生性活泼开朗的妻子怀抱两个幼儿跳楼自杀了。 看完之后我觉得真是不可思议,...
    Cplusplus墨水阅读 705评论 0 0
  • 简介 一个叫嫣然月的女孩儿在茫茫的黑夜中被一辆像是被安排过的车撞了,不幸的是她成了植...
    有辞而别阅读 165评论 0 0
  • 大一时候胖胖的女老师在讲台上看着我们说, 哎,整天写这种什么数据得到什么结论的东西,整个人也变得干巴巴的不会说好听...
    雪琪呀阅读 221评论 0 0