所有文章已搬遷到個(gè)人站點(diǎn):me.harley-xk.studio憎蛤,歡迎訪問留言
原由
最近跟著公司大佬在做 Laravel 后端開發(fā)果善,要求使用 php lint 進(jìn)行代碼規(guī)范檢查之后才能 push 代碼踪旷,保證所有人寫出風(fēng)格統(tǒng)一的代碼逞盆,方便后期的維護(hù)和 Review刊懈,于是開始往老本行上反思绿饵。
想想自己寫了五六年的 iOS 刀森,雖然自認(rèn)代碼還是寫的很規(guī)整的踱启,但是寫 high 了之后還是會(huì)忽略很多細(xì)節(jié)上的東西,雖說無傷大雅研底,但是軟件開發(fā)作為一門工程性質(zhì)的東東埠偿,始終覺得規(guī)范化是一件很重要的事情。
在之前的公司也曾經(jīng)在 iOS 組內(nèi)部推行過代碼規(guī)范的實(shí)施榜晦,但那時(shí)候還只是停留在弄個(gè) Word 文檔冠蒋,把各條規(guī)范列一列,然后開個(gè)小會(huì)普及下的程度上∏海現(xiàn)在接觸了不少其他開發(fā)領(lǐng)域的東西抖剿,越來越覺得對(duì)于開發(fā)者來說提高視角去了解各個(gè)方面是多么重要的一件事情。不同領(lǐng)域的經(jīng)驗(yàn)识窿、做事的方式斩郎、思路,都可以相互借鑒與融合喻频。
于是開始尋找在 iOS 下實(shí)行類似方案的可能性缩宜。說來也巧,最近在看 iOS 相關(guān)資料的時(shí)候發(fā)現(xiàn)了 SwiftLint 這玩意兒,遂打算來實(shí)踐下锻煌。
SwiftLint 是啥妓布?
SwiftLint 是 Realm 推出的一款 Swift 代碼規(guī)范檢查工具,Realm 就不用介紹了宋梧,他們家推出的移動(dòng)端跨平臺(tái)數(shù)據(jù)庫在業(yè)內(nèi)的名氣還是很大的匣沼,就算沒有用過,相信大多數(shù)人也是聽過的捂龄。
SwiftLint 基于 Github 公布的 Swift 代碼規(guī)范進(jìn)行代碼檢查释涛,并且能夠很好的和 Xcode 整合。配置好所有的設(shè)置之后倦沧,在 Xcode 中執(zhí)行編譯時(shí)枢贿,SwiftLint 會(huì)自動(dòng)運(yùn)行檢查,不符合規(guī)范的代碼會(huì)通過警告或者 error 的形式指示出來刀脏,并且擁有豐富的配置項(xiàng),可以進(jìn)行大量的自定義超凳,相當(dāng)方便愈污。
安裝配置
SwiftLint 有多種不同的安裝方式,可以根據(jù)自己的喜好選擇轮傍。
使用 Homebrew 安裝
Homebrew 是 macOS 自帶的包管理工具暂雹,使用這種方式安裝也是最簡單的:
brew install swiftlint
使用 CocoaPods 安裝
通過 CocoaPods 安裝同樣很簡單,只需要在 Podfile 中添加依賴:
pod 'SwiftLint'
之后執(zhí)行 pod install
就可以自動(dòng)安裝了创夜,這種方式會(huì)將 SwiftLint 安裝到項(xiàng)目的 Pods/
目錄下杭跪。如果你想要針對(duì)不同的項(xiàng)目使用不同的 SwiftLint 版本,這是一種很好的解決方案(Homebrew 會(huì)自動(dòng)安裝最新版本)驰吓。
需要注意的是使用這種方案會(huì)將整個(gè) ** SwiftLint** 以及他的依賴包的完整資源文件都安裝到 Pods/
目錄中去涧尿,所以在使用版本管理工具比如 git
時(shí)要注意設(shè)置忽略相關(guān)目錄。
使用安裝包
SwiftLint 還支持使用 pkg
安裝包進(jìn)行安裝檬贰,在官方的 Github 頁面可以找到最新發(fā)布的安裝包姑廉。
編譯源代碼
SwiftLint 完全使用 Swift 開發(fā),并且它是基于 MIT License 開源的翁涤,所以你可以下載它的源代碼桥言,然后通過以下命令編譯安裝:
git submodule update --init --recursive; make install
安裝完成
等待安裝完成,輸入 swiftlint help
可以查看所有可用的命令:
? ~ swiftlint help
Available commands:
autocorrect Automatically correct warnings and errors
help Display general or command-specific help
lint Print lint warnings and errors (default command)
rules Display the list of rules and their identifiers
version Display the current version of SwiftLint
到此 SwiftLint 就安裝完成了
配置 Xcode
接下來需要在工程中配置相關(guān)編譯選項(xiàng)葵礼,才能使 SwiftLint 在 Xcode 中運(yùn)行起來号阿。配置也很簡單,只需要在 Xcode 的 Build Phases
中新建一個(gè) Run Script Phase
配置項(xiàng)鸳粉,在里面添加如下代碼:
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
如圖所示:
[圖片上傳失敗...(image-933261-1580636760609)]
如果是通過 CocoaPods 安裝的 SwiftLint 需要將 swiftlint
替換為 CocoaPods 中的路徑: "${PODS_ROOT}/SwiftLint/swiftlint"
扔涧。
這里其實(shí)是設(shè)置了一個(gè)自動(dòng)編譯腳本,每次運(yùn)行編譯都會(huì)自動(dòng)執(zhí)行這個(gè)腳本赁严,如果正確安裝了 SwiftLint扰柠,就會(huì)執(zhí)行 SwiftLint 中的代碼規(guī)范檢查粉铐,如果沒有安裝,腳本會(huì)拋出一個(gè)沒有安裝 SwiftLint 并提示下載的警告卤档,方便提醒團(tuán)隊(duì)團(tuán)隊(duì)中沒有安裝的成員蝙泼。
當(dāng)然,你也可以設(shè)置為強(qiáng)制要求安裝劝枣,這時(shí)如果沒有安裝則無法通過編譯汤踏。只需要在腳本中 echo "warning: ..."
之后添加一行代碼:exit 1
,這樣一來舔腾,如果沒有安裝 SwiftLint溪胶,編譯時(shí)會(huì)直接拋出一個(gè)編譯錯(cuò)誤而非警告,提示需要安裝 SwiftLint稳诚。
到此配置就完成了哗脖,是不是很簡單。
自定義配置
現(xiàn)在編譯一下項(xiàng)目看看扳还,是不是很可怕??:
不要被 999+ 嚇到了才避,仔細(xì)看一下具體的錯(cuò)誤,會(huì)發(fā)現(xiàn)好多都是第三方庫的代碼規(guī)范問題氨距,而且好多問題的級(jí)別被設(shè)置成為了 error
這樣子可不行桑逝,第三方庫的代碼規(guī)范問題不能讓我們自己的項(xiàng)目來背鍋,接下來需要做一些配置俏让,讓 SwiftLint 在做代碼規(guī)范檢查的時(shí)候自動(dòng)忽略 CocoaPods楞遏、Carthage 等包管理器引入的第三方庫(當(dāng)然,手動(dòng)導(dǎo)入的第三方庫也能設(shè)置忽略)
首先需要在項(xiàng)目的根目錄下新建一個(gè)名為 .swiftlint.yml
的配置文件首昔,輸入如下內(nèi)容:
excluded:
- Pods
excluded
配置項(xiàng)用來設(shè)置忽略代碼規(guī)范檢查的路徑寡喝,可以指定整個(gè)文件夾,也可以指定精確路徑下的文件沙廉,通過 - xxxx
的形式列在下面就可以了拘荡,比如如果你的項(xiàng)目使用 Carthage 管理第三方庫的話,可以將 Carthage
目錄添加到忽略列表:
excluded:
- Pods
- Carthage
保存之后再來編譯下撬陵,少了很多編譯錯(cuò)誤了珊皿,至少第三方庫的編譯錯(cuò)誤都被干掉了,oh yeah~
不過錯(cuò)誤和警告依然很多巨税,繼續(xù)往下看蟋定,發(fā)現(xiàn)大量的
trailing_whitespace
的警告,這個(gè)是之前寫代碼不注意留下的草添,在空行中包含了空格驶兜,雖然肉眼看不出來,但是 SwiftLint 火眼金睛啊。你可以選擇更正所有這些不規(guī)范的問題抄淑,不過如果這個(gè)這個(gè)項(xiàng)目是遺留下來的老項(xiàng)目屠凶,可能存在大量類似的問題,手動(dòng)更正這些問題需要相當(dāng)多的精力肆资,這時(shí)候可以選擇開啟忽略這類問題矗愧,只需要在
.swiftlint.yml
文件中加入如下代碼:
disabled_rules:
- trailing_whitespace
再次編譯,發(fā)現(xiàn) trailing_whitespace
的問題已經(jīng)不再提示了郑原,你可以用同樣的方法配置忽略特定的規(guī)則唉韭。
其他規(guī)則
Xcode自動(dòng)生成的代碼經(jīng)常包含大段的注視,我們經(jīng)常會(huì)選擇保留這些注釋犯犁。不過 SwiftLint 有一個(gè) line_length
的規(guī)則属愤,默認(rèn)是會(huì)檢查注釋的長度的,可以在 .swiftlint.yml
中設(shè)置忽略檢查注釋的長度:
line_length:
warning: 110
ignores_function_declarations: true
ignores_comments: true
這段代碼設(shè)置了 line_length
的檢查規(guī)則:
warning: 110
表示單行字符數(shù)超過 110 時(shí)拋出警告酸役,你也可以設(shè)置為其他的值住诸。
ignores_function_declarations
表示是否忽略檢查函數(shù)定義的長度
ignores_comments
設(shè)置是否忽略檢查注釋的長度
當(dāng)然,你也可以在 disabled_rules
中設(shè)置忽略單行長度規(guī)則
這里有所有目前已經(jīng)實(shí)現(xiàn)了的規(guī)則涣澡。你也可以實(shí)現(xiàn)自己的規(guī)則只壳,然后給他們發(fā) Pull requests。
本文的最后附上了我自己的 .swiftlint.yml
文件暑塑,你可以在 SwiftLint 的官方文檔找到更多關(guān)于自定義規(guī)則的說明。
設(shè)置完所有配置之后锅必,再次編譯代碼事格,之后就可以根據(jù)錯(cuò)誤提示去更正不規(guī)范的代碼了。
.swiftlint.yml
的嵌套
.swiftlint.yml
配置文件支持嵌套搞隐,因此
- 你可以給每個(gè)文件夾下的代碼單獨(dú)指定不同的規(guī)則設(shè)置
- 每個(gè)文件會(huì)匹配距離自己層級(jí)最近的父文件夾中的配置文件
- 嵌套的配置文件中的
excluded
和included
配置會(huì)被忽略
結(jié)語
終于寫完了第一篇技術(shù)博客驹愚,深感寫文章的不易,希望能保持下去劣纲。
這篇文章是我在初步研究了 SwiftLint 之后寫的逢捺,一定有很多謬誤和不足之處,各位輕噴- -
<a name="SwiftLint">.swiftlint.yml
</a>
disabled_rules: # rule identifiers to exclude from running
- force_cast
- trailing_whitespace
- cyclomatic_complexity
- unused_closure_parameter
# - colon
# - comma
# - control_statement
# opt_in_rules: # some rules are only opt-in
# - empty_count
# - missing_docs
# # Find all the available rules by running:
# # swiftlint rules
# included: # paths to include during linting. `--path` is ignored if present.
# - Docs.M/*/*.swift
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Carthage
- Pods
# - Source/ExcludedFolder
# - Source/ExcludedFile.swift
# configurable rules can be customized from this configuration file
# binary rules can set their severity level
# force_cast: warning # implicitly
force_try:
severity: warning # explicitly
# rules that have both warning and error levels, can set just the warning level
# implicitly
line_length:
warning: 200
ignores_function_declarations: true
ignores_comments: true
# they can set both implicitly with an array
type_body_length:
- 300 # warning
- 400 # error
# or they can set both explicitly
file_length:
warning: 500
error: 1200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
# type_name:
# min_length: 4 # only warning
# max_length: # warning and error
# warning: 40
# error: 50
# excluded: iPhone # excluded via string
identifier_name:
min_length: # only min_length
error: 3 # only error
excluded: # excluded via string array
- id
# - URL
# - GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji)