SwiftLine的使用分為 編譯期間 和 代碼提交期間
1. SwiftLine的安裝使用 - 編譯期間的使用
全局安裝
全局安裝非常簡單,首先我們需要通過brew命令安裝SwiftLint:
brew install swiftlint
然后添加編譯腳本:

最后在黑框框中添加如下腳本:
if which swiftlint >/dev/null; then
swiftlint
#echo "skip"
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
大功告成,就可以編譯啦,之后每次安裝只需要給工程添加腳本就可以了。
局部安裝
除了全局安裝,我們也可以通過CocoaPods進(jìn)行安裝。在Podfile上添加相關(guān)的依賴:
pod 'SwiftLint'
然后跟全局方法一樣,在Run Script中添加命令,但是內(nèi)容有些許的不同:
"${PODS_ROOT}/SwiftLint/swiftlint"

接下來就讓我們來試試看SwiftLint的吧!
使用
在給項(xiàng)目初次接入SwiftLint的時候,你可能會被下面這樣的情景給嚇到

但是呢,不用慌,我們可以看一下這是什么情況。仔細(xì)觀察一番之后,我們會發(fā)現(xiàn),絕大多數(shù)的Warning都是這個原因:

我這一行哪里有空格符?簡直就是冤枉?。〉鋵?shí)是這樣的,雖然看起來好像沒有空格符,但是在換行符之間不應(yīng)該摻雜制表符,也就是說你實(shí)際的代碼是這樣的:
\n \tab \n
所以呢,人家的Warning也不是沒有道理的嘛。那么我們該怎么來消除這些Warning呢?
首先,我們要確保,以后我們所碼的代碼不再出現(xiàn)這樣的格式,所以我們需要把Text Editing里面的Including whitespace-only lines勾選上:

這樣可以保證我們今后的換行不再出現(xiàn)制表符的警告,然后,我們就需要處理現(xiàn)有的代碼?,F(xiàn)有的代碼,少說也有幾萬行,手動改不是要累死人?這個時候就輪到SwiftLint的命令行出場了:

我們將目錄切換到工程的根目錄之下,然后敲擊如下命令:
swiftlint autocorrect
然后我們就會發(fā)現(xiàn),所有的空格符Warning都消失了。這都得益于我們剛剛所進(jìn)行的命令行操作,它會將已知的能夠自動修復(fù)的Error和Warning都自動修復(fù),大大的減輕了我們的工作量。
但是又出現(xiàn)了一個問題,在項(xiàng)目的根目錄之下執(zhí)行自動糾正,SwiftLint會將Pods文件夾中的Swift文件也一起糾正了,第三方的框架原則上能不動就不動,那么我們該怎么辦呢?
這個時候就需要.swiftlint.yml文件了。那么這是一個什么文件呢?在使用SwiftLint的時候,很多時候我們會碰到一些自定義的規(guī)則需求,這個時候就需要.swiftlint.yml來解決問題了。
.swiftlint.yml
所謂的.swiftlint.yml其實(shí)就是SwiftLint的一個配置文件,我們可以通過這個配置文件來修改約束的規(guī)則,以此達(dá)到自定義的效果。把這個文件放在代碼根目錄下面。

一般的配置文件大概長這個樣子:
excluded: # 執(zhí)行 linting 時忽略的路徑。 優(yōu)先級比 `included` 更高。
- Carthage
- Pods
line_length:
warning: 350
error: 450
ignores_function_declarations: true
ignores_comments: true
function_body_length: # 函數(shù)體長度
warning: 300
error: 350
identifier_name:
min_length: # 只有最小長度
error: 1 # 只有錯誤
type_body_length: # 類的長度
warning: 800
error: 1200
file_length: # 文件長度
warning: 1000
error: 1500
cyclomatic_complexity: # 代碼復(fù)雜度,默認(rèn)為10
warning: 30
error: 35
force_cast: warning # 強(qiáng)制轉(zhuǎn)換(代碼中存在一些前面通過if判斷過類型,后面做的強(qiáng)制轉(zhuǎn)換的代碼)
force_try: warning # try語句判斷
disabled_rules: # 執(zhí)行時排除舍棄的規(guī)則
- trailing_whitespace # 每一個空行不能有空格,會與Xcode換行后自動對齊生成的空格沖突,建議排除掉加。
- identifier_name # 命名規(guī)則必須按照駝峰原則(可能model中的某些字段與json字段命名沖突,建議排除掉)
- type_name # 類型命名規(guī)則限制,以大寫字母開頭,且長度在1到20個字符之間
- shorthand_operator # 使用+= , -=, *=, /= 代替 a = a + 1
2. SwiftLine的使用 - 代碼提交期間的使用
首先要安裝swiftlint,上面文章已經(jīng)寫過,只需要安裝上去,不用在Run Script中添加命令。.swiftlint.yml文件放在根目錄下面
在代碼提交期間,使用git hooks原理,對提交的代碼進(jìn)行規(guī)范規(guī)則判斷檢查 ,不符合.swiftlint.yml的規(guī)范,就會報錯、報警告。 在根目錄下面的hooks文件里面有commit-msg和pre-commit這個兩個腳本,

