Search code examples
mavengroovycodenarc

How to make CodeNarc force maven build to fail


I'm trying to integrate CodeNarc into a maven based project and I've been running into problems. I want to use a custom ruleset, and when a rule is violated, I'd like my maven build to fail.

How can I configure codenarc so that violations of rules lead to a failure when I run the following?

mvn clean install

Also, the documentation for configuring CodeNarc in a POM doesn't explain how to reference where my custom ruleset is. Any advice for how to set that up? Thanks!

When I run mvn clean install with the configurations below (I have a groovy file with blatant violations in accordance with my ruleset)

My build succeeds. :(

I tried referencing my own ruleset and no violations were being produced. I took away a rulesetfiles property in the POM and it started producing violations. (But I don't get to choose my own)

Anyone know how to make it actually read a custom rule set file? I tried with both xml and groovy.

Here's my ruleset and plugin config from my POM:

<ruleset xmlns="http://codenarc.org/ruleset/1.0"; 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
    xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd";
    xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd">;

    <description>Dummy rule set</description>

    <rule class='org.codenarc.rule.formatting.SpaceAfterIf'>
        <property name='priority' value='1'/>
    </rule>

    <rule class='org.codenarc.rule.basic.EmptyIfStatement'>
        <property name='priority' value='1'/>
    </rule>
</ruleset>

I referenced this ruleset in my POM like this:

<groupId>org.codehaus.mojo</groupId>
<artifactId>codenarc-maven-plugin</artifactId>
<version>0.18-1</version>
<configuration>
    <sourceDirectory>${basedir}/src/test/groovy</sourceDirectory>
    <maxPriority1Violations>0</maxPriority1Violations>
    <maxPriority2Violations>0</maxPriority2Violations>
    <maxPriority3Violations>0</maxPriority3Violations>
    <rulesetfiles>${basedir}/rulesets/ruleset.xml</rulesetfiles>
    <xmlOutputDirectory>${basedir}/</xmlOutputDirectory>
</configuration>
<executions>
    <execution>
        <id>execution1</id>
        <phase>install</phase>
        <goals>
            <goal>codenarc</goal>
        </goals>
    </execution>
</executions>


Solution

  • I was struggling with the same some time ago. I remember it was possible to run with maven properly but I don't have this config. Why? Because CodeNarc needs to compile your sources for purpuse of some rules execution. But codenarc maven plugin doesn't pass classpath and compilation was failing.

    So I went for different approach which is running CodeNarc as a test source with ant task. It looks like:

    import spock.lang.Specification
    
    class GroovyCodeNarcStaticAnalysisRunner extends Specification {
    
        private static final GROOVY_FILES = '**/*.groovy'
        private static final ANALYSIS_SCOPE = 'src/main/groovy'
        private static final RULESET_LOCATION = 'file:tools/static-analysis/codenarc.xml'
        private static final HTML_REPORT_FILE = 'target/codenarc-result.html'
        private static final XML_REPORT_FILE = 'target/codenarc-result.xml'
    
        def 'Groovy code should meet coding standards'() {
            given:
            def ant = new AntBuilder()
            ant.taskdef(name: 'codenarc', classname: 'org.codenarc.ant.CodeNarcTask')
    
            expect:
            ant.codenarc(
                    ruleSetFiles: RULESET_LOCATION,
                    maxPriority1Violations: 0,
                    maxPriority2Violations: 0,
                    maxPriority3Violations: 0)
                    {
                        fileset(dir: ANALYSIS_SCOPE) {
                            include(name: GROOVY_FILES)
                        }
                        report(type: 'text') {
                            option(name: 'writeToStandardOut', value: true)
                        }
                        report(type: 'xml') {
                            option(name: 'outputFile', value: XML_REPORT_FILE)
                        }
                        report(type: 'html') {
                            option(name: 'outputFile', value: HTML_REPORT_FILE)
                        }
                    }
        }
    }
    

    You don't need to use Spock's Specification for that. Any test runner will do. On the maven side it's enough to make CodeNarc dependency configured with scope test.