codeclimate-duplication é um mecanismo que envolve o Flay e suporta Java, Ruby, Python, JavaScript e PHP. Você pode executá -lo na linha de comando usando a CLI climática do código ou em nossa plataforma de análise hospedada.
O algoritmo do mecanismo de duplicação pode ser surpreendente, mas na verdade é muito simples. Temos uma página de documentos explicando o algoritmo.
cd na pasta do seu projeto e execute codeclimate analyze . A análise de duplicação é ativada por padrão, para que você não precise fazer mais nada. Definimos padrões de limite úteis para os idiomas que suportamos, mas você pode ajustar essas configurações com base nas diretrizes do seu projeto.
A configuração do limite de massa representa a "massa" mínima que um bloco de código deve ser analisado para duplicação. Se o motor estiver relatando muito facilmente duplicação, tente aumentar o limite. Se você suspeitar que o motor não está pegando duplicação suficiente, tente abaixar o limite. A melhor configuração tende a diferir de idioma para idioma.
Para ajustar essa configuração, use a tecla checks nível superior em seu arquivo de configuração:
checks :
identical-code :
config :
threshold : 25
similar-code :
config :
threshold : 50 Observe que você tem a atualização da estrutura YAML sob a chave dos languages para o tipo de hash para suportar configuração extra.
Por padrão, o mecanismo de duplicação relatará código que foi duplicado em apenas dois locais. Você pode ser menos rigoroso ao levantar apenas um aviso se o código for duplicado apenas em três ou mais locais. Para ajustar essa configuração, adicione uma chave count_threshold à sua configuração. Por exemplo, para usar o mass_threshold padrão para Ruby, mas para fazer cumprir a regra dos três, você pode usar esta configuração:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
count_threshold : 3 Você também pode alterar o count_threshold padrão para todos os idiomas:
plugins :
duplication :
enabled : true
config :
count_threshold : 3 Todos os motores verificam apenas arquivos apropriados, mas você pode substituir o conjunto padrão de padrões. Os padrões são executados contra o diretório raiz do projeto, então você deve usar ** para combinar arquivos em diretórios aninhados. Observe também que você deve especificar todos os padrões, não apenas o que você deseja adicionar.
plugins :
duplication :
enabled : true
config :
languages :
ruby :
patterns :
- " **/*.rb
- " **/*.rake"
- " Rakefile "
- " **/*.ruby " Por padrão, o mecanismo de duplicação usará um analisador Python 2. Para ativar a análise para o código Python 3, especifique o python_version como mostrado no exemplo abaixo. Isso permitirá um analisador Python 3 e adicionará a extensão do arquivo .py3 à lista de padrões de arquivo incluídos.
plugins :
duplication :
enabled : true
config :
languages :
python :
python_version : 3Às vezes, são relatadas semelhanças estruturais que você simplesmente não se importa. Por exemplo, o conteúdo de matrizes ou hashes pode ter estruturas semelhantes e há pouco que você possa fazer para refatorá -los. Você pode especificar filtros específicos do idioma para ignorar quaisquer problemas que correspondam ao padrão. Aqui está um exemplo que filtra hashes e matrizes simples:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
filters :
- " (hash (lit _) (str _) ___) "
- " (array (str _) ___) " A sintaxe para padrões é bastante simples. No primeiro padrão: "(hash (lit _) (str _) ___)" especifica "um hash com uma chave literal, um valor de string, seguido por qualquer outra coisa (incluindo nada)". Você também pode especificar "(hash ___)" para ignorar todos os hashes completamente.
Descobrir o que filtrar é complicado. O codeclimate-duplicação vem com uma opção de configuração para ajudar na descoberta. Em vez de digitalizar seu código e imprimir problemas de codeclima, ele imprime as árvores de pasta! Basta adicionar dump_ast: true e debug: true ao seu arquivo .codeclimate.yml:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
debug: true
... rest of config ...
Em seguida, execute codeclimate analyze enquanto estiver usando o sinalizador de depuração para produzir Stderr:
% CODECLIMATE_DEBUG=1 codeclimate analyze
Executar esse comando pode gerar algo como:
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...)
Esta é a representação interna do código real. Supondo que você tenha analisado esses problemas e os determinou a não ser um problema que você deseja abordar, você pode filtrá -lo escrevendo uma sequência de padrões que corresponderia a essa árvore.
Olhando para a saída da árvore novamente, desta vez achatando -a:
s(:ExpressionStatement, :expression, s(:AssignmentExpression, :"=",:left, ...) ...)
A representação interna (que é rubi) é diferente da linguagem padrão (que é do tipo Lisp), então primeiro precisamos converter s(: para ( e remover todas as vírgulas e colonos:
(ExpressionStatement expression (AssignmentExpression "=" left ...) ...)
Em seguida, não nos importamos com expression , então vamos nos livrar disso substituindo -a pelo Matcher por qualquer elemento único _ :
(ExpressionStatement _ (AssignmentExpression "=" left ...) ...)
O mesmo vale para "=" e left , mas na verdade não nos importamos com o restante do nó de expressão da atribuição, então vamos usar o correspondente que ignorará o restante da árvore ___ :
(ExpressionStatement _ (AssignmentExpression ___) ...)
E, finalmente, não nos importamos com o que se segue no ExpressionStatement , então vamos ignorar o resto também:
(ExpressionStatement _ (AssignmentExpression ___) ___)
Isso diz: "Qualquer nó ExpressionStatement, com qualquer valor e um nó de expressão de atribuição com qualquer coisa, seguida por qualquer outra coisa". Existem outras maneiras de escrever um padrão para combinar com essa árvore, mas isso é bastante claro.
Então você pode adicionar esse filtro à sua configuração:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
languages:
javascript:
filters:
- "(ExpressionStatement _ (AssignmentExpression ___) ___)"
Em seguida, execute novamente o analisador e descubra qual deve ser o próximo filtro. Quando estiver satisfeito com os resultados, remova a configuração dump_ast (ou defina -a como falsa) para voltar à análise normal.
Para obter mais informações sobre a correspondência de padrões, consulte Sexp_processor, especialmente o Sexp.rb