import org.gradle.api.plugins.quality.CodeNarcExtension
plugins {
id 'codenarc'
}
dependencies {
codenarc 'org.codenarc:CodeNarc:3.6.0-groovy-4.0'
}
extensions.configure(CodeNarcExtension) {
it.configFile = file('config/codenarc/codenarc.groovy')
it.maxPriority1Violations = 0
it.maxPriority2Violations = 0
it.maxPriority3Violations = 0
}
16 Building a Successful Application
Version: 7.0.8-SNAPSHOT
Table of Contents
16 Building a Successful Application
Building a successful Grails application goes beyond writing features. Code analysis, consistent styling, continuous integration, and reliable release processes help maintain quality as your project grows. This section covers tools and practices that support long-term project health.
16.1 Code Analysis and Styling for Groovy
CodeNarc is a static analysis tool for Groovy that finds defects, poor coding practices, inconsistencies, style issues, and more. Grails projects can integrate CodeNarc via the Gradle CodeNarc plugin.
Adding Code Analysis to Your Build
Apply the CodeNarc plugin and configure it using extensions.configure():
Use the -groovy-4.0 variant of CodeNarc for Grails 7 projects (which use Groovy 4.x). The plain artifact without a -groovy-4.0 suffix is built for Groovy 3.x and will not work correctly.
|
You can then run CodeNarc with:
$ ./gradlew codenarcMain
The HTML report is written to build/reports/codenarc/main.html.
GORM AST Compatibility
CodeNarc provides pre-built rulesets that can be imported as a group using the ruleset() syntax:
// config/codenarc/codenarc.groovy - DO NOT use this approach in Grails projects
ruleset {
ruleset('rulesets/basic.xml')
ruleset('rulesets/formatting.xml')
ruleset('rulesets/unused.xml')
}
Importing entire rulesets with ruleset('rulesets/xxx.xml') in a Grails project causes compilation failures. This is because some CodeNarc rules (known as "enhanced" rules) perform semantic analysis at Groovy compiler phase 4. These enhanced rules attempt to resolve AST-transformed classes such as OrderedGormTransformation and ServiceTransformation, but CodeNarc compiles each source file independently without GORM’s AST transformation processors on its classpath. The result is ClassNotFoundException or NoClassDefFoundError during analysis.
|
Adding compilationClasspath to the CodeNarc Gradle task helps with basic class resolution but does not make GORM’s transformation processors available, so enhanced rules still fail.
Recommended Configuration
The solution is to list individual rules explicitly rather than importing entire rulesets. This avoids pulling in enhanced rules that require GORM’s AST infrastructure. The Grails framework’s own build uses this approach:
// config/codenarc/codenarc.groovy
ruleset {
description 'A Codenarc ruleset for the Grails codebase'
BracesForClass
ClassStartsWithBlankLine {
ignoreInnerClasses = true
}
ClosureStatementOnOpeningLineOfMultipleLineClosure
ConsecutiveBlankLines
FileEndsWithoutNewline
NoTabCharacter
DuplicateImport
ImportFromSamePackage
Indentation
MisorderedStaticImports {
comesBefore = false // static imports should come last
}
MissingBlankLineAfterImports
MissingBlankLineAfterPackage
MissingBlankLineBeforeAnnotatedField
NoWildcardImports
SpaceAfterCatch
SpaceAfterClosingBrace
SpaceAfterComma
SpaceAfterFor
SpaceAfterIf
SpaceAfterMethodCallName
SpaceAfterMethodDeclarationName
SpaceAfterNotOperator
SpaceAfterOpeningBrace {
ignoreEmptyBlock = true
}
SpaceAfterSemicolon
SpaceAfterSwitch
SpaceAfterWhile
SpaceAroundClosureArrow
SpaceAroundMapEntryColon {
characterAfterColonRegex = ' '
}
SpaceAroundOperator {
ignoreParameterDefaultValueAssignments = false
}
SpaceBeforeClosingBrace {
ignoreEmptyBlock = true
}
SpaceBeforeOpeningBrace
SpaceInsideParentheses
UnnecessaryConstructor
UnnecessaryDotClass
UnnecessaryGroovyImport
UnnecessaryGString
UnnecessaryOverridingMethod
UnnecessaryPublicModifier
UnnecessarySafeNavigationOperator
UnnecessarySemicolon
UnusedImport
}
This is the exact ruleset used by the Grails framework’s own build. It covers formatting, imports, spacing, and unnecessary code - all without triggering GORM AST compatibility issues. You can add additional individual rules as needed.
| You can find the full list of available CodeNarc rules at codenarc.org. Add individual rules as needed, testing that each one compiles cleanly against your Grails source files. |
Separate Ruleset for Tests
Spock specifications often use patterns that trigger style rules (method names with spaces, loose typing, mock syntax). You can configure a separate, more lenient ruleset for test sources:
tasks.named('codenarcTest', CodeNarc) {
configFile = file('config/codenarc/codenarc-test.groovy')
}
Reference
The grails-server-timing plugin provides a complete working example of CodeNarc and Checkstyle configuration using Gradle convention plugins in its build-logic/ directory. The Grails framework’s own CodeNarc ruleset can be found in the grails-core repository under build-logic/plugins/src/main/resources/META-INF/org.apache.grails.buildsrc.codestyle/codenarc/codenarc.groovy. Both are reliable starting points for any Grails project.