ソースコードをコピーアンドペーストで作成したコードクローンの方が信頼性がいいという言説もないことはないですが、多くの場合、コードクローンの存在は我々を土壇場で苦しめることが多いです。
担当者が逃げた、ソースコードを、夜遅くまで修正してリリースしたあとに、実は「コピペで作っているから別の所も全部なおしてテストしてね」とか言われて、作業をやり直すのは、とてもとても悲しいものです。
殆ど同じソースコードを間違い探しのように微妙に変更して、修正していくのは屈辱の極みです。
土壇場において、このような罰ゲームを避けるために、コピペの頻度というものは常時監視しておき、異常な頻度の場合はただちに是正すべきです。
ここでは、コピペの検出を行うツールについて説明します。
PMD-CPD
PMDはJavaで実装されたJavaのソースコードの潜在的問題を検出するツールです。
http://pmd.sourceforge.net/snapshot/
この機能の一部に重複したコードを検出するCPDコマンドが存在しており、次のプログラミング言語の重複を検出可能です。
・Java
・JSP
・C++
・Ruby
・Fortran
・PHP
・C#
・PLSQL
・Ecmascript
インストール方法
下記のいずれかのファイルをダウンロード、解凍して任意のフォルダに展開してください。
http://sourceforge.net/projects/pmd/files/pmd/
実行例
Windowsでの実行例
cpd --minimum-tokens 50 --language ecmascript --format text --encoding utf8 --files C:\tool\clonedigger\test\ > result.txt
Linuxでの実行例
bin/run.sh cpd --minimum-tokens 35 --format xml --language ruby --files /var/lib/redmine/app/ > result.xml
パラメータ
パラメータはwindowsとlinuxで共有です。
パラメータ | 説明 |
---|---|
--minimum-tokens | 重複を検知するトークン数を指定します。 |
--format | text,xml,csvが選択できます。xmlで出力した場合はjenkinsで使用できます。 |
--language | プログラミング言語の種類を指定します. |
--files | 検査対象のソースコードのディレクトリを指定します。これは再帰的に検出します。 |
--encoding | 検査対象のソースコードのエンコードを指定します |
GUI
bin/cpdgui.batを実行することでGUIで動作することもできます。
Clonedigger
ClonediggerはPythonとJavaで実装されたコピペ検出ツールです。
http://clonedigger.sourceforge.net/
検出可能なプログラミング言語は次の通りです。
・python
・java
・lua
・javascript
python以外のプログラミング言語の検出には、後述するコツがあります。
インストール方法
easy_install clonedigger
実行例
Pythonの検出例
ファイルを指定した場合
clonedigger -l python -o ./test.html C:\tool\clonedigger\test\test_utf8.py
フォルダを指定した場合
clonedigger -l python -o ./test.html C:\tool\clonedigger\test\test_utf8.py
フォルダを指定した場合は、サブフォルダも検出します。
-oで指定したファイルに以下のようなHTMLを作成します。
もし、次のように--cpd-outputオプションを使用するとXML形式で出力されます。この出力形式はPMD/CPDと同じものになります。
clonedigger -l python --cpd-output -o test.xml C:\tool\clonedigger\test\python\
Javaの検出例
Python以外のソースコードを検出する場合、カレントディレクトリにjava_antlrが存在しないと動作しません。
Windows、Python2.7の場合は次のような操作が必要になります。
cd C:\Python27\Lib\site-packages\clonedigger-1.1.0-py2.7.egg\clonedigger
clonedigger -l java --cpd-output -o test.xml C:\tool\clonedigger\test\test.java
JavaScriptの検出例
JavaScriptを検出するときには、カレントディレクトリにjs_antlrが存在しないと動作しません。
Windows、Python2.7の場合は次のような操作が必要になります。
cd C:\Python27\Lib\site-packages\clonedigger-1.1.0-py2.7.egg\clonedigger
clonedigger -l js --cpd-output -o test.xml C:\tool\clonedigger\test\test.js
ブラウザで動作させるJavaScriptは次のようないい加減な実装でも動作します。
// 最後のコンマが余分
var questions = [
{message: "ああああ", category: Category.emotionalExhaustion} ,
];
しかし、clonediggerではこのような不正な記述があると、解析が中断されエラーとなります。この時次のようなエラーメッセージが表示されるので、修正のヒントになるでしょう
line 14:2 rule arrayItem failed predicate: { input.LA(1) == COMMA }?
AIST CCFinderX
コメントで教えてもらった、AIST CCFinderXは下記のページからダウンロードできます。
http://www.ccfinder.net/ccfinderxos-j.html
動作させるに32ビットのJavaとPython2.6(上でも下でもダメ)が必要になります。
Windowsのバイナリをダウンロードした場合、32bitで動作させないと動かないので、gemx.batは以下のように修正する必要があります。
set PATH=C:\Windows\SysWOW64;C:\TracLight\python;C:\TracLight\python\python\Scripts\;%~dp0\scripts
set CCFINDERX_PYTHON_INTERPRETER_PATH=C:\TracLight\python\python.exe
以下の画像はgemx.batで検知した画面の例になります。
その他、散布図なども表示できます。これらのGUIは魅力的といえるでしょう。
コマンドラインから実行する場合は次のようになります。
ccfx p java -d c:\dev\java\
この時出力される、a.ccfxdはバイナリファイルでGemXで開くことが可能です。以下のコマンドでテキスト形式に変換できます。
>ccfx p a.ccfxd > test.txt
VisualBasicの対応
この手のツールとしてはめずらしくVisualBasicを対応しています。
VB6やVBAで作ったコードも解析しているようです。しかし、clsファイルは認識しないのでccfx_prep_scripts.iniを以下のように修正してください。
visualbasic=.vb;.bas;.frm;.cls
その他
・マルチバイトを扱っているソースに対する処理が失敗していることがあります。
・Jenkinsとの連携は調べた限り、簡単にはできそうもないです。
・更新履歴のページがデッドリンクになっていることから、現在はもうメンテナンスされていないようです。
ソースコードがあるので、必要に応じて自分で治す必要があるでしょう。
Jenkinsによる監視
JenkinsのViolationsプラグインを用いることでコードクローンの遷移を監視できます。
https://wiki.jenkins-ci.org/display/JENKINS/Violations
-
Jenkinsのスクリプト上にてワークスペース上にXMLを生成します。
-
プロジェクトの設定のビルド後の処理でReportViolationsのcpdに1.のXMLを指定します。
-
各ビルドを行うことで以下のようなレポートが作成されます。
[…] 僕にそのコピペを直せというのか https://needtec.sakura.ne.jp/wod07672/?p=9264 […]