Skip to content

Commit dd033e5

Browse files
authored
Merge pull request #15404 from jamesfredley/docs/codenarc-gorm-compatibility
Document CodeNarc configuration for Grails projects
2 parents db9083d + ceb3e52 commit dd033e5

File tree

3 files changed

+182
-0
lines changed

3 files changed

+182
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
////
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
https://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
////
19+
20+
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.
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
////
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
https://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
////
19+
20+
https://codenarc.org/[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 https://docs.gradle.org/current/userguide/codenarc_plugin.html[CodeNarc plugin].
21+
22+
==== Adding Code Analysis to Your Build
23+
24+
Apply the CodeNarc plugin and configure it using `extensions.configure()`:
25+
26+
[source,groovy]
27+
----
28+
import org.gradle.api.plugins.quality.CodeNarcExtension
29+
30+
plugins {
31+
id 'codenarc'
32+
}
33+
34+
dependencies {
35+
codenarc 'org.codenarc:CodeNarc:3.6.0-groovy-4.0'
36+
}
37+
38+
extensions.configure(CodeNarcExtension) {
39+
it.configFile = file('config/codenarc/codenarc.groovy')
40+
it.maxPriority1Violations = 0
41+
it.maxPriority2Violations = 0
42+
it.maxPriority3Violations = 0
43+
}
44+
----
45+
46+
NOTE: 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.
47+
48+
You can then run CodeNarc with:
49+
50+
[source,bash]
51+
----
52+
$ ./gradlew codenarcMain
53+
----
54+
55+
The HTML report is written to `build/reports/codenarc/main.html`.
56+
57+
==== GORM AST Compatibility
58+
59+
CodeNarc provides pre-built rulesets that can be imported as a group using the `ruleset()` syntax:
60+
61+
[source,groovy]
62+
----
63+
// config/codenarc/codenarc.groovy - DO NOT use this approach in Grails projects
64+
ruleset {
65+
ruleset('rulesets/basic.xml')
66+
ruleset('rulesets/formatting.xml')
67+
ruleset('rulesets/unused.xml')
68+
}
69+
----
70+
71+
WARNING: 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.
72+
73+
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.
74+
75+
==== Recommended Configuration
76+
77+
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:
78+
79+
[source,groovy]
80+
----
81+
// config/codenarc/codenarc.groovy
82+
ruleset {
83+
84+
description 'A Codenarc ruleset for the Grails codebase'
85+
86+
BracesForClass
87+
ClassStartsWithBlankLine {
88+
ignoreInnerClasses = true
89+
}
90+
ClosureStatementOnOpeningLineOfMultipleLineClosure
91+
ConsecutiveBlankLines
92+
FileEndsWithoutNewline
93+
NoTabCharacter
94+
DuplicateImport
95+
ImportFromSamePackage
96+
Indentation
97+
MisorderedStaticImports {
98+
comesBefore = false // static imports should come last
99+
}
100+
MissingBlankLineAfterImports
101+
MissingBlankLineAfterPackage
102+
MissingBlankLineBeforeAnnotatedField
103+
NoWildcardImports
104+
SpaceAfterCatch
105+
SpaceAfterClosingBrace
106+
SpaceAfterComma
107+
SpaceAfterFor
108+
SpaceAfterIf
109+
SpaceAfterMethodCallName
110+
SpaceAfterMethodDeclarationName
111+
SpaceAfterNotOperator
112+
SpaceAfterOpeningBrace {
113+
ignoreEmptyBlock = true
114+
}
115+
SpaceAfterSemicolon
116+
SpaceAfterSwitch
117+
SpaceAfterWhile
118+
SpaceAroundClosureArrow
119+
SpaceAroundMapEntryColon {
120+
characterAfterColonRegex = ' '
121+
}
122+
SpaceAroundOperator {
123+
ignoreParameterDefaultValueAssignments = false
124+
}
125+
SpaceBeforeClosingBrace {
126+
ignoreEmptyBlock = true
127+
}
128+
SpaceBeforeOpeningBrace
129+
SpaceInsideParentheses
130+
UnnecessaryConstructor
131+
UnnecessaryDotClass
132+
UnnecessaryGroovyImport
133+
UnnecessaryGString
134+
UnnecessaryOverridingMethod
135+
UnnecessaryPublicModifier
136+
UnnecessarySafeNavigationOperator
137+
UnnecessarySemicolon
138+
UnusedImport
139+
}
140+
----
141+
142+
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.
143+
144+
TIP: You can find the full list of available CodeNarc rules at https://codenarc.org/codenarc-rules-formatting.html[codenarc.org]. Add individual rules as needed, testing that each one compiles cleanly against your Grails source files.
145+
146+
==== Separate Ruleset for Tests
147+
148+
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:
149+
150+
[source,groovy]
151+
----
152+
tasks.named('codenarcTest', CodeNarc) {
153+
configFile = file('config/codenarc/codenarc-test.groovy')
154+
}
155+
----
156+
157+
==== Reference
158+
159+
The https://github.com/grails-plugins/grails-server-timing[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 https://github.com/apache/grails-core[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.

grails-doc/src/en/guide/toc.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ testing:
304304
usefulProperties: Useful Properties
305305
integrationTesting: Integration Testing
306306
functionalTesting: Functional Testing
307+
bestPractices:
308+
title: Building a Successful Application
309+
codeAnalysisGroovy: Code Analysis and Styling for Groovy
307310
i18n:
308311
title: Internationalization
309312
understandingMessageBundles: Understanding Message Bundles

0 commit comments

Comments
 (0)