c++ - ¿Cómo detectar la duplicación de código durante el desarrollo?
code-duplication (13)
Tenemos una base de código bastante grande, 400K LOC de C ++, y la duplicación de código es un problema. ¿Hay alguna herramienta que pueda detectar bloques de código duplicados?
Idealmente, esto sería algo que los desarrolladores podrían usar durante el desarrollo en lugar de solo ejecutarlo ocasionalmente para ver dónde están los problemas. También sería bueno si pudiéramos integrar tal herramienta con CruiseControl para dar un informe después de cada check-in.
Duploc un vistazo a Duploc un tiempo, mostró un buen gráfico pero requiere un entorno de texto pequeño para usarlo, lo que hace que ejecutarlo automáticamente sea bastante difícil.
Las herramientas gratuitas serían buenas, pero si hay algunas buenas herramientas comerciales, también me interesaría.
Bueno, puedes ejecutar un detector de clonación en tu base de código fuente todas las noches.
Muchos detectores de clones funcionan al comparar líneas de origen y solo pueden encontrar el código duplicado exacto.
CCFinder, arriba, funciona comparando tokens de idioma, por lo que no es sensible a los cambios de espacio en blanco. Puede detectar clones que son variantes del código original si solo hay cambios de token individuales (por ejemplo, cambiar una variable de X a Y en el clon).
Idealmente, lo que desea es lo anterior, pero la capacidad de encontrar clones donde las variaciones se permiten es relativamente arbitraria, por ejemplo, reemplazar una variable por una expresión, un enunciado por un bloque, etc.
Nuestro detector de clonación CloneDR hace esto para Java, C #, C ++, COBOL, VB.net, VB6, Fortran y una variedad de otros lenguajes. Se puede ver en: http://www.semdesigns.com/Products/Clone/index.html
Además de ser capaz de manejar múltiples idiomas, el motor CloneDR es capaz de manejar una variedad de estilos de codificación de entrada, incluyendo ASCII, ISO-8859-1, UTF8, UTF16, EBCDIC, varias codificaciones de Microsoft y Shift (japonés). JIS.
El sitio tiene varios informes de ejemplo de ejecución de clonación, incluido uno para C ++.
EDITAR Feb 2014: Ahora maneja todo C ++ 14.
Encontrar fragmentos de código "idénticos" es relativamente fácil, ya existe una herramienta que ya lo hace (ver otras respuestas).
A veces es algo bueno, a veces no lo es; puede empantanar el tiempo de desarrollo si se hace en un "nivel" demasiado fino; es decir, tratando de refactorizar tanto código, pierdes tu objetivo (y probablemente arruines tus hitos y horarios).
Lo que es más difícil es encontrar múltiples funciones / métodos que hagan lo mismo pero con entradas y / o algoritmos diferentes (pero similares) sin la documentación adecuada.
Si tiene dos o diferentes métodos para hacer lo mismo y el programador intenta arreglar una instancia pero se olvida (o no sabe que existen) para arreglar las otras, aumentará el riesgo para su software.
Mire el proyecto PMD .
Nunca lo he usado, pero siempre he querido.
Para mi futura referencia, estos paquetes de Debian parecen hacer algo en esta línea:
similarity-tester (también conocido como el software y simulador de similitud de texto SIM )
Podría haber jurado que tenía algunos otros paquetes instalados que podrían ser aún más relevantes, pero no los puedo encontrar en este momento. (Por eso estoy enumerando mis hallazgos aquí esta vez: ¡para tener la oportunidad de poder encontrarlos de nuevo!)
PS: realmente parece que debería haber una etiqueta debtags para todas las herramientas relacionadas para encontrar duplicación [cercana]. (¿Pero cómo se llamaría?)
Puede usar nuestra herramienta SourceMeter para detectar la duplicación de código. Es una herramienta de línea de comandos (muy similar a los compiladores), por lo que puedes integrarla fácilmente en herramientas de integración continua, como CruiseControl tu mencionado, o Jenkins .
Same ( http://sourceforge.net/projects/same/ ) es extremadamente sencillo, pero funciona en líneas de texto en lugar de tokens, lo que es útil si está utilizando un idioma que no es compatible con uno de los clones más elegantes. buscadores
También hay Simian que admite Java, C #, C ++, C, Objective-C, JavaScript ...
Es compatible con Hudson (como CPD).
A menos que sea un proyecto de código abierto, debe pagar por Simian.
Utilicé Copiar y Pegar-Detector de PMD y lo integé en CruiseControl utilizando el siguiente script de envoltura (asegúrese de tener el jar de pmd en la ruta de clases).
Nuestro cheque funciona todas las noches. Si desea limitar la salida para listar solo archivos del conjunto de cambios actual, es posible que necesite alguna programación personalizada (idea: marque todos y haga una lista solo de los duplicados donde está involucrado uno de los archivos modificados. Debe verificar todos los archivos porque podría cambiar algún código de un archivo no cambiado). Debería ser factible al usar salida XML y analizar el resultado. No olvides publicar esa secuencia de comandos cuando esté terminado;)
Para empezar, la salida "Texto" debería estar bien, pero querrá mostrar los resultados de una manera fácil de usar, para lo cual utilizo un script perl para generar archivos HTML a partir de la salida "xml" de CPD. Esos son accesibles al publicarlos en el tomcat donde reside jsp de informes de crucero. Los desarrolladores pueden verlos desde allí y ver los resultados de su sucio pirateo :)
Funciona bastante rápido, menos de 2 segundos en el código de 150 KLoc (líneas vacías y comentarios no contados en ese número).
duplicatecheck.xml :
<project name="duplicatecheck" default="cpd">
<property name="files.dir" value="dir containing your sources"/>
<property name="output.dir" value="dir containing results for publishing"/>
<target name="cpd">
<taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask"/>
<cpd minimumTokenCount="100"
language="cpp"
outputFile="${output.dir}/duplicates.txt"
ignoreLiterals="false"
ignoreIdentifiers="false"
format="text">
<fileset dir="${files.dir}/">
<include name="**/*.h"/>
<include name="**/*.cpp"/>
<!-- exclude third-party stuff -->
<exclude name="boost/"/>
<exclude name="cppunit/"/>
</fileset>
</cpd>
</target>
duplo parece ser una implementación C del algoritmo utilizado en Duploc. Es simple de compilar e instalar, y aunque las opciones son limitadas, parece funcionar más o menos desde el primer momento.
CCFinderX es un detector de código clonado gratuito (para uso interno) que admite múltiples lenguajes de programación (Java, C, C ++, COBOL, VB, C #).
Simian detecta código duplicado en proyectos de C ++.
Actualización: también funciona con Java, C #, C, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, código fuente Groovy e incluso archivos de texto sin formato
TeamCity tiene un potente motor de duplicación de código para .NET y Java, que se puede ejecutar sin esfuerzo como parte de su sistema de compilación.
ConQAT es una gran herramienta que respalda el análisis de código C ++. Puede encontrar duplicados ignorando espacios en blanco. Tiene interfaces gui y consola sumamente prácticas. Debido a su flexibilidad, no es fácil de configurar. Encontré esta publicación de blog muy útil para configurar proyectos de C ++ .