利用PMD工具检测代码中的复制粘贴

参考文章链接.
在一个工程中, 复制粘贴一段代码永远是百害而无一益的, 复制粘贴的代码导致的是 bug 的复制, 难于维护, 代码体积变大等各种问题.

所以在日常工作中, 应该引入工具对代码进行检查, 常用的工具是 PMD. 它配合Swiftlint, 可以做到代码的静态检查和复制粘贴代码检查.

下面主要来介绍 PMD 工具的使用.

在 Xcode build 时运行复制粘贴检查

首先利用 HomeBrew 安装 PMD:

brew install pmd

安装好 PMD 后, 就可以在 Xcode 中添加 Run Script 脚本了:

# Running CPD
pmd cpd --files ${EXECUTABLE_NAME} --minimum-tokens 50 --language swift --encoding UTF-8 --format net.sourceforge.pmd.cpd.XMLRenderer > cpd-output.xml --failOnViolation true
# Running script
php ./cpd_script.php -cpd-xml cpd-output.xml

首先需要将其中的 ${EXECUTABLE_NAME} 替换为工程名称, 比如 MyApp 等.

上面的脚本中使用 pmd 进行复制粘贴检查, 检查结果会存放在 cpd-output.xml 文件中. --minimum-tokens 的值是一个经验值, 这里的 50 适合 swift.(参考文章内作者给的经验值, 这个需要根据具体情况确定.)

另外脚本中需要 php 对输出脚本进行分析并显示到 Xcode 中, 如果没有安装 php, 则需要安装.

还有需要的 cpd_script.php 文件, 需要放到工程根目录, 它的作用是利用之前生成的检查结果文件, 将检查的结果显示到 Xcode 中:

duplication as $duplication) {
    $files = $duplication->xpath('file');
    foreach ($files as $file) {
        echo $file['path'].':'.$file['line'].':1: warning: '.$duplication['lines'].' copy-pasted lines from: '
            .implode(', ', array_map(function ($otherFile) { return $otherFile['path'].':'.$otherFile['line']; },
            array_filter($files, function ($f) use (&$file) { return $f != $file; }))).PHP_EOL;
    }
}
?>

关于这个 php 脚本为什么要这么写, 可以参考这篇文章.

安装--->设置 run script 脚本----> 放入辅助 php 脚本. 简单三步, 检查代码中的复制粘贴就是分分钟的事情.

注意事项

发现一个不能提示复制粘贴代码的问题, 如果实际使用的时候没有正常检测到复制粘贴的代码, 可以尝试 clean 一次后再进行检测.

附录 token 限制值的确定

在一个文件中引入如下测试代码:

    public func add() {
        let a = 3
        let b = 4
        let c = 5
        let result = a + b + c
        print(result)
    }

    public func somethingPrint() {
        let a = 3
        let b = 4
        let c = 5
        let result = a + b + c
        print(result)
    }

一看就知道两个方法体中的代码是复制的, 此时 --minimum-tokens 设置为 50 的时候检测不到, 若降低到 40, 仍然检测不到, 降低到 30, 可以检测到了. 通过这个方式可以确定自己需要的 token 值设置.
一定注意 --minimum-tokens 不能太高也不能太低, 太低的话检测到一个词都是复制的, 太高的话又会什么都检测不到.

你可能感兴趣的:(利用PMD工具检测代码中的复制粘贴)