Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuring CPD #9

Open
Okeanos opened this issue Nov 8, 2016 · 12 comments
Open

Configuring CPD #9

Okeanos opened this issue Nov 8, 2016 · 12 comments

Comments

@Okeanos
Copy link

Okeanos commented Nov 8, 2016

So, the usage explanation shows how to configure everything but CPD. How do I pass custom configuration to the CPD task?

@jsotuyod
Copy link
Member

Currently the DSL provides no extra configuration for CPD.

By default, CPD will run once per module, including all sources; ignoring both literals and identifiers; with language defined to 'java'.

You can however re-configure CPD tasks manually through the defined task properties

For instance, you could do something such as:

project.tasks.withType(CPDTask).all {
  it.ignoreLiterals = false
  it.ignoreIdentifiers = false
}

I there anything in particular you would like to configure? Maybe you are hitting a use case I wasn't considering and should extend the current DSL.

@Okeanos
Copy link
Author

Okeanos commented Nov 14, 2016

Well, my original assumption was that all of the CPD parameters as described here would be somehow available directly within the DSL similarly to how PMD and Checkstyle configuration is made available. Manually reconfiguring the task as you described may actually be sufficient, I'd have to check. Personally, I'd still prefer exposed options, though, if only for consistency's sake.
In any case thanks for the explanation.

@jsotuyod
Copy link
Member

PMD and Checkstyle tasks are implemented by Gradle itself. CPD is not, so we defined it ourselves.

We can however map other options to it. We just didn't because we weren't using them ATM. Feel free to submit a PR 'though!

As for the DSL, we are not currently exposing all properties from the tasks, only rule config / suppression filters, and whether to fail or not on errors. We are favoring sane defaults for everything else (files to analyze, the version of each tool, report location, etc.).

We may add cpd configuration through the DSL, 'though I'm not sure when in our roadmap. If you are eager to get it, feel free to send a PR for review!

@Okeanos
Copy link
Author

Okeanos commented Jan 6, 2017

Okay, just checked … your initial solution appears to work, however, not all of the options described in the CPD documentation are available to be set/modified using the task.

@XVicarious
Copy link

Similarly, is it possible for an option for an xslt file as per the documentation for html output?

@jsotuyod
Copy link
Member

@XVicarious the XSLT transform is not a standard part of CPD, but used as a separate ant task (the xsl file itself is shipped with PMD, but no logic to apply it). That's why the documentation only mentions it for Ant.

It would technically be possible to replicate this (as Gradle can run arbitrary ant tasks), but most probably this is better off as a feature request for PMD itself; since that request exceeds this plugin.

PMD has a long-standing tech debt regarding CPD report rendering (PMD itself is good), as shown on pmd/pmd#198 Adding report formats for CPD would be much easier if both reporting systems are merged (disclaimer, I'm a PMD maintainer myself).

@LethiferousMoose
Copy link

LethiferousMoose commented Mar 26, 2019

I attempted to follow your example for customizing the task, using it to exclude tests, but it does not work:

tasks.withType(com.monits.gradle.sca.task.CPDTask).all {
     FileTree srcDir = project.fileTree("$project.projectDir/src/")
     srcDir.include '**/*.java'
     srcDir.exclude '**/test/**'

     it.inputFiles = srcDir
 }

Any suggestions?

@jsotuyod
Copy link
Member

jsotuyod commented Mar 27, 2019

@LethiferousMoose my guess is that you have an issue with the order in which configurations are applied…

tasks.withType(com.monits.gradle.sca.task.CPDTask).all will call your closure when a new CPDTask is added to the task container. However, if we look at:

Task cpdTask = project.task(CPD, type:CPDTask) { CPDTask it ->
it.ignoreFailures = extension.getIgnoreErrors()
it.ignoreLiterals = true
it.ignoreIdentifiers = true
FileTree srcDir = project.fileTree("$project.projectDir/src/")
srcDir.include '**/*.java'
srcDir.exclude '**/gen/**'
it.inputFiles = srcDir
it.outputFile = new File("$project.buildDir/reports/pmd/cpd.xml")
}

the task is created and THEN it's configured. It seems your configuration is applied as soon as the task is created and added to the task container; and then the default configuration overrides it.

Try doing this after applying the plugin:

plugins {
  id 'com.monits.staticCodeAnalysis' version '2.6.9' // it's important to apply the plugin first!
}

afterEvaluate {
    tasks.withType(com.monits.gradle.sca.task.CPDTask).all {
        FileTree srcDir = project.fileTree("$project.projectDir/src/")
        srcDir.include '**/*.java'
        srcDir.exclude '**/test/**'

        it.inputFiles = srcDir
    }
}

@LethiferousMoose
Copy link

LethiferousMoose commented Mar 27, 2019

@jsotuyod That seems to have fixed my issue, thanks!

I do have a followup question though. I'm currently using this soley for CPD in gradle, we use our own versions for pmd, spotbugs, checkstyle, etc. If I have those turned off via the DSL, does the plugin still try to get the artifacts for your versions? I don't want to encounter any weird dependency issues.

@jsotuyod
Copy link
Member

@LethiferousMoose no, the dependencies are only added / tasks defined if a given tool is enabled.

Moreover, even if CPD and PMD are bundled together in the same artifacts (pmd-core and pmd-java), the plugin uses separate gradle configurations for each task, so you may use different versions of PMD for each (even if not the default behavior).

Non the less, I'm curious as to why use custom versions for PMD / Checkstyle (Spotbugs is not currently supported), as the plugin will always try and use the latest known version to be compatible with your setup (Java version + Gradle version)… is there a use-case I'm missing?

@LethiferousMoose
Copy link

LethiferousMoose commented Mar 27, 2019

@jsotuyod I was digging through your code, and it looked like you had everything hard-coded in ToolsVersions, currently your PMD is at 6.11, I recently upgraded to 6.12. Is this not the case? I didn't do an extremely deep dive, so I may have missed some nuances. Also our current gradle version (3.2?) is lagging a bit behind, our PMD version for our gradle was pre-5.0.

@jsotuyod
Copy link
Member

@LethiferousMoose I do manually raise the used version to latest on each release. Using dynamic dependencies hurts configuration time, and Checkstyle is not even using semantic versioning, so I can't rely on a future release working without actually testing it.

I'm about ready to make a new release, I should update to PMD 6.13.0 (due this weekend) for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants