Skip to content

Commit cdd5fa0

Browse files
committed
Missing codestyle and codecoverage added, fixing codenarc violations
1 parent 68f0477 commit cdd5fa0

11 files changed

Lines changed: 319 additions & 3 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
3+
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
4+
<suppressions>
5+
</suppressions>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
3+
"https://checkstyle.org/dtds/configuration_1_3.dtd">
4+
<module name="Checker">
5+
6+
<!-- Suppressions -->
7+
<module name="SuppressionFilter">
8+
<property name="file" value="${config_loc}/checkstyle-suppressions.xml"/>
9+
</module>
10+
11+
<!-- Root Checks -->
12+
<module name="NewlineAtEndOfFile"/>
13+
<module name="FileTabCharacter"/>
14+
<module name="SuppressWarningsFilter"/>
15+
16+
<!-- TreeWalker Checks -->
17+
<module name="TreeWalker">
18+
19+
<module name="SuppressWarningsHolder"/>
20+
21+
<!-- Imports -->
22+
<module name="AvoidStarImport"/>
23+
<module name="RedundantImport"/>
24+
<module name="UnusedImports">
25+
<property name="processJavadoc" value="false"/>
26+
</module>
27+
<module name="ImportOrderCheck">
28+
<!-- Import groups: JAVA, JAVAX, GROOVY, JAKARTA, OTHER, SPRING, GRAILS, STATIC -->
29+
<property name="groups"
30+
value="java,javax,/^(groovy|org\.apache\.groovy|org\.codehaus\.groovy)\..+/,jakarta,*,/(^io\.spring|org\.springframework)\..+/,/^(grails|org\.apache\.grails|org\.grails)\..+/"/>
31+
<property name="ordered" value="true"/>
32+
<property name="option" value="bottom"/>
33+
<property name="separated" value="true"/>
34+
<property name="sortStaticImportsAlphabetically" value="true"/>
35+
</module>
36+
37+
<!-- Whitespace -->
38+
<module name="CommentsIndentation"/>
39+
<module name="EmptyLineSeparator">
40+
<property name="allowMultipleEmptyLines" value="false"/>
41+
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
42+
<property name="allowNoEmptyLineBetweenFields" value="true"/>
43+
<property name="tokens"
44+
value="IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF, STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF, COMPACT_CTOR_DEF"/><!-- PACKAGE_DEF removed from defaults -->
45+
</module>
46+
<module name="GenericWhitespace"/>
47+
<module name="Indentation"/>
48+
<module name="NoLineWrap"/>
49+
<module name="MethodParamPad"/>
50+
<module name="NoWhitespaceAfter">
51+
<property name="tokens"
52+
value="AT, INC, DEC, UNARY_MINUS, UNARY_PLUS, BNOT, LNOT, DOT, ARRAY_DECLARATOR, INDEX_OP"/><!-- ARRAY_INIT removed from defaults -->
53+
</module>
54+
<module name="NoWhitespaceBefore"/>
55+
<module name="NoWhitespaceBeforeCaseDefaultColon"/>
56+
<module name="OperatorWrap">
57+
<property name="option" value="eol"/>
58+
</module>
59+
<module name="ParenPad"/>
60+
<module name="SeparatorWrap">
61+
<property name="option" value="nl"/>
62+
<property name="tokens" value="DOT"/>
63+
</module>
64+
<module name="SingleSpaceSeparator"/>
65+
<module name="TypecastParenPad"/>
66+
<module name="WhitespaceAfter"/>
67+
<module name="WhitespaceAround">
68+
<property name="allowEmptyCatches" value="true"/>
69+
<property name="allowEmptyConstructors" value="true"/>
70+
<property name="allowEmptyMethods" value="true"/>
71+
<property name="allowEmptyTypes" value="true"/>
72+
</module>
73+
</module>
74+
75+
</module>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
ruleset {
2+
3+
description 'A Codenarc ruleset for the Grails codebase'
4+
5+
BracesForClass
6+
ClassStartsWithBlankLine {
7+
ignoreInnerClasses = true
8+
}
9+
ClosureStatementOnOpeningLineOfMultipleLineClosure
10+
ConsecutiveBlankLines
11+
FileEndsWithoutNewline
12+
NoTabCharacter
13+
DuplicateImport
14+
ImportFromSamePackage
15+
Indentation
16+
MisorderedStaticImports {
17+
comesBefore = false // static imports should come last
18+
}
19+
MissingBlankLineAfterImports
20+
MissingBlankLineAfterPackage
21+
MissingBlankLineBeforeAnnotatedField
22+
NoWildcardImports
23+
SpaceAfterCatch
24+
SpaceAfterClosingBrace
25+
SpaceAfterComma
26+
SpaceAfterFor
27+
SpaceAfterIf
28+
SpaceAfterMethodCallName
29+
SpaceAfterMethodDeclarationName
30+
SpaceAfterNotOperator
31+
SpaceAfterOpeningBrace {
32+
ignoreEmptyBlock = true
33+
}
34+
SpaceAfterSemicolon
35+
SpaceAfterSwitch
36+
SpaceAfterWhile
37+
SpaceAroundClosureArrow
38+
SpaceAroundMapEntryColon {
39+
characterAfterColonRegex = ' '
40+
}
41+
SpaceAroundOperator {
42+
ignoreParameterDefaultValueAssignments = false
43+
}
44+
SpaceBeforeClosingBrace {
45+
ignoreEmptyBlock = true
46+
}
47+
SpaceBeforeOpeningBrace
48+
SpaceInsideParentheses
49+
UnnecessaryConstructor
50+
UnnecessaryDotClass
51+
UnnecessaryGroovyImport
52+
UnnecessaryGString
53+
UnnecessaryOverridingMethod
54+
UnnecessaryPublicModifier
55+
UnnecessarySafeNavigationOperator
56+
UnnecessarySemicolon
57+
UnusedImport
58+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
plugins {
2+
id 'base'
3+
id 'jacoco'
4+
}
5+
6+
extensions.configure(JacocoPluginExtension) {
7+
it.toolVersion = jacocoVersion
8+
}
9+
10+
def aggregateConfiguration = configurations.register('aggregateConfiguration') {
11+
canBeConsumed = false
12+
canBeResolved = false
13+
}
14+
15+
def aggregateProject = project
16+
rootProject.subprojects { sub ->
17+
sub.pluginManager.withPlugin('config.code-coverage') {
18+
aggregateProject.dependencies.add(
19+
'aggregateConfiguration',
20+
aggregateProject.dependencies.project(path: sub.path)
21+
)
22+
}
23+
}
24+
25+
def coverageProjects = aggregateConfiguration.map {
26+
it.dependencies.withType(ProjectDependency).collect { project.project(it.path) }
27+
}
28+
29+
def allSourceDirs = coverageProjects.map {
30+
it.findAll { it.plugins.hasPlugin(JavaPlugin) }
31+
.collectMany { p ->
32+
p.extensions.getByType(SourceSetContainer).named('main').get()
33+
.allSource.sourceDirectories.files
34+
}
35+
}
36+
37+
def allClassDirs = coverageProjects.map {
38+
it.findAll { it.plugins.hasPlugin(JavaPlugin) }
39+
.collectMany { p ->
40+
p.extensions.getByType(SourceSetContainer).named('main').get()
41+
.output.files
42+
}
43+
}
44+
45+
def jacocoAggregatedReport = tasks.register('jacocoAggregatedReport', JacocoReport) {
46+
description = 'Generates aggregated JaCoCo coverage report across all subprojects.'
47+
group = 'verification'
48+
49+
classDirectories.from(allClassDirs)
50+
sourceDirectories.from(allSourceDirs)
51+
52+
reports {
53+
xml.required = true
54+
html.required = true
55+
csv.required = false
56+
}
57+
}
58+
59+
coverageProjects.get().each {
60+
it.tasks.withType(Test).configureEach { test ->
61+
jacocoAggregatedReport.configure { JacocoReport report ->
62+
report.executionData(test)
63+
}
64+
}
65+
}
66+
67+
tasks.named('check') {
68+
dependsOn(jacocoAggregatedReport)
69+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
plugins {
2+
id 'jacoco'
3+
}
4+
5+
extensions.configure(JacocoPluginExtension) {
6+
it.toolVersion = jacocoVersion
7+
}
8+
9+
pluginManager.withPlugin('groovy') {
10+
// The jacoco plugin automatically creates 'jacocoTestReport' for the 'test' task.
11+
// Configure it to produce XML (for CI tools) and HTML reports.
12+
tasks.named('jacocoTestReport', JacocoReport) {
13+
reports {
14+
xml.required = true
15+
html.required = true
16+
csv.required = false
17+
}
18+
19+
dependsOn(tasks.named('test'))
20+
}
21+
22+
// Ensure coverage report runs after tests
23+
tasks.named('test') {
24+
finalizedBy(tasks.named('jacocoTestReport'))
25+
}
26+
}
27+
28+
// When an integrationTest task is registered (e.g., via the Grails web plugin in example apps),
29+
// register a JaCoCo report task for it. Unlike the 'test' task, the JaCoCo plugin does not
30+
// auto-create report tasks for custom Test tasks.
31+
afterEvaluate { proj ->
32+
33+
def integrationTestTasks = tasks.withType(Test).matching { it.name == 'integrationTest' }
34+
if (!integrationTestTasks.isEmpty()) {
35+
36+
def integrationTest = integrationTestTasks.first()
37+
def execFile = integrationTest.extensions.getByType(JacocoTaskExtension).destinationFile
38+
39+
def reportTask = tasks.register('jacocoIntegrationTestReport', JacocoReport) {
40+
description = 'Generates code coverage report for the integrationTest task.'
41+
group = 'verification'
42+
43+
executionData.from(execFile)
44+
sourceSets(proj.extensions.getByType(SourceSetContainer).named('main').get())
45+
46+
reports {
47+
xml.required = true
48+
html.required = true
49+
csv.required = false
50+
}
51+
52+
dependsOn(integrationTest)
53+
}
54+
55+
integrationTest.finalizedBy(reportTask)
56+
}
57+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
plugins {
2+
id 'checkstyle'
3+
id 'codenarc'
4+
}
5+
6+
// Resolved relative to the root project directory, which is the parent of build-logic/.
7+
def codeStyleConfigDir = rootProject.layout.settingsDirectory.dir('build-logic/config')
8+
def checkstyleConfigDir = codeStyleConfigDir.dir('checkstyle')
9+
def codenarcConfigDir = codeStyleConfigDir.dir('codenarc')
10+
11+
extensions.configure(CheckstyleExtension) {
12+
it.toolVersion = checkstyleVersion
13+
it.configDirectory = checkstyleConfigDir
14+
it.maxWarnings = 0
15+
it.showViolations = true
16+
it.ignoreFailures = false
17+
}
18+
19+
tasks.withType(Checkstyle).configureEach {
20+
group = 'verification'
21+
onlyIf { !project.hasProperty('skipCodeStyle') }
22+
}
23+
24+
extensions.configure(CodeNarcExtension) {
25+
it.toolVersion = codenarcVersion
26+
it.configFile = codenarcConfigDir.file('codenarc.groovy').getAsFile()
27+
it.maxPriority1Violations = 0
28+
it.maxPriority2Violations = 0
29+
it.maxPriority3Violations = 0
30+
}
31+
32+
tasks.withType(CodeNarc).configureEach {
33+
group = 'verification'
34+
onlyIf { !project.hasProperty('skipCodeStyle') }
35+
}
36+
37+
tasks.register('codeStyle') {
38+
group = 'verification'
39+
description = 'Runs all code style checks (Checkstyle + CodeNarc).'
40+
dependsOn(tasks.withType(Checkstyle))
41+
dependsOn(tasks.withType(CodeNarc))
42+
}

code-coverage/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
plugins {
2+
id 'config.code-coverage-aggregate'
3+
}

gradle.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ grailsVersion=7.0.11
33
# Comma-separated list of projects to publish
44
projectsToPublish=grails-plugin-template
55
# Build dependencies
6+
checkstyleVersion=10.21.4
7+
codenarcVersion=3.6.0
8+
jacocoVersion=0.8.12
69
asciidoctorVersion=4.0.5
710
testLoggerVersion=4.0.0
811
# Enable and set agree=yes to publish build scans from GitHub workflows

plugin/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
plugins {
2+
id 'config.code-coverage'
3+
id 'config.code-style'
24
id 'config.compile'
35
id 'config.grails-plugin'
46
id 'config.project-metadata'

plugin/src/main/groovy/grails/plugins/template/PluginTemplateGrailsPlugin.groovy

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import grails.plugins.Plugin
66

77
@Commons
88
class PluginTemplateGrailsPlugin extends Plugin {
9-
def grailsVersion = "7.0.0 > *"
9+
10+
def grailsVersion = '7.0.0 > *'
1011
def dependsOn = [:]
1112

12-
def title = "Grails Plugin Template"
13-
def documentation = "https://grails-plugins.github.io/grails-plugin-template/"
13+
def title = 'Grails Plugin Template'
14+
def documentation = 'https://grails-plugins.github.io/grails-plugin-template/'
1415
def description = '''\
1516
A Grails plugin Template, that can be used either as a starting point for a new grails project, or as base for existing plugins that needs a uniform release process
1617
'''

0 commit comments

Comments
 (0)