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