commit-msg 的腳本內(nèi)容如下:
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
forcecommit=$(git config --type=bool hooks.forcecommit)
if [ "$forcecommit" != "true" ]
then
if [ "$(grep '^feat:' "$1")" == "" ] &&
[ "$(grep '^fix:' "$1")" == "" ] &&
[ "$(grep '^lint_error:' "$1")" == "" ] &&
[ "$(grep '^lint_warning:' "$1")" == "" ] &&
[ "$(grep '^docs:' "$1")" == "" ] &&
[ "$(grep '^style:' "$1")" == "" ] &&
[ "$(grep '^refactor:' "$1")" == "" ] &&
[ "$(grep '^test:' "$1")" = "" ] &&
[ "$(grep '^chore:' "$1")" == "" ]
then
cat <<\EOF
?錯誤:提交日志格式錯誤; 如需強(qiáng)制提交,可執(zhí)行以下命令(僅限于本次提交)
git config hooks.forcecommit true
我們有如下幾種提交格式可供選擇:
feat: 新功能(feature)
fix: 修補(bǔ)bug
lint_error: 處理lint?
lint_warning: 處理lint??
docs: 文檔(documentation)
style: 格式(不影響代碼運(yùn)行)
refactor: 重構(gòu)(即不是新增功能,也不是修改bug的代碼變動)
test: 增加測試
chore: 構(gòu)建過程或輔助工具的變動
如 "feat:新增直播間粉絲之間問候語"
??:冒號為英文格式,切記切記
EOF
exit 1
fi
else
git config hooks.forcecommit false
fi
# echo "提交的日志為:$1"
# test "" = "$(grep '^Signed-off-by: ' "$1" |
# sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
# echo >&2 Duplicate Signed-off-by lines.
# exit 1
# }
pre-commit的腳本內(nèi)容如下:
#!/bin/bash
# use for SourceTree And Xcode
if test -d "/opt/homebrew/bin/"; then
PATH="/opt/homebrew/bin/:${PATH}"
fi
export PATH
# 檢測swiftLint工具是否安裝
if [ -z "$(which swiftlint)" ]
then
cat <<\EOF
設(shè)備上沒有檢測到SwiftLint,請使用以下命令進(jìn)行下載安裝:
brew install swiftLint
EOF
exit 1
fi
# 接收lint結(jié)果,并進(jìn)行格式化處理
function dealLintResult() {
while read -r line; do
FILE_NAME=$(echo "$line" | cut -d : -f 1 | rev | cut -d / -f 1 | rev)
LINE=$(echo "$line" | cut -d : -f 2)
COLUMN=$(echo "$line" | cut -d : -f 3)
VIOLATION_TYPE=$(echo "$line" | cut -d : -f 4 | cut -c 2-)
VIOLATION=$(echo "$line" | cut -d : -f 5 | cut -c 2-)
DESCRIPTION=$(echo "$line" | cut -d : -f 6 | cut -c 2-)
if [ "$VIOLATION_TYPE" == "warning" ]; then
echo -e "\n?? $VIOLATION \n"
else
echo -e "\n? $VIOLATION \n"
fi
echo -e "$FILE_NAME: 第${LINE}行 第${COLUMN}列。- $DESCRIPTION \n"
echo "---------------------------------------------------------------------"
done <<<"$1"
printf "\n????♀???提交被阻止,請?jiān)谔峤磺靶迯?fù)好以上問題\n"
cat <<\EOF
或使用終極命令 git commit -m 'xxx' --no-verify (不建議使用)
EOF
}
EXIT_CODE=0
COMMIT_SWIFT_FILES=()
# 搜集un-staged files中的swift文件
CHANGED_FILES_UNSTAGED=$(git diff --diff-filter=d --name-only -- "*.swift")
if [ "$CHANGED_FILES_UNSTAGED" ]; then
COMMIT_SWIFT_FILES+=("$CHANGED_FILES_UNSTAGED")
fi
# 搜集staged files中的swift文件
CHANGED_FILES_STAGED=$(git diff --cached --diff-filter=d --name-only -- "*.swift")
if [ "$CHANGED_FILES_STAGED" ]; then
COMMIT_SWIFT_FILES+=("$CHANGED_FILES_STAGED")
fi
# 遍歷所有添加的swift文件,并對其逐一進(jìn)行l(wèi)int
while read -r swiftfile; do
if [ -e "$swiftfile" ]; then
LINTRESULT=$($(which swiftlint) lint --quiet --path "$swiftfile" --config ".swiftlint.yml")
if [ -n "$LINTRESULT" ]; then
dealLintResult "$LINTRESULT"
EXIT_CODE=1
fi
fi
done <<<"${COMMIT_SWIFT_FILES[@]}"
exit $EXIT_CODE
注意我用 sourcetree clone 到本地的代碼后 .git 目錄下沒有發(fā)現(xiàn) hooks 文件夾,但是通過終端 git clone 完的倉庫里就有,我想不明白,sourcetree 只不過是個 git 客戶端而已,還能給我過濾掉了文件夾嗎。后來看到別人寫的 hooks 的應(yīng)用才明白,對于任何 Git 倉庫來說鉤子(hooks)都是本地的,而且它不會隨著 git clone 一起復(fù)制到新的倉庫。 但是在終端里的 git clone 密令是可以把它克隆下來的。
參考文章:
https://blog.csdn.net/weixin_42206732/article/details/90737049
上面的腳本配置完了,接下來就是代碼提交期間使用swiftlint了,在終端里面寫commit命令,會報錯誤,我列出來兩種:
git commit -m "測試swiftlint的使用代碼"
錯誤1:
YPLetterIndexView.swift 這個文件寫法不規(guī)范

錯誤2:
提交代碼的時候,調(diào)教文案不規(guī)范。改成如下就OK了。
git commit -m "feat: 測試swiftlint的使用代碼"
