codeclimate-duplication es un motor que envuelve el desglose y admite Java, Ruby, Python, JavaScript y PHP. Puede ejecutarlo en la línea de comandos utilizando la CLI del clima de código o en nuestra plataforma de análisis alojado.
El algoritmo del motor de duplicación puede ser sorprendente, pero en realidad es muy simple. Tenemos una página de documentos que explica el algoritmo.
cd en la carpeta de su proyecto y ejecute codeclimate analyze . El análisis de duplicación está habilitado de forma predeterminada, por lo que no necesita hacer nada más. Establecemos valores predeterminados de umbral útiles para los idiomas que apoyamos, pero es posible que desee ajustar estas configuraciones en función de las pautas de su proyecto.
La configuración del umbral de masa representa la "masa" mínima que un bloque de código debe analizarse para su duplicación. Si el motor informa con demasiada facilidad la duplicación, intente elevar el umbral. Si sospecha que el motor no está atrapando suficiente duplicación, intente reducir el umbral. La mejor configuración tiende a diferir de un lenguaje a otro.
Para ajustar esta configuración, use la tecla checks de nivel superior en su archivo de configuración:
checks :
identical-code :
config :
threshold : 25
similar-code :
config :
threshold : 50 Tenga en cuenta que tiene la actualización de la estructura YAML en la tecla languages al tipo hash para admitir la configuración adicional.
Por defecto, el motor de duplicación informará el código que ha sido duplicado en solo dos ubicaciones. Puede ser menos estricto al aumentar solo una advertencia si el código se duplica solo en tres o más ubicaciones. Para ajustar esta configuración, agregue una tecla count_threshold a su configuración. Por ejemplo, para usar el mass_threshold predeterminado para Ruby, pero para hacer cumplir la regla de tres, puede usar esta configuración:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
count_threshold : 3 También puede cambiar el count_threshold predeterminado para todos los idiomas:
plugins :
duplication :
enabled : true
config :
count_threshold : 3 Todos los motores verifican solo los archivos apropiados, pero puede anular el conjunto predeterminado de patrones. Los patrones se ejecutan contra el directorio raíz del proyecto, por lo que debe usar ** para hacer coincidir los archivos en directorios anidados. También tenga en cuenta que debe especificar todos los patrones, no solo el que desea agregar.
plugins :
duplication :
enabled : true
config :
languages :
ruby :
patterns :
- " **/*.rb
- " **/*.rake"
- " Rakefile "
- " **/*.ruby " Por defecto, el motor de duplicación utilizará un analizador Python 2. Para habilitar el análisis para el código Python 3, especifique la python_version como se muestra en el siguiente ejemplo. Esto habilitará un analizador Python 3 y agregará la extensión del archivo .py3 a la lista de patrones de archivos incluidos.
plugins :
duplication :
enabled : true
config :
languages :
python :
python_version : 3A veces, se informan similitudes estructurales que simplemente no le importa. Por ejemplo, el contenido de matrices o hashes puede tener estructuras similares y hay poco que pueda hacer para refactorizarlas. Puede especificar filtros específicos del idioma para ignorar cualquier problema que coincida con el patrón. Aquí hay un ejemplo que filtra hashes y matrices simples:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
filters :
- " (hash (lit _) (str _) ___) "
- " (array (str _) ___) " La sintaxis para los patrones es bastante simple. En el primer patrón: "(hash (lit _) (str _) ___)" Especifica "un hash con una clave literal, un valor de cadena, seguido de cualquier otra cosa (incluido nada)". También puede especificar "(hash ___)" para ignorar todos los hashes por completo.
Descubrir qué filtrar es complicado. CodeClimate-Duplation viene con una opción de configuración para ayudar con el descubrimiento. En lugar de escanear su código e imprimir problemas para CodeClimate, ¡imprime los árboles de análisis! Simplemente agregue dump_ast: true y debug: true a su archivo .codeClimate.yml:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
debug: true
... rest of config ...
Luego ejecute codeclimate analyze mientras se usa el indicador de depuración para emitir stderr:
% CODECLIMATE_DEBUG=1 codeclimate analyze
Ejecutar ese comando podría generar 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 es la representación interna del código real. Suponiendo que haya visto esos problemas y haya determinado que no sean un problema que desea abordar, puede filtrarlo escribiendo una cadena de patrón que coincida con ese árbol.
Mirando la salida del árbol nuevamente, esta vez aplanándolo:
s(:ExpressionStatement, :expression, s(:AssignmentExpression, :"=",:left, ...) ...)
La representación interna (que es Ruby) es diferente del lenguaje de patrón (que es similar a LISP), por lo que primero necesitamos convertir s(: a ( y eliminar todas las comas y colons:
(ExpressionStatement expression (AssignmentExpression "=" left ...) ...)
A continuación, no nos importa expression , así que vamos a deshacernos de eso reemplazándolo con el combate para cualquier elemento único _ :
(ExpressionStatement _ (AssignmentExpression "=" left ...) ...)
Lo mismo ocurre con "=" y left , pero en realidad no nos importa el resto del nodo de asignación de expresión, así que usemos el Matcher que ignorará el resto del árbol ___ :
(ExpressionStatement _ (AssignmentExpression ___) ...)
Y finalmente, no nos importa lo que sigue en la ExpressionStatement , así que también ignoremos el resto:
(ExpressionStatement _ (AssignmentExpression ___) ___)
Esto dice: "Cualquier nodo de ExpressionStatement, con cualquier valor y un nodo de asignación de expresión con cualquier cosa, seguido de cualquier otra cosa". Hay otras formas de escribir un patrón para que coincida con este árbol, pero esto es bastante claro.
Luego puede agregar ese filtro a su configuración:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
languages:
javascript:
filters:
- "(ExpressionStatement _ (AssignmentExpression ___) ___)"
Luego vuelva a ejecutar el analizador y descubra cuál debería ser el siguiente filtro. Cuando esté satisfecho con los resultados, elimine la configuración dump_ast (o configure en falso) para volver al análisis normal.
Para obtener más información sobre la coincidencia de patrones, consulte sexp_processor, especialmente sexp.rb