codeclimate-duplication是一種發動機,可以包裝Flay並支持Java,Ruby,Python,JavaScript和PHP。您可以使用代碼氣候CLI或我們託管的分析平台在命令行上運行它。
複製引擎的算法可能令人驚訝,但實際上非常簡單。我們有一個文檔頁面解釋算法。
cd到您的項目文件夾中並運行codeclimate analyze 。默認情況下啟用了重複分析,因此您無需做任何其他事情。 我們為我們支持的語言設置了有用的閾值默認值,但是您可能需要根據項目準則調整這些設置。
質量閾值配置表示必須分析代碼塊的最小“質量”才能重複。如果引擎太容易報告重複,請嘗試提高閾值。如果您懷疑發動機的複制不足,請嘗試降低閾值。最好的設置往往因語言而異。
要調整此設置,請使用配置文件中的頂級checks密鑰:
checks :
identical-code :
config :
threshold : 25
similar-code :
config :
threshold : 50請注意,您的languages按鍵的更新為YAML結構,以支持額外的配置。
默認情況下,重複引擎將報告僅在兩個位置重複的代碼。僅在僅在三個或更多位置重複代碼時,就可以通過提出警告來不太嚴格。要調整此設置,請將count_threshold密鑰添加到您的配置中。例如,要使用Ruby的默認mass_threshold ,但是要執行三個規則,您可以使用此配置:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
count_threshold : 3您還可以更改所有語言的默認count_threshold :
plugins :
duplication :
enabled : true
config :
count_threshold : 3所有引擎僅檢查適當的文件,但您可以覆蓋默認模式集。模式與項目root目錄進行了運行,因此您必須使用**匹配嵌套目錄中的文件。另請注意,您必須指定所有模式,而不僅僅是要添加的模式。
plugins :
duplication :
enabled : true
config :
languages :
ruby :
patterns :
- " **/*.rb
- " **/*.rake"
- " Rakefile "
- " **/*.ruby "默認情況下,重複引擎將使用Python 2解析器。要啟用Python 3代碼的分析,請指定python_version ,如下示例所示。這將啟用Python 3解析器,並將.py3文件擴展名添加到隨附的文件模式列表中。
plugins :
duplication :
enabled : true
config :
languages :
python :
python_version : 3有時,據報導您只是不在乎的結構相似性。例如,陣列或哈希的內容可能具有相似的結構,您幾乎無能為力地重構它們。您可以指定特定語言的過濾器,以忽略與模式相匹配的任何問題。這是一個過濾簡單哈希和數組的示例:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
filters :
- " (hash (lit _) (str _) ___) "
- " (array (str _) ___) "圖案的語法非常簡單。在第一個模式中: "(hash (lit _) (str _) ___)"指定“帶有字面鑰匙,字符串值的哈希,然後是其他任何內容(包括什麼)”。您也可以指定"(hash ___)" ,以完全忽略所有哈希。
弄清楚要過濾的內容是棘手的。編碼氣候賦予的配置選項可幫助您進行發現。它沒有掃描您的代碼並打印出針對編解碼的問題,而是打印出解析樹!只需添加dump_ast: true和debug: true您的.codeclimate.yml文件:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
debug: true
... rest of config ...
然後在使用調試標誌來輸出stderr時運行codeclimate analyze :
% CODECLIMATE_DEBUG=1 codeclimate analyze
運行該命令可能會輸出類似的內容:
Sexps for issues:
# 1) ExpressionStatement#4261258897 mass=128:
# 1.1) bogus-examples.js:5
s(:ExpressionStatement,
:expression,
s(:AssignmentExpression,
:"=",
:left,
s(:MemberExpression,
:object,
s(:Identifier, :EventBlock),
:property,
s(:Identifier, :propTypes)),
... LOTS more...)
... even more LOTS more...)
這是實際代碼的內部表示。假設您已經查看了這些問題並確定它們不是要解決的問題,則可以通過編寫匹配該樹的模式字符串來過濾它。
再次查看樹的輸出,這次將其弄平:
s(:ExpressionStatement, :expression, s(:AssignmentExpression, :"=",:left, ...) ...)
內部表示(Ruby)與模式語言不同(類似於LISP),因此首先我們需要轉換s(: to (並刪除所有逗號和結腸:
(ExpressionStatement expression (AssignmentExpression "=" left ...) ...)
接下來,我們不在乎回合expression ,讓我們通過用匹配器代替任何單個元素_ ::
(ExpressionStatement _ (AssignmentExpression "=" left ...) ...)
"="並left情況也是如此,但實際上我們不在乎分配表達節點的其餘部分,因此讓我們使用匹配器,該匹配器會忽略樹的其餘部分___ :
(ExpressionStatement _ (AssignmentExpression ___) ...)
最後,我們不在乎ExpressionStatement的下面是什麼,所以讓我們也忽略其餘的:
(ExpressionStatement _ (AssignmentExpression ___) ___)
這是:“任何具有任何值的表達式結節,其中包含任何值,其次是其他任何內容”。還有其他方法可以編寫圖案以匹配這棵樹,但這很明顯。
然後,您可以將該過濾器添加到您的配置:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
languages:
javascript:
filters:
- "(ExpressionStatement _ (AssignmentExpression ___) ___)"
然後重新運行分析儀,並弄清楚下一個過濾器應該是什麼。當您對結果感到滿意時,請刪除dump_ast config(或將其設置為false)以返回正常分析。
有關圖案匹配的更多信息,請參見SEXP_Processor,尤其是SEXP.RB