參考文章鏈接.
在一個工程中, 復(fù)制粘貼一段代碼永遠(yuǎn)是百害而無一益的, 復(fù)制粘貼的代碼導(dǎo)致的是 bug 的復(fù)制, 難于維護(hù), 代碼體積變大等各種問題.
所以在日常工作中, 應(yīng)該引入工具對代碼進(jìn)行檢查, 常用的工具是 PMD. 它配合Swiftlint, 可以做到代碼的靜態(tài)檢查和復(fù)制粘貼代碼檢查.
下面主要來介紹 PMD 工具的使用.
在 Xcode build 時運(yùn)行復(fù)制粘貼檢查
首先利用 HomeBrew 安裝 PMD:
brew install pmd
安裝好 PMD 后, 就可以在 Xcode 中添加 Run Script 腳本了:
# Running CPD
pmd cpd --files ${EXECUTABLE_NAME} --minimum-tokens 50 --language swift --encoding UTF-8 --format net.sourceforge.pmd.cpd.XMLRenderer > cpd-output.xml --failOnViolation true
# Running script
php ./cpd_script.php -cpd-xml cpd-output.xml
首先需要將其中的 ${EXECUTABLE_NAME}
替換為工程名稱, 比如 MyApp 等.
上面的腳本中使用 pmd 進(jìn)行復(fù)制粘貼檢查, 檢查結(jié)果會存放在 cpd-output.xml 文件中. --minimum-tokens
的值是一個經(jīng)驗值, 這里的 50 適合 swift.(參考文章內(nèi)作者給的經(jīng)驗值, 這個需要根據(jù)具體情況確定.)
另外腳本中需要 php 對輸出腳本進(jìn)行分析并顯示到 Xcode 中, 如果沒有安裝 php, 則需要安裝.
還有需要的 cpd_script.php
文件, 需要放到工程根目錄, 它的作用是利用之前生成的檢查結(jié)果文件, 將檢查的結(jié)果顯示到 Xcode 中:
<?php
foreach (simplexml_load_file('cpd-output.xml')->duplication as $duplication) {
$files = $duplication->xpath('file');
foreach ($files as $file) {
echo $file['path'].':'.$file['line'].':1: warning: '.$duplication['lines'].' copy-pasted lines from: '
.implode(', ', array_map(function ($otherFile) { return $otherFile['path'].':'.$otherFile['line']; },
array_filter($files, function ($f) use (&$file) { return $f != $file; }))).PHP_EOL;
}
}
?>
關(guān)于這個 php 腳本為什么要這么寫, 可以參考這篇文章.
安裝--->設(shè)置 run script 腳本----> 放入輔助 php 腳本. 簡單三步, 檢查代碼中的復(fù)制粘貼就是分分鐘的事情.
注意事項
發(fā)現(xiàn)一個不能提示復(fù)制粘貼代碼的問題, 如果實際使用的時候沒有正常檢測到復(fù)制粘貼的代碼, 可以嘗試 clean 一次后再進(jìn)行檢測.
附錄 token 限制值的確定
在一個文件中引入如下測試代碼:
public func add() {
let a = 3
let b = 4
let c = 5
let result = a + b + c
print(result)
}
public func somethingPrint() {
let a = 3
let b = 4
let c = 5
let result = a + b + c
print(result)
}
一看就知道兩個方法體中的代碼是復(fù)制的, 此時 --minimum-tokens
設(shè)置為 50 的時候檢測不到, 若降低到 40, 仍然檢測不到, 降低到 30, 可以檢測到了. 通過這個方式可以確定自己需要的 token 值設(shè)置.
一定注意 --minimum-tokens
不能太高也不能太低, 太低的話檢測到一個詞都是復(fù)制的, 太高的話又會什么都檢測不到.