I have the following Gradle build file: https://github.com/markuswustenberg/jsense/blob/a796055f984ec309db3cc0f3e8340cbccac36e4e/jsense-protobuf/build.gradle which includes:
checkstyle {
// TODO The excludes are not working, ignore failures for now
//excludes '**/org/jsense/serialize/protobuf/gen/**'
ignoreFailures = true
showViolations = false
}
findbugs {
// TODO The excludes are not working, ignore failures for now
//excludes '**/org/jsense/serialize/protobuf/gen/**'
ignoreFailures = true
}
As you can see, I'm trying to exclude auto-generated code in the package org.jsense.serialize.protobuf.gen. I cannot figure out the format of the strings given to the excludes parameter, and the documentation isn't of much help: http://www.gradle.org/docs/1.10/dsl/org.gradle.api.plugins.quality.FindBugs.html#org.gradle.api.plugins.quality.FindBugs:excludes (it just says "The set of exclude patterns.").
So my question is: How should the excludes pattern strings be formatted for both the Findbugs and Checkstyle plugins?
I'm running Gradle 1.10.
Thanks!
EDIT 1: I got the Checkstyle exclude working with the following:
tasks.withType(Checkstyle) {
exclude '**/org/jsense/serialize/protobuf/gen/**'
}
However, using the exact same exclude on the Findbugs plugin doesn't work:
tasks.withType(FindBugs) {
exclude '**/org/jsense/serialize/protobuf/gen/*'
}
EDIT 2: The accepted answer works, and so does using an XML file and filtering on that, like so:
findbugs {
excludeFilter = file("$projectDir/config/findbugs/excludeFilter.xml")
}
and
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<Package name="org.jsense.serialize.protobuf.gen"/>
</Match>
</FindBugsFilter>
EDIT 3: This works great, and no XML file is needed:
def excludePattern = 'org/jsense/serialize/protobuf/gen/'
def excludePatternAntStyle = '**/' + excludePattern + '*'
tasks.withType(FindBugs) {
classes = classes.filter {
!it.path.contains(excludePattern)
}
}
tasks.withType(Checkstyle) {
exclude excludePatternAntStyle
}
tasks.withType(Pmd) {
exclude excludePatternAntStyle
}
SourceTask#exclude filters source files. However, FindBugs primarily operates on class files, which you'll have to filter as well. Try something like:
tasks.withType(FindBugs) {
exclude '**/org/jsense/serialize/protobuf/gen/*'
classes = classes.filter {
!it.path.contains(new File("org/jsense/serialize/protobuf/gen/").path)
}
}
PS: It could be that filtering source files makes no difference (and therefore isn't necessary) in case of FindBugs. (I haven't tried though.)
If someone looking for a modern day solution:
For checkstyle, you can use something like this in build.gradle:
checkstyleMain.exclude '**/org/jsense/serialize/protobuf/gen/**'
If you want to exclude more than one path
solution 1:
checkstyleMain.exclude '**/org/jsense/serialize/protobuf/gen/**'
checkstyleMain.exclude '**/org/example/some/random/path/**'
solution 2:
checkstyleMain {
setExcludes(new HashSet(['**/org/jsense/serialize/protobuf/gen/**', '**/org/example/some/random/path/**']))
}
Related
I'm generating the javadoc using Java 11 and gradle for a project that does not use modules using the configuration below.
The documentation is generated correctly, but navigating to a search result yields a file not found instead of the expected page. There is an extra "undefined/" in the URL before the package and class name (e.g. ".../doc/undefined/package/Class.html").
There is a similar question for javadoc with Maven, but I cannot see how to add the --no-module-directories option in gradle.
task allJavadoc (type: Javadoc, description: 'Generate javadoc from all projects', group: 'Documentation') {
destinationDir = file("$projectDir/doc")
title = "Title"
maxMemory = "2048m"
failOnError true
options.author false
options.version true
options.use true
options.links "https://docs.oracle.com/en/java/javase/11/docs/api/"
options.breakIterator true
subprojects.each { proj ->
proj.tasks.withType(Javadoc).each { javadocTask ->
classpath += javadocTask.classpath
excludes += javadocTask.excludes
includes += "**/*.java"
}
}
}
You need to add a boolean option with the leading hyphen removed:
options.addBooleanOption "-no-module-directories", true
Alternatively, if you're not defining a custom task:
javadoc {
doFirst {
options.addBooleanOption('-no-module-directories', true)
}
}
Adapted from a related post for specifying a module path.
I have a gradle task that uses ant to create code coverage reports via Cobertura. This works as expected when excluding one file:
fileset(dir: classes,
includes:"**/*.class",
excludes:"**/*Test.class")
But when I want to exclude multiple files the *Test.class files remain exlcuded but not the *Jar.class.
fileset(dir: classes,
includes:"**/*.class",
excludes:["**/*Test.class", "**/*Jar.java"])
I'm now testing this with one file but the end goal is to exclude an entire package. What would be the correct syntax for excluding multiple files?
Entire gradle task:
logger.info "Configuring Cobertura Plugin"
configurations{
coberturaRuntime {extendsFrom testRuntime}
}
dependencies {
coberturaRuntime 'net.sourceforge.cobertura:cobertura:2.1.1'
}
def serFile="${project.buildDir}/cobertura.ser"
def classes="${project.buildDir}/"
def classesCopy="${classes}-copy"
task cobertura(type: Test){
dependencies {
testRuntime 'net.sourceforge.cobertura:cobertura:2.1.1'
}
systemProperty "net.sourceforge.cobertura.datafile", serFile
}
cobertura.doFirst {
logger.quiet "Instrumenting classes for Cobertura"
ant {
delete(file:serFile, failonerror:false)
delete(dir: classesCopy, failonerror:false)
copy(todir: classesCopy) { fileset(dir: classes) }
taskdef(resource:'tasks.properties', classpath: configurations.coberturaRuntime.asPath)
'cobertura-instrument'(datafile: serFile) {
fileset(dir: classes,
includes:"**/*.class",
excludes:["**/*Test.class", "**/*Jar.class"])
}
}
}
cobertura.doLast{
if (new File(classesCopy).exists()) {
//create html cobertura report
// ant.'cobertura-report'(destdir:"${project.reportsDir}/cobertura",
// format:'html', srcdir:"src/main/java", datafile: serFile)
//create xml cobertura report
ant.'cobertura-report'(destdir:"${project.reportsDir}/cobertura",
format:'xml', srcdir:"src/main/java", datafile: serFile)
ant.delete(file: classes)
ant.move(file: classesCopy, tofile: classes)
}
}
The answer turned out to be quite simple. Instead of giving the includes and excludes as parameters to fileset it is possible to use multiple include and exclude methods inside a fileset method. So replace the fileset line from my question with this:
fileset(dir: classes) {
include(name: "**/*.class")
exclude(name: "**/*Test.class")
exclude(name: "**/*Jar.class")
}
I found this in gradles documentation about passing nested elements to an Ant task.
See: https://docs.gradle.org/current/userguide/ant.html#example_passing_nested_elements_to_an_ant_task
I'm attempting to create some exclude patterns for a PMD task in Gradle.
My task is generated in the next way:
/* Allows generation of pmd config */
allprojects {
apply plugin: 'pmd'
}
gradle.projectsEvaluated {
subprojects.each() { project ->
if (project.hasProperty('android')) {
project.task("runPmd", type: Pmd) {
description "Run pmd"
group 'verification'
source = fileTree("${project.projectDir}/src/main/java")
ruleSetFiles = files("${project.rootDir}/build-tools/pmd.xml")
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
}
}
}
And the ruleSet is:
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="MyCompany ruleset"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
MyCompany ruleset for Android PMD
</description>
<exclude-pattern>.*/org/jivesoftware/.*</exclude-pattern>
<exclude-pattern>.*/net/java/.*</exclude-pattern>
...rules...
</ruleset>
But in my reports, I'm getting:
Am I doing something wrong? Checking this answer seems that I'm defining the exclude-pattern right, but pmd is analyzing those files.
I was running into the same issue and adding an empty ruleSets [] property seemed to fix it for me.
Make sure to define the rules that you actually want to apply in your ruleset file - i.e. Move them from the ruleSet property block to the file (if you had any there).
This is what my task generation looks like:
// PMD
afterEvaluate {
def variants = plugins.hasPlugin('com.android.application') ?
android.applicationVariants : android.libraryVariants
variants.each { variant ->
def task = tasks.create("pmd${variant.name.capitalize()}", Pmd)
task.group = 'verification'
task.description = "Run PMD for the ${variant.description}."
task.ruleSetFiles = files("pmd-ruleset.xml")
task.ruleSets = []
task.reports {
xml.enabled = false
html.enabled = true
}
def variantCompile = variant.javaCompile
task.source = variantCompile.source
task.dependsOn(variantCompile)
tasks.getByName('check').dependsOn(task)
}
}
I got the hint from this thread:
http://sourceforge.net/p/pmd/discussion/188193/thread/6e9c6017/
Add below snippet in your build.gradle, you can exclude Classes and packages also
pmd {
sourceSets = [ project.sourceSets.main ]
ruleSetFiles = rootProject.files("codequality/pmd-ruleset.xml")
ruleSets = []
pmdMain {
excludes = [
'**/Application.*',
'**/jivesoftware/.*'
]
}
}
For my ruleset.xml for Gradle pmd plugin the following command works:
<ruleset name="Custom Rules">
<!-- Exclude generated open api classes -->
<exclude-pattern>.*/src/main/java/com/tbd/tbd/tbd/.*</exclude-pattern>
<exclude-pattern>.*/src/main/java/com/tbd/tbd/tbd/tbd/.*</exclude-pattern>
...
</ruleset>
Could you please try the command below?
...
<exclude-pattern>.*/src/main/java/net/java/.*</exclude-pattern>
...
Is it possible to integrate the fb-contrib library with Gradle's FindBugs plugin? I've been looking around for a solution for a while but so far I haven't found anything...
If it helps, here's the script I have right now. It's a work in progress but the report is generated correctly.
apply plugin: "findbugs"
task findbugs(type: FindBugs) {
classes = fileTree(project.rootDir.absolutePath).include("**/*.class");
source = fileTree(project.rootDir.absolutePath).include("**/*.java");
classpath = files()
findbugs {
toolVersion = "2.0.3"
ignoreFailures = true
effort = "max"
reportLevel = "low"
reportsDir = file("${projectDir}/reports/findbugs")
sourceSets = [it.sourceSets.main, it.sourceSets.test]
}
tasks.withType(FindBugs) {
reports {
xml.enabled = false
html.enabled = true
}
}
}
Thanks in advance for any answer.
I just came across this very same problem. I was able to solve it as follows:
apply plugin: 'findbugs'
dependencies {
// We need to manually set this first, or the plugin is not loaded
findbugs 'com.google.code.findbugs:findbugs:3.0.0'
findbugs configurations.findbugsPlugins.dependencies
// To keep everything tidy, we set these apart
findbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:6.0.0'
}
task findbugs(type: FindBugs) {
// Add all your config here ...
pluginClasspath = project.configurations.findbugsPlugins
}
Hope that helps!
You can add more Findbugs plugins just by adding them under dependencies for findbugsPlugins
if you place the fb-contrib.jar in Findbugs' plugin directory, it should just automagically get picked up, i would think. Never tried with Gradle tho.
I am using Java 8 with Gradle and trying to add the Google checkstyle rules into the build, but what I get is this error:
"Expected file collection to contain exactly one file, however, it contains 14 files."
My configuration is:
apply plugin: 'checkstyle'
configurations {
checkstyleConfig
}
def versions = [
checkstyle: '8.8',
]
dependencies {
checkstyleConfig "com.puppycrawl.tools:checkstyle:${versions.checkstyle}"
}
checkstyle {
toolVersion = "${versions.checkstyle}"
config = resources.text.fromArchiveEntry(configurations.checkstyleConfig, 'google_checks.xml')
}
The issue here is that configurations.checkstyleConfig includes multiple JAR files: com.puppycrawl.tools:checkstyle, as well as all of its transitive dependencies. Debugging the issue locally, I see that these dependencies are being included:
antlr:antlr:2.7.7
com.google.code.findbugs:jsr305:1.3.9
com.google.errorprone:error_prone_annotations:2.1.3
com.google.guava:guava:23.6-jre
com.google.j2objc:j2objc-annotations:1.1
com.puppycrawl.tools:checkstyle:8.8
commons-beanutils:commons-beanutils:1.9.3
commons-cli:commons-cli:1.4
commons-collections:commons-collections:3.2.2
commons-logging:commons-logging:1.2
net.sf.saxon:Saxon-HE:9.8.0-7
org.antlr:antlr4-runtime:4.7.1
org.checkerframework:checker-compat-qual:2.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.14
The fix for this is fortunately very simple. All you need to do is exclude the transitive dependencies from the Checkstyle dependency, and the rest of your script will work the way you want it to:
dependencies {
checkstyleConfig("com.puppycrawl.tools:checkstyle:${versions.checkstyle}") { transitive = false }
}
btw, for future reference, there's no need to add a new configuration to use this, it's just a matter of filtering the checkstyle dependency from the existing configuration used by the plgin.
This is the config I use:
checkstyle {
config = resources.text.fromArchiveEntry(
configurations.checkstyle.find { it.name.contains('checkstyle') },
'google_checks.xml'
)
}
For anyone interested, this is the Kotlin DSL variant of the config from #thiago answer:
checkstyle {
config = resources.text.fromArchiveEntry(
configurations.checkstyle.get().find { it.name.contains("checkstyle") }!!,
"google_checks.xml"
)
}