使用Gradle和PMD的复制/粘贴检测器

4

我想在我的Gradle构建中使用复制/粘贴检测器。

这就是为什么我决定将以下Ant任务(我在这里找到)翻译成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,具体的堆栈跟踪信息在这里

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

谢谢!

3个回答

8
您还可以使用我的gradle-cpd-plugin。有关更多信息,请参见https://github.com/aaschmid/gradle-cpd-plugin。应用cpd插件会自动将其添加为check任务的依赖项。
注意:我对扩展名(请参阅toolVersion)和任务的名称cpd不太满意,欢迎提出建议;-)
目前,它是版本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

来自Gradle论坛的人建议您在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'

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的贡献。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接