It is possible to run the Checkstyle linter from Gradle, without having to write a configuration .xml file. Here is an example:
/// Checkstyle linter
// Run by `gradle check`, which is run by `gradle build`
apply plugin: 'checkstyle'
ext.checkstyleVersion = '10.5.0'
configurations {
checkstyleConfig
}
dependencies {
checkstyleConfig("com.puppycrawl.tools:checkstyle:${checkstyleVersion}") { transitive = false }
}
checkstyle {
toolVersion "${checkstyleVersion}"
ignoreFailures = false
config = resources.text.fromArchiveEntry(configurations.checkstyleConfig, 'google_checks.xml')
}
However, I do not see how to disable/suppress a particular check, still from the build.gradle file.
I want to disable the LineLength check. None of these works:
checkstyle {
...
configProperties += ['LineLength.max': 140]
configProperties += ['LineLength.enabled': false]
configProperties += ['suppressions.suppress': 'LineLength']
}
What is the right invocation, if there is one?
Your apparent intention is start with a stock Checkstyle configuration and customize it for your projects. Let's write a Gradle script to transform the Checkstyle configuration. The script deletes the LineLength module.
import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamResult
import javax.xml.transform.stream.StreamSource
def readCheckstyleConfig() {
def xslt = '''
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
doctype-public="-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
doctype-system="https://checkstyle.org/dtds/configuration_1_3.dtd"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="module[#name='LineLength']">
<!-- Delete this module. -->
</xsl:template>
</xsl:transform>
'''
def transformer = TransformerFactory.newInstance()
.newTransformer(new StreamSource(new StringReader(xslt)))
def xml = resources.text.fromArchiveEntry(
configurations.checkstyleConfig, 'google_checks.xml').asReader()
def stringWriter = new StringWriter()
transformer.transform(new StreamSource(xml), new StreamResult(stringWriter))
return resources.text.fromString(stringWriter.toString())
}
checkstyle {
toolVersion = checkstyleVersion
config = readCheckstyleConfig()
}
The above code merely demonstrates the idea. In practice, you would not copy the code into many build.gradle files, then try to keep the copies in sync. Gradle recommends convention plugins to share build logic across multiple projects.
Related
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>
...
I would like to use the gradle PMD plugin in an enterprise project which is built with gradle.
I have a pmd_rules.xml file which already works, but I can't add own java rules (I get a class not found exception). I followed the tutorial on it's website.
Where do I have to put my own rules so they get recognized by gradle and PMD? Has somebody already done something like that?
pmd.gradle:
apply from: rootProject.file("core/modules.gradle"), to : ext
if(project.name in (modules["modules"] +modules["modules"])){
apply plugin: 'pmd'
pmd {
ignoreFailures = true
ruleSetFiles = rootProject.files("../repo/pmd_rules.xml")
sourceSets = [sourceSets.main,sourceSets.test]
targetJdk = org.gradle.api.plugins.quality.TargetJdk.VERSION_1_7
ruleSets = []
toolVersion = "5.0.5"
}
}
tasks.withType(Pmd) {
pmdClasspath += file("path/to/rules.jar")
}
For latest Gradle pmd plugin you need to do the following things:
Add your library with pmd rules to plugin classpath
https://github.com/dgroup/arch4u-pmd#gradle-buildgradle
dependencies {
...
pmd "io.github.groupid:libid:versionid"
pmd "commons-io:commons-io:2.11.0"
...
}
Include ruleset from your lib
https://github.com/dgroup/arch4u-pmd#include-arch4u-pmd-rules-into-your-existing-custom-ruleset
<?xml version="1.0"?>
<ruleset name="pmd ruleset with your rules">
...
<rule ref="io/github/path-to-ruleset-from-your-lib.xml"/>
...
</ruleset>
or define particular rules in your
https://github.com/dgroup/arch4u-pmd#reconfigure-a-rule
<?xml version="1.0"?>
<ruleset name="pmd ruleset with your rules">
...
<!-- 2. Reconfigure rule with expected property -->
<rule name="RuleFromYourLibrary" class="io.github.RuleFromYourLibrary">
<priority>3</priority>
<properties>
...
</properties>
</rule>
...
</ruleset>
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/**']))
}
I want to generate a pom file that does not include dependencies. I have tried clearing the dependencies using the code below, however the dependencies are still listed in the generated pom.
install.doFirst {
repositories.mavenInstaller {
pom.dependencies.clear()
}
}
Why I need this: I need a pom file to be included with my jar when I upload it to a "home brewed" service, however the service blows up when it reads '+' as the version for the dependencies (I am using dynamic dependencies).
uploadArchives {
repositories {
mavenDeployer {
// Do not write any dependencies into the POM
pom*.whenConfigured { pom -> pom.dependencies.clear() }
}
}
}
I ended up using the solution below calling gradle cleanPom. Basically I use an XML parser to edit the generated POM.
apply plugin: 'maven'
pomFileLocation="build/poms/noDeps.pom"
/**
* Creates pom with dependencies
*/
task writeNewPom << {
pom {}.writeTo(pomFileLocation)
}
/**
* Reads and Overwrites POM file removing dependencies
*/
task cleanPom(dependsOn: writeNewPom) << {
def xml = new XmlParser().parse(pomFileLocation)
def nodes = []
xml.dependencies[0].each {
nodes.add(it)
}
def parrent = nodes.first().parent()
nodes.each {
parrent.remove(it)
}
new XmlNodePrinter(new PrintWriter(new FileWriter(pomFileLocation))).print(xml)
}
I want to setup the FindBugsExtension to Gradle. It works but I'm unable to exclude specific patterns with the excludeFilter option.
I have the following gradle FindBugs definition:
findbugs {
toolVersion = "2.0.1"
reportsDir = file("$project.buildDir/findbugsReports")
effort = "max"
reportLevel = "high"
excludeFilter = file("$rootProject.projectDir/config/findbugs/excludeFilter.xml")
}
In the excludeFilter.xml I have the following exclude defined:
<FindBugsFilter>
<Match>
<Bug pattern="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE"/>
</Match>
</FindBugsFilter>
But when I run gradle findBugsMain it fails because it could find FindBugs errors:
<BugCollection version="2.0.1" sequence="0" timestamp="1348055542169" analysisTimestamp="1348055545581" release="">
<!-- ... -->
<BugInstance type="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE" priority="2" abbrev="NP" category="STYLE">
<!-- ... -->
Okay, I've found the solution from here.
Opposed to the documentation the excludeFilter needs to be defined per task due to a bug in Gradle version 1.2.
So the full configuration would look like this for 1.2:
findbugs {
toolVersion = "2.0.1"
reportsDir = file("$project.buildDir/findbugsReports")
effort = "max"
reportLevel = "high"
}
tasks.withType(FindBugs) {
excludeFilter = file("$rootProject.projectDir/config/findbugs/excludeFilter.xml")
}