Contents
You can configure rules within the RuleSet file or within the “codenarc.properties” file. Both of these approaches are described in the sections below.
NOTE: Keep in mind that RuleSet files can be nested (to any depth). That, along with the “codenarc.properties” file support, allows multiple layers of rule configuration. The hierarchical layering of configuration can come in handy within organizations comprised of multiple teams or projects. For instance, you can define an organization RuleSet file. Then each team can define its own RuleSet file and/or a “codenarc.properties” file, customizing the rules from the top-level file.
Creating a RuleSet describes how to create a new RuleSet and configure the rules within it.
Here is an example of a Groovy RuleSet file that configures all three rules that it contains:
ruleset {
CyclomaticComplexity {
maxMethodComplexity = 1
}
ConfusingTernary(priority:3)
StatelessClass {
name = 'StatelessDao'
applyToClassNames = '*Dao'
}
}
Here is another example of a Groovy RuleSet file. This one includes another RuleSet, and configures a couple of the rules that it contains:
ruleset {
ruleset('rulesets/basic.xml') {
CatchThrowable {
priority = 1
}
EqualsAndHashCode priority:3
}
}
If you have an XML RuleSet, then you can configure rules when you include a whole RuleSet
using \*ruleset-ref\
*, as in the following example:
<ruleset-ref path='rulesets/size.xml'>
<rule-config name='ClassSize'>
<property name='maxLines' value='500'/>
</rule-config>
</ruleset-ref>
Or you can configure Rules that you include individually using \*rule\
*, as in the following example:
<rule class='org.codenarc.rule.naming.VariableNameRule'>
<property name="finalRegex" value="F_[A-Z0-9]*"/>
<property name='priority' value='1'/>
</rule>
CodeNarc reads the properties file named “codenarc.properties”, if found on the classpath,
and applies the property values to any matching Rules. You can optionally override the location
of the properties file by setting the “codenarc.properties.file” system property to the path or
URL of the properties file. You can also override the location of the properties file by
specifying the -properties=FILENAME
command-line parameter (if executing CodeNarc from the
command-line). In either case, that filename can include a “file:” URL to load from a relative
or absolute path on the filesystem (e.g., “file:relative/path/override-codenarc.properties”).
If the properties file is not found, then it logs a warning message but does nothing else.
For each properties entry of the form [rule-name].[property-name]=[property-value], the named property for the rule matching rule-name is set to the specified property-value. Properties entries not of this form or specifying rule names not within the current RuleSet are ignored.
NOTE: Overriding a rule’s name through “codenarc.properties” is not allowed.
The following example “codenarc.properties” file configures several rules. Note that
Fields with Integer
, String
and Boolean
values are configured.
# Sample RuleSet configuration
# Entries should be of the form: [rule-name].[property-name]=[property-value]
CatchThrowable.doNotApplyToClassNames=BaseController,AbstractTest
CatchThrowable.priority = 1
ReturnFromFinallyBlock.priority = 1
# Turn off this rule
AbstractClassName.enabled=false
# Unset special naming for final fields -- use base 'regex' value for all names
FieldName.finalRegex=
# Make sure all field names are prefixed with '_'
FieldName.regex=_[a-z][a-zA-Z0-9]*
Note that you cannot add new rules using the “codenarc.properties” file, though you can disable (turn off) rules.
The rules included with CodeNarc (as well as any subclasses of AbstractRule
) provide
several standard properties that can be used to configure how rules are applied to source files.
The applyToClassNames
and doNotApplyToClassNames
properties enable filtering the
classes to which the rule is applied.
If applyToClassNames
is not empty or null, then the rule is only
applied to classes matching one of the specified class names. Likewise, if
doNotApplyToClassNames
is not empty or null, then the rule is NOT applied to classes
matching any of the specified class names.
Both of these properties can specify either a single class name or a comma-separated list of names. The names may optionally contain wildcard characters (‘’ or ‘?’). The wildcard character ‘’ matches a sequence of zero or more characters in the input string. The wildcard character ‘?’ matches exactly one character in the input string.
Each class name(s) can be either a fully-qualified class name (including the package) or else a class name without a package.
For instance, in the following example “codenarc.properties” excerpt, the CatchThrowable rule
is NOT applied to classes named “BaseController” or “AbstractTest”, no matter what package they
are in (if any). The FieldName rule, on the other hand, is only applied to the
org.codenarc.CodeNarc
class or any of the classes within org.codenarc.extra
package.
CatchThrowable.doNotApplyToClassNames=BaseController,AbstractTest
FieldName.applyToClassNames=org.codenarc.CodeNarc,org.codenarc.extra.*
Both properties default to null
.
NOTE: The applyToClassNames and doNotApplyToClassNames rule configuration properties
are available only to subclasses of AbstractAstVisitorRule
. This includes
most of the rules provided with CodeNarc – i.e., all of the rules that deal with
the Groovy AST (Abstract Syntax Tree) of a source file. This includes any rule that processes
source code elements such as a package, class, method, field, parameter, etc.. But it does not
include rules that handle imports, blank lines or other file-based rules.
The applyToFileNames
and doNotApplyToFileNames
properties enable filtering the
files to which the rule is applied by specifying a comma-separated list of filenames (with optional
path) of source files. If applyToFileNames
is not empty or null, then the rule is only
applied to source files matching one of the specified filenames. Likewise, if
doNotApplyToFilesMatching
is not empty or null, then the rule is NOT applied to source files
matching any of the specified filenames.
Both properties may optionally specify a path (i.e., if the value contains at least one ‘/’ path separator). In that case, the value is matched against the full pathname of each source file. If no path is specified, then only the filename of each source file is compared (i.e., its path is ignored).
Both properties may optionally contain wildcard
characters (‘’ or ‘?’). The wildcard character ‘’ matches a sequence of zero or more characters
in the input string. The wildcard character ‘?’ matches exactly one character in the input string.
Both properties default to null
.
The applyToFilesMatching
and doNotApplyToFilesMatching
properties enable filtering
the files to which the rule is applied by matching a regular expression against the full pathname
of each source file. If applyToFilesMatching
is not empty or null, then the rule is only
applied to source files with matching paths. Likewise, if doNotApplyToFilesMatching
is not
empty or null, then the rule is NOT applied to source files with matching paths. Both properties
default to null
.
NOTE: File separator characters within pathnames are normalized to forward slashes (/). On Windows, for instance, that means that the path “c:\dir\file.txt” is normalized to “c:/dir/file.txt”. If your regular expressions contain file separator characters, be sure that they are all the standard ‘/’, no matter what operating system.
The enabled
boolean property allows a rule to be completely turned off (by setting it to false
).
It defaults to true
.
The violationMessage
property enables overriding the rule violation message. If not null,
this is used as the message for all violations of this rule, overriding any message generated
by the rule itself. This property defaults to null
. Note that setting this to an empty
string “hides” the message, if any, generated by the actual rule.
The description
property enables overriding the rule description text. If not null,
this value is used as the description text for this rule, overriding any description text
found in the i18n resource bundles. This property defaults to null
. Also see
Include Substitutable Message Parameters in a Rule Description
You can also override the default name
or priority
properties for each rule. If you override the name
property,
you should also override the description
property; otherwise it will not find a description for the rule.
You can turn off a rule by filtering the containing ruleset to exclude the rule. See Filtering Rules Within a RuleSet.
Alternately, as mentioned above, you can turn off (disable) a rule by setting its enabled
boolean property to false
(assuming it is a subclass of AbstractRule
), as shown in
the following “codenarc.properties” excerpt.
# Turn off this rule
AbstractClassName.enabled=false
And here is an example of disabling a rule within a Groovy RuleSet by setting its enabled
attribute to false
.
ruleset {
ruleset('rulesets/basic.xml') {
CatchThrowable(enabled:false)
}
}
You can use the @SuppressWarnings
annotation on a class, method, constructor, field or
property to suppress one or more CodeNarc rules within its source code. Import statements can also be annotated,
and in that case the suppression applies to the entire file.
Specify one or more rule name as the parameter of the @SuppressWarnings
annotation. Note
that this is the rule name, not the class name (i.e., without the “Rule” suffix). Specify
multiple rule names by passing a List of rule names as a single parameter, e.g.
@SuppressWarnings(['IfStatementBraces', 'ThrowException'])
NOTE: The @SuppressWarnings
annotation only works for rule classes that subclass AbstractAstVisitorRule
.
For example, the following code suppresses (prevents) violations of the DuplicateStringLiteral
rule within the MyClass
class, as well as suppressing the IfStatementBraces and ThrowException
rules within its getCount()
method.
@SuppressWarnings('DuplicateStringLiteral')
class MyClass {
def y = 'x'
def z = 'x'
@SuppressWarnings(['IfStatementBraces', 'ThrowException'])
int getCount() {
if (!ready) throw new Exception('Not ready')
}
}
You can specify “all” or “CodeNarc” within @SuppressWarnings
(e.g. @SuppressWarnings('all')
or
@SuppressWarnings('CodeNarc')
) to suppress violations for all CodeNarc rules for the annotated scope.
You can disable (suppress) rule violations for all or part of a source file by specifying codenarc-disable
within
a comment in the source code, and then optionally re-enable by specifying codenarc-enable
on a subsequent line. You
can disable rule violations for only the current line by specifying codenarc-disable-line
within a comment on that line.
Either /* .. */
or // ..
comments can be used. The comment can be on a line by itself or on the same line with code.
Specifying codenarc-disable
disables all CodeNarc rules, or it can optionally be followed by one or more rule names
to disable only the named rules, e.g. // codenarc-disable FieldName, NoDef
. Likewise, specifying codenarc-disable-line
disables all CodeNarc rules for that line, or it can be followed by rule names.
Disable all CodeNarc rules for the rest of the file:
// codenarc-disable
println 1
println 2
...
Disable specified CodeNarc rules for the rest of the file:
println 1 // codenarc-disable NoDef, Println
def count = 1
...
Disable all CodeNarc rules for part of the file (disable and then re-enable):
/* codenarc-disable */
println 1
println 2
/* codenarc-enable */
println 3
...
Disable some CodeNarc rules for part of the file (disable and then re-enable):
// codenarc-disable NoDef, Println
println 1
def count = 1
// codenarc-enable NoDef, Println
println 3
...
Disable all CodeNarc rules for the current line only:
def myVar = 123 // codenarc-disable-line
Disable specific CodeNarc rules for the current line only:
def myVar = 123 /* codenarc-disable-line NoDef */
The descriptions for rules used in a CodeNarc report are shown at the bottom of the resulting HTML report. Those rule descriptions are retrieved from a ResourceBundle. This ResourceBundle consists of a base (parent) bundle, provided with the CodeNarc distribution, and an optional custom (child) bundle, which may be provided by the user.
Because this is based on the standard Java ResourceBundle facility, you can customize (override) or translate these descriptions by providing your own locale-specific message properties file on the classpath. For example, a German one would be named “codenarc-messages_de.properties”.
The rule description message key is of the form “*rule-name*.description.html”. Examples include “BooleanInstantiation.description.html” and “CatchThrowable.description.html”.
(Note that the rule description included in the XML report is specified by the key *rule-name*.description).
See the javadoc for the java.util.ResourceBundle
class for more information.
You can optionally include message parameters within a rule description, whether that description
is specified in a ResourceBundle properties file or through the description
property of the
rule. Use the standard Groovy template parameter syntax: ${..}
. You can reference rule property
values through the “rule” object within the template parameter closure. For example, this description
includes the rule priority
within the rule description:
"Description for rule with priority ${rule.priority}"
.
The base ResourceBundle provided with the CodeNarc distribution has a basename of “codenarc-base-messages”. The rules provided with CodeNarc all have associated descriptions within the “codenarc-base-messages.properties” file.
You can provide a locale-specific variant of this file on the classpath if you wish, but in most scenarios, the recommended approach for customizing rule descriptions is to provide a custom messages bundle file, as described below.
You can optionally provide descriptions for new rules or override existing rule descriptions by placing a “codenarc-messages.properties” file on the classpath. This is also a ResourceBundle file, so it can have locale-specific variants, if needed. If this bundle (file) is present, it is searched first. If the desired message key is not found, only then is the base message bundle checked.
You can provide rule description entries within this file for custom rules that you create. You can also include rule description entries for existing rules, in which case the descriptions in this file override the default descriptions.
You may wish to customize both the name and the description for an existing rule. For example, you may want to have multiple instances of a generic rule, each configured differently. Or you may just want to make the rule name more clearly denote its specific purpose.
For example, in the following excerpt from a RuleSet file, because the name property is customized for the IllegalRegexRule, the new rule name “AuthorTagNotAllowed” will show up at the bottom of the HTML report, instead of the default rule name “IllegalRegex”.
<rule class='org.codenarc.rule.generic.IllegalRegexRule'>
<property name="name" value="AuthorTagNotAllowed"/>
<property name='regex' value='\@author'/>
</rule>
The rule description must be added to the custom messages resource bundle file (“codenarc-messages.properties”). The message key will be “AuthorTagNotAllowed.description.html” to set the description used in the HTML report, and “AuthorTagNotAllowed.description” for the description used in the XML report.