commit | author | age
|
6c33bb
|
1 |
plugins { |
a2f2fd
|
2 |
id 'java' |
8b4e78
|
3 |
id 'org.springframework.boot' version '2.7.3' |
0e4602
|
4 |
id 'io.openapiprocessor.openapi-processor' version '2022.2' |
8b4e78
|
5 |
id 'io.spring.dependency-management' version '1.0.13.RELEASE' |
c4531c
|
6 |
id 'com.github.jk1.dependency-license-report' version '2.1' |
8b4e78
|
7 |
id "org.owasp.dependencycheck" version "7.1.2" |
MH |
8 |
id "com.diffplug.spotless" version "6.10.0" |
a66ed8
|
9 |
id 'jacoco' |
7d4815
|
10 |
id 'info.solidsoft.pitest' version '1.9.0' |
8b4e78
|
11 |
id 'se.patrikerdes.use-latest-versions' version '0.2.18' |
MH |
12 |
id 'com.github.ben-manes.versions' version '0.42.0' |
6c33bb
|
13 |
} |
MH |
14 |
|
|
15 |
group = 'net.hostsharing' |
|
16 |
version = '0.0.1-SNAPSHOT' |
|
17 |
|
d9ee00
|
18 |
wrapper { |
MH |
19 |
distributionType = Wrapper.DistributionType.BIN |
|
20 |
gradleVersion = '7.5' |
|
21 |
} |
|
22 |
|
6c33bb
|
23 |
configurations { |
MH |
24 |
compileOnly { |
|
25 |
extendsFrom annotationProcessor |
|
26 |
} |
3de8b0
|
27 |
testCompile { |
MH |
28 |
// Only JUNit 5 (Jupiter) should be used at compile time. |
|
29 |
// For runtime it's still needed by testcontainers, though. |
|
30 |
exclude group: 'junit', module: 'junit' |
|
31 |
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' |
|
32 |
} |
6c33bb
|
33 |
} |
MH |
34 |
|
|
35 |
repositories { |
|
36 |
mavenCentral() |
433d0e
|
37 |
} |
MH |
38 |
|
|
39 |
java { |
|
40 |
toolchain { |
|
41 |
languageVersion = JavaLanguageVersion.of(17) |
|
42 |
} |
6c33bb
|
43 |
} |
MH |
44 |
|
|
45 |
ext { |
|
46 |
set('testcontainersVersion', "1.17.3") |
|
47 |
} |
a2f2fd
|
48 |
|
MH |
49 |
// wrapper |
6c33bb
|
50 |
|
MH |
51 |
dependencies { |
|
52 |
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' |
|
53 |
implementation 'org.springframework.boot:spring-boot-starter-data-rest' |
|
54 |
implementation 'org.springframework.boot:spring-boot-starter-jdbc' |
|
55 |
implementation 'org.springframework.boot:spring-boot-starter-web' |
8b4e78
|
56 |
implementation 'org.springdoc:springdoc-openapi-ui:1.6.11' |
6c33bb
|
57 |
implementation 'org.liquibase:liquibase-core' |
8b4e78
|
58 |
implementation 'com.vladmihalcea:hibernate-types-55:2.18.0' |
0e4602
|
59 |
implementation 'org.openapitools:jackson-databind-nullable:0.2.3' |
eeab68
|
60 |
implementation 'org.modelmapper:modelmapper:3.1.0' |
6c33bb
|
61 |
|
MH |
62 |
compileOnly 'org.projectlombok:lombok' |
|
63 |
|
|
64 |
developmentOnly 'org.springframework.boot:spring-boot-devtools' |
|
65 |
|
|
66 |
runtimeOnly 'org.postgresql:postgresql' |
|
67 |
|
|
68 |
annotationProcessor 'org.projectlombok:lombok' |
|
69 |
|
|
70 |
testImplementation 'org.springframework.boot:spring-boot-starter-test' |
|
71 |
testImplementation 'org.testcontainers:testcontainers' |
|
72 |
testImplementation 'org.testcontainers:junit-jupiter' |
|
73 |
testImplementation 'org.testcontainers:postgresql' |
142aac
|
74 |
testImplementation 'com.tngtech.archunit:archunit-junit5:1.0.0-rc1' |
0e4602
|
75 |
testImplementation 'io.rest-assured:spring-mock-mvc' |
9fb661
|
76 |
testImplementation 'org.hamcrest:hamcrest-core:2.2' |
MH |
77 |
testImplementation 'org.pitest:pitest-junit5-plugin:1.0.0' |
6c33bb
|
78 |
} |
MH |
79 |
|
|
80 |
dependencyManagement { |
|
81 |
imports { |
|
82 |
mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}" |
|
83 |
} |
|
84 |
} |
|
85 |
|
a66ed8
|
86 |
// Java Compiler Options |
433d0e
|
87 |
tasks.withType(JavaCompile) { |
a66ed8
|
88 |
options.compilerArgs += [ |
MH |
89 |
"-parameters" // keep parameter names => no need for @Param for SpringData |
|
90 |
] |
433d0e
|
91 |
} |
MH |
92 |
|
a66ed8
|
93 |
// Use JUnit Jupiter |
6c33bb
|
94 |
tasks.named('test') { |
MH |
95 |
useJUnitPlatform() |
|
96 |
} |
a2f2fd
|
97 |
|
a66ed8
|
98 |
// OpenAPI Source Code Generation |
eeab68
|
99 |
openapiProcessor { |
cd9be1
|
100 |
springRoot { |
MH |
101 |
processorName 'spring' |
0e4602
|
102 |
processor 'io.openapiprocessor:openapi-processor-spring:2022.4' |
eeab68
|
103 |
apiPath "$projectDir/src/main/resources/api-definition.yaml" |
MH |
104 |
mapping "$projectDir/src/main/resources/api-mappings.yaml" |
cd9be1
|
105 |
targetDir "$projectDir/build/generated/sources/openapi" |
MH |
106 |
showWarnings true |
|
107 |
openApiNullable true |
|
108 |
} |
|
109 |
springRbac { |
|
110 |
processorName 'spring' |
|
111 |
processor 'io.openapiprocessor:openapi-processor-spring:2022.4' |
|
112 |
apiPath "$projectDir/src/main/resources/api-definition/rbac/rbac.yaml" |
|
113 |
mapping "$projectDir/src/main/resources/api-definition/rbac/api-mappings.yaml" |
|
114 |
targetDir "$projectDir/build/generated/sources/openapi" |
|
115 |
showWarnings true |
|
116 |
openApiNullable true |
|
117 |
} |
|
118 |
springTest { |
|
119 |
processorName 'spring' |
|
120 |
processor 'io.openapiprocessor:openapi-processor-spring:2022.4' |
|
121 |
apiPath "$projectDir/src/main/resources/api-definition/test/test.yaml" |
|
122 |
mapping "$projectDir/src/main/resources/api-definition/test/api-mappings.yaml" |
|
123 |
targetDir "$projectDir/build/generated/sources/openapi" |
eeab68
|
124 |
showWarnings true |
0e4602
|
125 |
openApiNullable true |
eeab68
|
126 |
} |
af90fe
|
127 |
springHs { |
MH |
128 |
processorName 'spring' |
|
129 |
processor 'io.openapiprocessor:openapi-processor-spring:2022.4' |
|
130 |
apiPath "$projectDir/src/main/resources/api-definition/hs-admin/hs-admin.yaml" |
|
131 |
mapping "$projectDir/src/main/resources/api-definition/hs-admin/api-mappings.yaml" |
|
132 |
targetDir "$projectDir/build/generated/sources/openapi" |
|
133 |
showWarnings true |
|
134 |
openApiNullable true |
|
135 |
} |
eeab68
|
136 |
} |
MH |
137 |
sourceSets.main.java.srcDir 'build/generated/sources/openapi' |
af90fe
|
138 |
abstract class ProcessSpring extends DefaultTask {} |
MH |
139 |
tasks.register('processSpring', ProcessSpring) |
|
140 |
['processSpringRoot', 'processSpringRbac', 'processSpringTest', 'processSpringHs'].each { |
|
141 |
project.tasks.processSpring.dependsOn it |
cd9be1
|
142 |
} |
af90fe
|
143 |
project.tasks.processResources.dependsOn processSpring |
MH |
144 |
project.tasks.compileJava.dependsOn processSpring |
eeab68
|
145 |
|
a66ed8
|
146 |
// Spotless Code Formatting |
a2f2fd
|
147 |
spotless { |
MH |
148 |
java { |
0e4602
|
149 |
// removeUnusedImports() TODO: reactivate once it can deal with multi-line-strings |
MH |
150 |
indentWithSpaces(4) |
a2f2fd
|
151 |
endWithNewline() |
MH |
152 |
toggleOffOn() |
eeab68
|
153 |
|
0e4602
|
154 |
target fileTree(rootDir) { |
eeab68
|
155 |
include '**/*.java' |
MH |
156 |
exclude '**/generated/**/*.java' |
|
157 |
} |
a2f2fd
|
158 |
} |
MH |
159 |
} |
80b1e0
|
160 |
project.tasks.check.dependsOn(spotlessCheck) |
MH |
161 |
|
a66ed8
|
162 |
// OWASP Dependency Security Test |
80b1e0
|
163 |
dependencyCheck { |
MH |
164 |
cveValidForHours=4 |
|
165 |
format = 'ALL' |
|
166 |
suppressionFile = 'etc/owasp-dependency-check-suppression.xml' |
|
167 |
failOnError = true |
|
168 |
failBuildOnCVSS = 7 |
|
169 |
} |
|
170 |
project.tasks.check.dependsOn(dependencyCheckAnalyze) |
4ec261
|
171 |
project.tasks.dependencyCheckAnalyze.doFirst { // Why not doLast? See README.md! |
fd96bf
|
172 |
println "OWASP Dependency Security Report: file:///${project.rootDir}/build/reports/dependency-check-report.html" |
MH |
173 |
} |
|
174 |
|
c4531c
|
175 |
|
a66ed8
|
176 |
// License Check |
c4531c
|
177 |
licenseReport { |
MH |
178 |
excludeBoms = true |
|
179 |
allowedLicensesFile = new File("$projectDir/etc/allowed-licenses.json") |
|
180 |
} |
|
181 |
project.tasks.check.dependsOn(checkLicense) |
a66ed8
|
182 |
|
MH |
183 |
// JaCoCo Test Code Coverage |
|
184 |
jacoco { |
|
185 |
toolVersion = "0.8.8" |
|
186 |
} |
|
187 |
test { |
|
188 |
finalizedBy jacocoTestReport // generate report after tests |
|
189 |
excludes = [ |
cd9be1
|
190 |
'net.hostsharing.hsadminng.**.generated.**', |
a66ed8
|
191 |
] |
MH |
192 |
} |
|
193 |
jacocoTestReport { |
|
194 |
dependsOn test |
|
195 |
afterEvaluate { |
|
196 |
classDirectories.setFrom(files(classDirectories.files.collect { |
|
197 |
fileTree(dir: it, exclude: [ |
cd9be1
|
198 |
"net/hostsharing/hsadminng/**/generated/**/*.class", |
1a18ba
|
199 |
"net/hostsharing/hsadminng/hs/hscustomer/HsadminNgApplication.class" |
a66ed8
|
200 |
]) |
MH |
201 |
})) |
|
202 |
} |
4ec261
|
203 |
doFirst { // Why not doLast? See README.md! |
a66ed8
|
204 |
println "HTML Jacoco Test Code Coverage Report: file://${reports.html.outputLocation.get()}/index.html" |
MH |
205 |
} |
|
206 |
} |
|
207 |
project.tasks.check.dependsOn(jacocoTestCoverageVerification) |
|
208 |
jacocoTestCoverageVerification { |
|
209 |
violationRules { |
|
210 |
rule { |
|
211 |
limit { |
cd9be1
|
212 |
minimum = 0.90 |
a66ed8
|
213 |
} |
MH |
214 |
} |
|
215 |
|
|
216 |
// element: PACKAGE, BUNDLE, CLASS, SOURCEFILE or METHOD |
|
217 |
// counter: INSTRUCTION, BRANCH, LINE, COMPLEXITY, METHOD, or CLASS |
|
218 |
// value: TOTALCOUNT, COVEREDCOUNT, MISSEDCOUNT, COVEREDRATIO or MISSEDRATIO |
|
219 |
|
|
220 |
rule { |
|
221 |
element = 'CLASS' |
|
222 |
excludes = [ |
cd9be1
|
223 |
'net.hostsharing.hsadminng.**.generated.**', |
a66ed8
|
224 |
'net.hostsharing.hsadminng.HsadminNgApplication', |
cd9be1
|
225 |
'net.hostsharing.hsadminng.PingController', |
4aa8b8
|
226 |
'net.hostsharing.hsadminng.Mapper' |
a66ed8
|
227 |
] |
MH |
228 |
|
|
229 |
limit { |
|
230 |
counter = 'LINE' |
|
231 |
value = 'COVEREDRATIO' |
1a18ba
|
232 |
minimum = 0.95 |
a66ed8
|
233 |
} |
MH |
234 |
} |
|
235 |
rule { |
|
236 |
element = 'METHOD' |
|
237 |
excludes = [ |
cd9be1
|
238 |
'net.hostsharing.hsadminng.**.generated.**', |
2124d4
|
239 |
'net.hostsharing.hsadminng.HsadminNgApplication.main', |
cd9be1
|
240 |
'net.hostsharing.hsadminng.PingController.*' |
4aa8b8
|
241 |
] |
a66ed8
|
242 |
|
MH |
243 |
limit { |
|
244 |
counter = 'BRANCH' |
|
245 |
value = 'COVEREDRATIO' |
2124d4
|
246 |
minimum = 0.95 |
a66ed8
|
247 |
} |
MH |
248 |
} |
|
249 |
} |
|
250 |
} |
|
251 |
|
9fb661
|
252 |
// pitest mutation testing |
MH |
253 |
pitest { |
|
254 |
targetClasses = ['net.hostsharing.hsadminng.**'] |
|
255 |
excludedClasses = [ |
|
256 |
'net.hostsharing.hsadminng.config.**', |
af90fe
|
257 |
'net.hostsharing.hsadminng.**.*Controller', |
cd9be1
|
258 |
'net.hostsharing.hsadminng.**.generated.**' |
9fb661
|
259 |
] |
MH |
260 |
|
|
261 |
targetTests = ['net.hostsharing.hsadminng.**.*UnitTest', 'net.hostsharing.hsadminng.**.*RestTest'] |
|
262 |
excludedTestClasses = ['**AcceptanceTest*', '**IntegrationTest*'] |
|
263 |
|
|
264 |
pitestVersion = '1.9.0' |
|
265 |
junit5PluginVersion = '1.0.0' |
|
266 |
|
|
267 |
threads = 4 |
|
268 |
|
|
269 |
// As Java unit tests are pretty pointless in our case, this maybe makes not much sense. |
af90fe
|
270 |
mutationThreshold = 71 |
MH |
271 |
coverageThreshold = 57 |
87e2b0
|
272 |
testStrengthThreshold = 88 |
9fb661
|
273 |
|
MH |
274 |
outputFormats = ['XML', 'HTML'] |
|
275 |
timestampedReports = false |
|
276 |
} |
|
277 |
project.tasks.check.dependsOn(project.tasks.pitest) |
4ec261
|
278 |
project.tasks.pitest.doFirst { // Why not doLast? See README.md! |
9fb661
|
279 |
println "PiTest Mutation Report: file:///${project.rootDir}/build/reports/pitest/index.html" |
MH |
280 |
} |
|
281 |
|
|
282 |
|
8b4e78
|
283 |
// Dependency Versions Upgrade |
MH |
284 |
useLatestVersions { |
|
285 |
finalizedBy check |
|
286 |
} |