web-dev-qa-db-fra.com

Comment détecter la duplication de code pendant le développement?

Nous avons une base de code assez grande, 400K LOC de C++, et la duplication de code est un problème. Existe-t-il des outils capables de détecter efficacement les blocs de code dupliqués?

Idéalement, ce serait quelque chose que les développeurs pourraient utiliser pendant le développement plutôt que de simplement l'exécuter occasionnellement pour voir où se trouvent les problèmes. Ce serait aussi bien si nous pouvions intégrer un tel outil avec CruiseControl pour faire un rapport après chaque enregistrement.

J'ai jeté un coup d'œil à Duploc il y a quelque temps, il a montré un joli graphique mais nécessite un environnement Smalltalk pour l'utiliser, ce qui rend son exécution automatique plutôt difficile.

Des outils gratuits seraient bien, mais s'il y a de bons outils commerciaux, je serais également intéressé.

75
David Dibben

Simian détecte le code en double dans les projets C++.

Mise à jour: fonctionne également avec Java, C #, C, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, le code source Groovy et même des fichiers de texte brut

35
Simon Steele

J'ai utilisé PMD's Copy-and-Paste-Detector et l'ai intégré dans CruiseControl en utilisant le script wrapper suivant (assurez-vous d'avoir le pot pmd dans le chemin de classe).

Notre chèque fonctionne tous les soirs. Si vous souhaitez limiter la sortie pour ne répertorier que les fichiers du jeu de modifications actuel, vous devrez peut-être une programmation personnalisée (idée: tout vérifier et répertorier uniquement les doublons dans lesquels l'un des fichiers modifiés est impliqué. Vous devez vérifier tous les fichiers car une modification pourrait utiliser du code d'un fichier non modifié). Devrait être faisable en utilisant la sortie XML et en analysant le résultat. N'oubliez pas de poster ce script quand c'est fait;)

Pour commencer, la sortie "Texte" devrait être correcte, mais vous voudrez afficher les résultats de manière conviviale, pour laquelle j'utilise un script Perl pour générer des fichiers HTML à partir de la sortie "xml" de CPD. Ceux-ci sont accessibles en les affichant sur le Tomcat où réside le jsp de rapport de croisière. Les développeurs peuvent les voir à partir de là et voir les résultats de leur piratage sale :)

Il s'exécute assez rapidement, moins de 2 secondes sur le code 150 KLoc (lignes vides et commentaires non comptés dans ce nombre).

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>
19
user39039

duplo semble être une implémentation C de l'algorithme utilisé dans Duploc. Il est simple à compiler et à installer, et bien que les options soient limitées, il semble fonctionner plus ou moins prêt à l'emploi.

6
benno

Regardez le projet PMD .

Je ne l'ai jamais utilisé, mais j'ai toujours voulu.

4
Andy Lester

Ces paquets Debian semblent faire quelque chose dans ce sens:

P.S. Il devrait y avoir une balise detteags pour tous les outils liés à la recherche de la duplication [proche]. (Mais comment cela s'appellerait-il?)

3
SamB

Eh bien, vous pouvez exécuter un détecteur de clone sur votre base de code source tous les soirs.

De nombreux détecteurs de clones fonctionnent en comparant les lignes source et ne peuvent trouver que le code en double exact.

CCFinder, ci-dessus, fonctionne en comparant les jetons de langue, il n'est donc pas sensible aux changements d'espace blanc. Il peut détecter des clones qui sont des variantes du code d'origine s'il n'y a qu'un seul changement de jeton (par exemple, changer une variable X en Y dans le clone).

Idéalement, ce que vous voulez est ce qui précède, mais la possibilité de trouver des clones où les variations peuvent être relativement arbitraires, par exemple, remplacer une variable par une expression, une déclaration par un bloc, etc.

Notre détecteur de clones CloneDR le fait pour Java, C #, C++, COBOL, VB.net, VB6, Fortran et une variété d'autres langages. Il peut être consulté sur: http://www.semdesigns.com/Products/Clone/index.html

En plus de pouvoir gérer plusieurs langues, le moteur CloneDR est capable de gérer une variété de styles d'encodage d'entrée, y compris ASCII, ISO-8859-1, UTF8, UTF16, EBCDIC, un certain nombre d'encodages Microsoft et Shift- (japonais) - JIS.

Le site propose plusieurs exemples de rapports d'exécution de détection de clone, dont un pour C++.

EDIT février 2014: gère désormais l'intégralité de C++ 14.

2
Ira Baxter

ConQAT est un excellent outil qui supporte l'analyse de code C++. Peut trouver des doublons en ignorant les espaces. Possède des interfaces gui et console extrêmement pratiques. En raison de sa flexibilité, il n'est pas facile à configurer. J'ai trouvé ce billet de blog très utile pour configurer un projet c ++ .

1
user2648800

CCFinderX est un détecteur de code cloné gratuit (pour une utilisation interne) qui prend en charge plusieurs langages de programmation (Java, C, C++, COBOL, VB, C #).

1
bk1e

Identique ( http://sourceforge.net/projects/same/ ) est extrêmement simple, mais il fonctionne sur les lignes de texte au lieu des jetons, ce qui est utile si vous utilisez une langue qui n'est pas pris en charge par l'un des chercheurs de clones les plus sophistiqués.

1
Sean McMillan

Trouver des extraits de code "identiques" est relativement facile, il existe des outils qui le font déjà (voir les autres réponses).

Parfois, c'est une bonne chose, parfois non; elle peut ralentir le temps de développement si elle est effectuée à un "niveau" trop fin; c'est-à-dire qu'en essayant de refactoriser tant de code, vous perdez votre objectif (et vous cassez probablement vos jalons et vos horaires).

Ce qui est plus difficile, c'est de trouver plusieurs fonctions/méthodes qui font la même chose mais avec des entrées et/ou algorithmes différents (mais similaires) sans documentation appropriée.

Si vous avez deux ou différentes méthodes pour faire la même chose et que le programmeur essaie de réparer une instance mais oublie (ou ne sait pas qu'elles existent) de réparer les autres, vous augmenterez le risque pour votre logiciel.

1
Max

Vous pouvez utiliser notre outil SourceMeter pour détecter la duplication de code. C'est un outil en ligne de commande (très similaire aux compilateurs), vous pouvez donc l'intégrer facilement dans des outils d'intégration continue, comme CruiseControl votre mentionné, ou Jenkins .

1
Rudolf FERENC

Il y a aussi Simian qui supporte Java, C #, C++, C, Objective-C, JavaScript ...

Il est pris en charge par Hudson (comme CPD).

Sauf si vous êtes un projet open source, vous devez payer pour Simian.

0
Wernight