将PMD的复制/粘贴检测器与Gradle一起使用

时间:2013-12-07 22:18:55

标签: ant gradle pmd

我想在Gradle版本中使用复制/粘贴检测器。

这就是为什么我决定将以下Ant任务(我发现here)转换为Gradle语法:

<target name="cpd">
    <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask" />
    <cpd minimumTokenCount="100" outputFile="/home/tom/cpd.txt">
        <fileset dir="/home/tom/tmp/ant">
            <include name="**/*.java"/>
        </fileset>
    </cpd>
</target>

这就是翻译目前的样子:

check << {
        ant.taskdef(name: 'cpd', classname: 'net.sourceforge.pmd.cpd.CPDTask', classpath: configurations.pmd.asPath)
        ant.cpd(minimumTokenCount: '100', outputFile: file('build/reports/pmd/copyPasteDetector.txt').toURI().toString()) {
            fileset(dir: 'src'){
                include(name: '**.java')
        }
    }
}

不幸的是,调用gradle check会产生net.sourceforge.pmd.cpd.ReportException,堆栈跟踪为here

如何使用Gradle 1.9使用复制/粘贴检测器扫描源代码?

谢谢!

3 个答案:

答案 0 :(得分:7)

您也可以使用我的gradle-cpd-plugin。有关详细信息,请参阅https://github.com/aaschmid/gradle-cpd-plugin。应用cpd插件会自动将cpd添加为check任务的依赖项。

注意:我对名称cpd的扩展名(参见toolVersion)和任务,建议表示欢迎,我不满意; - )

目前,它是版本0.1但我正在内部切换使用CPD的ant任务直接调用它。这将包括对所有参数的支持等。这是一个用法示例:

apply plugin: 'cpd'

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'de.aaschmid.gradle.plugins:gradle-cpd-plugin:0.1'
    }
}

// optional - default is 5.1.0
cpd {
    toolVersion = '5.0.5'
}

tasks.cpd {
    reports {
        text.enabled = true
        xml.enabled = false
    }
    source = files('src/main/java')
}

答案 1 :(得分:1)

来自gradle forums的家伙建议您在gradle中使用CPD:

task cpd(dependsOn: ':pmdSetup') {
    // Combine all source sets
    allSource = files {
        allprojects.findAll { proj ->
            proj.hasProperty("sourceSets")
        }.collect { proj ->
            proj.sourceSets.collect { ss ->
                ss.java
            }
        }
    }
    // Declare this task's inputs and outputs.
    inputs.files allSource
    outDir = file("$buildDirName/cpd")
    outputs.dir outDir
    //    outputs.files file("$outDir.path/cpd.xml")
    doLast {
        outDir.mkdirs()
        // Keep a reference to the gradle project for use inside the
        // ant closure, where "project" refers to the ant project.
        gproj = project
        ant {
            cpd(minimumTokenCount: '100', format: 'xml',
                    outputFile: outDir.path + '/cpd.xml') {
                fileset(dir: projectDir.getPath()) {
                    // Convert the gradle sourceSet to an ant
                    // fileset.
                    allSource.each { file ->
                        include(name: gproj.relativePath(file))
                    }
                }
            }
        }
    }
}

,当然还有apply plugin: 'pmd'之前。

答案 2 :(得分:1)

outputFile的定义导致了这个问题。

我改编了这个build.gradle,我现在对以下解决方案感到满意:

check << {
    File outDir = new File('build/reports/pmd/')
    // Make sure the output dir exists to prevent a ReportException
    outDir.mkdirs()

    ant.taskdef(name: 'cpd', classname: 'net.sourceforge.pmd.cpd.CPDTask',
                classpath: configurations.pmd.asPath)

    ant.cpd(minimumTokenCount: '100', format: 'text', 
        outputFile: new File(outDir , 'cpd.txt')) {
        fileset(dir: "src/main/java") {
            include(name: '**/*.java')
        }
    }
}

感谢Andrey Regentov和Perryn Fowler的投入。