From 7a822e26edbab7ed628bff5fd90eec90980788c4 Mon Sep 17 00:00:00 2001
From: Juan C Galvis <8420868+juancgalvis@users.noreply.github.com>
Date: Thu, 17 Oct 2024 19:24:45 -0500
Subject: [PATCH] feat(pitest): Add UpgradeAction for pitest settings
---
sh_dependencies.json | 4 +
.../factory/upgrades/UpdateUtils.java | 8 ++
.../actions/UpgradeY2024M10D17AddPitest.java | 132 ++++++++++++++++++
.../structure/root/build.gradle.mustache | 1 +
.../structure/root/main.gradle.mustache | 26 +++-
.../factory/upgrades/UpdateUtilsTest.java | 14 ++
.../UpgradeY2024M10D17AddPitestTest.java | 63 +++++++++
src/test/resources/pitest/build-after.txt | 37 +++++
src/test/resources/pitest/build-before.txt | 34 +++++
src/test/resources/pitest/main-after.txt | 122 ++++++++++++++++
src/test/resources/pitest/main-before.txt | 81 +++++++++++
11 files changed, 520 insertions(+), 2 deletions(-)
create mode 100644 src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitest.java
create mode 100644 src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitestTest.java
create mode 100644 src/test/resources/pitest/build-after.txt
create mode 100644 src/test/resources/pitest/build-before.txt
create mode 100644 src/test/resources/pitest/main-after.txt
create mode 100644 src/test/resources/pitest/main-before.txt
diff --git a/sh_dependencies.json b/sh_dependencies.json
index bece963c..9d63a354 100644
--- a/sh_dependencies.json
+++ b/sh_dependencies.json
@@ -73,6 +73,10 @@
{
"name": "DEPENDENCY_CHECK_VERSION",
"packageName": "org.owasp.dependencycheck:org.owasp.dependencycheck.gradle.plugin"
+ },
+ {
+ "name": "PITEST_VERSION",
+ "packageName": "info.solidsoft.pitest:info.solidsoft.pitest.gradle.plugin"
}
],
"custom": [
diff --git a/src/main/java/co/com/bancolombia/factory/upgrades/UpdateUtils.java b/src/main/java/co/com/bancolombia/factory/upgrades/UpdateUtils.java
index aeb04363..34b719d3 100644
--- a/src/main/java/co/com/bancolombia/factory/upgrades/UpdateUtils.java
+++ b/src/main/java/co/com/bancolombia/factory/upgrades/UpdateUtils.java
@@ -74,6 +74,14 @@ public static String insertAfterMatch(
return main.substring(0, start) + concatValue + main.substring(start);
}
+ public static String addToStartIfNotContains(
+ String main, String containsValue, String concatValue) {
+ if (main.contains(containsValue)) {
+ return main;
+ }
+ return concatValue + main;
+ }
+
public static String replace(String content, String previous, String next) {
return content.replace(previous, next);
}
diff --git a/src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitest.java b/src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitest.java
new file mode 100644
index 00000000..291e4b99
--- /dev/null
+++ b/src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitest.java
@@ -0,0 +1,132 @@
+package co.com.bancolombia.factory.upgrades.actions;
+
+import static co.com.bancolombia.Constants.MainFiles.BUILD_GRADLE;
+import static co.com.bancolombia.Constants.MainFiles.MAIN_GRADLE;
+
+import co.com.bancolombia.Constants;
+import co.com.bancolombia.factory.ModuleBuilder;
+import co.com.bancolombia.factory.upgrades.UpdateUtils;
+import co.com.bancolombia.factory.upgrades.UpgradeAction;
+import lombok.SneakyThrows;
+
+public class UpgradeY2024M10D17AddPitest implements UpgradeAction {
+ private final String pitestConfig =
+ "pitest {\n"
+ + " targetClasses = ['{{package}}.*']\n"
+ + " excludedClasses = []\n"
+ + " excludedTestClasses = []\n"
+ + " pitestVersion = '1.16.1'\n"
+ + " verbose = true\n"
+ + " outputFormats = ['XML', 'HTML']\n"
+ + " threads = 8\n"
+ + " exportLineCoverage = true\n"
+ + " timestampedReports = false\n"
+ + " //mutators = ['STRONGER', 'DEFAULTS']\n"
+ + " fileExtensionsToFilter.addAll('xml', 'orbit')\n"
+ + " junit5PluginVersion = '1.2.1'\n"
+ + " failWhenNoMutations = false\n"
+ + " jvmArgs = [\"-XX:+AllowRedefinitionToAddDeleteMethods\"]\n"
+ + " }\n"
+ + "\n"
+ + " ";
+
+ private final String pitestMergedConfig =
+ "\npitestReportAggregate {\n"
+ + " doLast {\n"
+ + " def reportDir = layout.buildDirectory.dir(\"reports/pitest\").get().asFile\n"
+ + " def consolidatedReport = new File(reportDir, 'mutations.xml')\n"
+ + " consolidatedReport.withWriter { writer ->\n"
+ + " writer.write(\"\\n\")\n"
+ + " subprojects.each { subproject ->\n"
+ + " def xmlReport = subproject.layout.buildDirectory.file(\"reports/pitest/mutations.xml\").get().asFile\n"
+ + " if (xmlReport.exists()) {\n"
+ + " def xmlContent = xmlReport.text\n"
+ + " xmlContent = xmlContent.replaceAll(\"<\\\\?xml[^>]*>\", \"\")\n"
+ + " xmlContent = xmlContent.replaceAll(\"?mutations( partial=\\\"true\\\")?>\", \"\")\n"
+ + " writer.write(xmlContent.trim() + \"\\n\")\n"
+ + " }\n"
+ + " }\n"
+ + " writer.write(\"\")\n"
+ + " }\n"
+ + " }\n"
+ + "}\n\n";
+
+ @Override
+ @SneakyThrows
+ public boolean up(ModuleBuilder builder) {
+ boolean appliedToBuildGradle =
+ builder.updateFile(
+ BUILD_GRADLE,
+ content -> {
+ String partial =
+ UpdateUtils.insertAfterMatch(
+ content,
+ "ext {",
+ "pitestVersion",
+ "\n pitestVersion = '" + Constants.PITEST_VERSION + "'");
+
+ partial =
+ UpdateUtils.insertAfterMatch(
+ partial,
+ "plugins {",
+ "info.solidsoft.pitest",
+ "\n id 'info.solidsoft.pitest' version \"${pitestVersion}\" apply false");
+
+ return UpdateUtils.insertAfterMatch(
+ partial,
+ "jacocoMergedReport.xml\"",
+ "sonar.pitest.reportPaths",
+ "\n property \"sonar.pitest.reportPaths\", \"build/reports/pitest/mutations.xml\"");
+ });
+ boolean appliedToMainGradle =
+ builder.updateFile(
+ MAIN_GRADLE,
+ content -> {
+ String partial =
+ UpdateUtils.addToStartIfNotContains(
+ content,
+ "info.solidsoft.pitest.aggregator",
+ "apply plugin: 'info.solidsoft.pitest.aggregator'\n\n");
+
+ partial =
+ UpdateUtils.insertAfterMatch(
+ partial,
+ "subprojects {",
+ "'info.solidsoft.pitest'",
+ "\n apply plugin: 'info.solidsoft.pitest'");
+
+ String packageLoaded = builder.getStringParam("package");
+ if (packageLoaded == null) {
+ packageLoaded = "your.package";
+ }
+ String pitest = pitestConfig.replace("{{package}}", packageLoaded);
+ partial =
+ UpdateUtils.insertBeforeMatch(
+ partial, "jacocoTestReport {", "pitestVersion", pitest);
+
+ partial =
+ UpdateUtils.insertAfterMatch(
+ partial,
+ "subprojects.jacocoTestReport",
+ "pitestReportAggregate",
+ ", pitestReportAggregate");
+
+ partial =
+ UpdateUtils.insertAfterMatch(partial, "dependsOn test", "'pitest'", ", 'pitest'");
+
+ return UpdateUtils.insertBeforeMatch(
+ partial, "tasks.named('wrapper')", "pitestReportAggregate {", pitestMergedConfig);
+ });
+ return appliedToBuildGradle || appliedToMainGradle;
+ }
+
+ @Override
+ public String name() {
+ return "3.17.24->3.18";
+ }
+
+ @Override
+ public String description() {
+ return "Add skipCompile for sonar";
+ }
+}
diff --git a/src/main/resources/structure/root/build.gradle.mustache b/src/main/resources/structure/root/build.gradle.mustache
index 3a92f290..223ce131 100644
--- a/src/main/resources/structure/root/build.gradle.mustache
+++ b/src/main/resources/structure/root/build.gradle.mustache
@@ -66,6 +66,7 @@ sonar {
property "sonar.junit.reportsPath", "{{sonar.junit.reportsPaths}}"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoMergedReport/jacocoMergedReport.xml"
+ property "sonar.pitest.reportPaths", "build/reports/pitest/mutations.xml"
property "sonar.externalIssuesReportPaths", "build/issues.json"
}
}
diff --git a/src/main/resources/structure/root/main.gradle.mustache b/src/main/resources/structure/root/main.gradle.mustache
index f70c0160..a51224cf 100644
--- a/src/main/resources/structure/root/main.gradle.mustache
+++ b/src/main/resources/structure/root/main.gradle.mustache
@@ -66,11 +66,13 @@ subprojects {
targetClasses = ['{{package}}.*']
excludedClasses = []
excludedTestClasses = []
+ pitestVersion = '1.16.1'
verbose = true
outputFormats = ['XML', 'HTML']
threads = 8
exportLineCoverage = true
timestampedReports = false
+ //mutators = ['STRONGER', 'DEFAULTS']
fileExtensionsToFilter.addAll('xml', 'orbit')
junit5PluginVersion = '1.2.1'
failWhenNoMutations = false
@@ -79,7 +81,7 @@ subprojects {
{{/mutation}}
jacocoTestReport {
- dependsOn test
+ dependsOn test, 'pitest'
reports {
xml.setRequired true
xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml")
@@ -96,7 +98,7 @@ jacoco {
}
tasks.register('jacocoMergedReport', JacocoReport) {
- dependsOn = [test, subprojects.jacocoTestReport]
+ dependsOn = [test, subprojects.jacocoTestReport, pitestReportAggregate]
additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
classDirectories.setFrom files(subprojects.sourceSets.main.output)
@@ -114,6 +116,26 @@ tasks.withType(JavaCompile).configureEach {
]
}
+pitestReportAggregate {
+ doLast {
+ def reportDir = layout.buildDirectory.dir("reports/pitest").get().asFile
+ def consolidatedReport = new File(reportDir, 'mutations.xml')
+ consolidatedReport.withWriter { writer ->
+ writer.write("\n")
+ subprojects.each { subproject ->
+ def xmlReport = subproject.layout.buildDirectory.file("reports/pitest/mutations.xml").get().asFile
+ if (xmlReport.exists()) {
+ def xmlContent = xmlReport.text
+ xmlContent = xmlContent.replaceAll("<\\?xml[^>]*>", "")
+ xmlContent = xmlContent.replaceAll("?mutations( partial=\"true\")?>", "")
+ writer.write(xmlContent.trim() + "\n")
+ }
+ }
+ writer.write("")
+ }
+ }
+}
+
tasks.named('wrapper') {
gradleVersion = '{{GRADLE_WRAPPER_VERSION}}'
}
diff --git a/src/test/java/co/com/bancolombia/factory/upgrades/UpdateUtilsTest.java b/src/test/java/co/com/bancolombia/factory/upgrades/UpdateUtilsTest.java
index 341ee339..ffb74b7c 100644
--- a/src/test/java/co/com/bancolombia/factory/upgrades/UpdateUtilsTest.java
+++ b/src/test/java/co/com/bancolombia/factory/upgrades/UpdateUtilsTest.java
@@ -96,6 +96,20 @@ void shouldAppendValidate() {
assertEquals(expected, result);
}
+ @Test
+ void shouldAddToStartIfNotContains() {
+ // Arrange
+ String file = "apply plugin: 'info.solidsoft.pitest.aggregator'\n\n";
+ String check = "info.solidsoft.pitest.aggregator";
+ String currentContent = "allprojects {}\n";
+ builder.addFile(file, currentContent);
+ // Act
+ String expected = "apply plugin: 'info.solidsoft.pitest.aggregator'\n\nallprojects {}\n";
+ String result = UpdateUtils.addToStartIfNotContains(currentContent, check, file);
+ // Assert
+ assertEquals(expected, result);
+ }
+
@Test
void shouldThrowWhenNoMatch() {
// Arrange
diff --git a/src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitestTest.java b/src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitestTest.java
new file mode 100644
index 00000000..c102f87b
--- /dev/null
+++ b/src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M10D17AddPitestTest.java
@@ -0,0 +1,63 @@
+package co.com.bancolombia.factory.upgrades.actions;
+
+import static co.com.bancolombia.Constants.MainFiles.BUILD_GRADLE;
+import static co.com.bancolombia.Constants.MainFiles.MAIN_GRADLE;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import co.com.bancolombia.factory.ModuleBuilder;
+import co.com.bancolombia.factory.upgrades.UpgradeAction;
+import co.com.bancolombia.utils.FileUtils;
+import com.github.mustachejava.resolver.DefaultResolver;
+import java.io.IOException;
+import java.nio.file.Files;
+import org.gradle.api.Project;
+import org.gradle.api.logging.Logger;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class UpgradeY2024M10D17AddPitestTest {
+
+ @Mock private Project project;
+ @Mock private Logger logger;
+
+ private ModuleBuilder builder;
+ private UpgradeAction updater;
+
+ @BeforeEach
+ public void setup() throws IOException {
+ when(project.getName()).thenReturn("UtilsTest");
+ when(project.getLogger()).thenReturn(logger);
+ when(project.getProjectDir()).thenReturn(Files.createTempDirectory("sample").toFile());
+
+ builder = spy(new ModuleBuilder(project));
+ updater = new UpgradeY2024M10D17AddPitest();
+
+ assertNotNull(updater.name());
+ assertNotNull(updater.description());
+ }
+
+ @Test
+ void shouldApplyUpdate() throws IOException {
+ DefaultResolver resolver = new DefaultResolver();
+ // Arrange
+ builder.addFile(
+ BUILD_GRADLE, FileUtils.getResourceAsString(resolver, "pitest/build-before.txt"));
+ builder.addFile(MAIN_GRADLE, FileUtils.getResourceAsString(resolver, "pitest/main-before.txt"));
+ // Act
+ boolean applied = updater.up(builder);
+ // Assert
+ assertTrue(applied);
+ verify(builder)
+ .addFile(BUILD_GRADLE, FileUtils.getResourceAsString(resolver, "pitest/build-after.txt"));
+ verify(builder)
+ .addFile(MAIN_GRADLE, FileUtils.getResourceAsString(resolver, "pitest/main-after.txt"));
+ }
+}
diff --git a/src/test/resources/pitest/build-after.txt b/src/test/resources/pitest/build-after.txt
new file mode 100644
index 00000000..d229df75
--- /dev/null
+++ b/src/test/resources/pitest/build-after.txt
@@ -0,0 +1,37 @@
+buildscript {
+ ext {
+ pitestVersion = '1.15.0'
+ cleanArchitectureVersion = '3.17.26'
+ springBootVersion = '3.3.4'
+ sonarVersion = '5.1.0.4882'
+ jacocoVersion = '0.8.12'
+ lombokVersion = '1.18.34'
+ }
+}
+
+plugins {
+ id 'info.solidsoft.pitest' version "${pitestVersion}" apply false
+ id 'co.com.bancolombia.cleanArchitecture' version "${cleanArchitectureVersion}"
+ id 'org.springframework.boot' version "${springBootVersion}" apply false
+ id 'org.sonarqube' version "${sonarVersion}"
+ id 'jacoco'
+}
+
+sonar {
+ def modules = subprojects.projectDir.collect { "${it.toString().replace(project.projectDir.toString() + "/", "")}" }
+ properties {
+ property "sonar.sourceEncoding", "UTF-8"
+ property "sonar.modules", "${modules.join(',')}"
+ property "sonar.sources", "src,deployment,settings.gradle,main.gradle,build.gradle,${modules.collect { "${it}/build.gradle" }.join(',')}"
+ property "sonar.test", "src/test"
+ property "sonar.exclusions", ""
+ property "sonar.java.binaries", "build/classes"
+ property "sonar.junit.reportsPath", "build/test-reports"
+ property "sonar.java.coveragePlugin", "jacoco"
+ property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoMergedReport/jacocoMergedReport.xml"
+ property "sonar.pitest.reportPaths", "build/reports/pitest/mutations.xml"
+ property "sonar.externalIssuesReportPaths", "build/issues.json"
+ }
+}
+
+apply from: './main.gradle'
\ No newline at end of file
diff --git a/src/test/resources/pitest/build-before.txt b/src/test/resources/pitest/build-before.txt
new file mode 100644
index 00000000..9d12cb3e
--- /dev/null
+++ b/src/test/resources/pitest/build-before.txt
@@ -0,0 +1,34 @@
+buildscript {
+ ext {
+ cleanArchitectureVersion = '3.17.26'
+ springBootVersion = '3.3.4'
+ sonarVersion = '5.1.0.4882'
+ jacocoVersion = '0.8.12'
+ lombokVersion = '1.18.34'
+ }
+}
+
+plugins {
+ id 'co.com.bancolombia.cleanArchitecture' version "${cleanArchitectureVersion}"
+ id 'org.springframework.boot' version "${springBootVersion}" apply false
+ id 'org.sonarqube' version "${sonarVersion}"
+ id 'jacoco'
+}
+
+sonar {
+ def modules = subprojects.projectDir.collect { "${it.toString().replace(project.projectDir.toString() + "/", "")}" }
+ properties {
+ property "sonar.sourceEncoding", "UTF-8"
+ property "sonar.modules", "${modules.join(',')}"
+ property "sonar.sources", "src,deployment,settings.gradle,main.gradle,build.gradle,${modules.collect { "${it}/build.gradle" }.join(',')}"
+ property "sonar.test", "src/test"
+ property "sonar.exclusions", ""
+ property "sonar.java.binaries", "build/classes"
+ property "sonar.junit.reportsPath", "build/test-reports"
+ property "sonar.java.coveragePlugin", "jacoco"
+ property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoMergedReport/jacocoMergedReport.xml"
+ property "sonar.externalIssuesReportPaths", "build/issues.json"
+ }
+}
+
+apply from: './main.gradle'
\ No newline at end of file
diff --git a/src/test/resources/pitest/main-after.txt b/src/test/resources/pitest/main-after.txt
new file mode 100644
index 00000000..b9244217
--- /dev/null
+++ b/src/test/resources/pitest/main-after.txt
@@ -0,0 +1,122 @@
+apply plugin: 'info.solidsoft.pitest.aggregator'
+
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
+
+subprojects {
+ apply plugin: 'info.solidsoft.pitest'
+ apply plugin: 'java-library'
+ apply plugin: 'jacoco'
+ apply plugin: 'io.spring.dependency-management'
+
+ compileJava.dependsOn validateStructure
+ sourceCompatibility = JavaVersion.VERSION_17
+
+ dependencies {
+ implementation 'io.projectreactor:reactor-core'
+ implementation 'io.projectreactor.addons:reactor-extra'
+ testImplementation 'io.projectreactor:reactor-test'
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.10.RELEASE'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+
+ compileOnly "org.projectlombok:lombok:${lombokVersion}"
+ annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
+ testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
+ testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
+ implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
+ }
+
+ tasks.withType(Test).configureEach {
+ if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) {
+ jvmArgs += [
+ "-XX:+AllowRedefinitionToAddDeleteMethods"
+ ]
+ }
+ }
+
+ test.finalizedBy(project.tasks.jacocoTestReport)
+
+ pitest {
+ targetClasses = ['your.package.*']
+ excludedClasses = []
+ excludedTestClasses = []
+ pitestVersion = '1.16.1'
+ verbose = true
+ outputFormats = ['XML', 'HTML']
+ threads = 8
+ exportLineCoverage = true
+ timestampedReports = false
+ //mutators = ['STRONGER', 'DEFAULTS']
+ fileExtensionsToFilter.addAll('xml', 'orbit')
+ junit5PluginVersion = '1.2.1'
+ failWhenNoMutations = false
+ jvmArgs = ["-XX:+AllowRedefinitionToAddDeleteMethods"]
+ }
+
+ jacocoTestReport {
+ dependsOn test, 'pitest'
+ reports {
+ xml.setRequired true
+ xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml")
+ csv.setRequired false
+ html.setOutputLocation layout.buildDirectory.dir("reports/jacocoHtml")
+ }
+ }
+
+ test {
+ useJUnitPlatform()
+ }
+
+}
+
+jacoco {
+ toolVersion = "${jacocoVersion}"
+ reportsDirectory.set(layout.buildDirectory.dir("reports"))
+}
+
+tasks.register('jacocoMergedReport', JacocoReport) {
+ dependsOn subprojects.jacocoTestReport, pitestReportAggregate,test
+ additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
+ sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
+ classDirectories.setFrom files(subprojects.sourceSets.main.output)
+ executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec')
+ reports {
+ xml.setRequired true
+ csv.setRequired false
+ html.setRequired true
+ }
+}
+
+tasks.withType(JavaCompile).configureEach {
+ options.compilerArgs = [
+ '-Amapstruct.suppressGeneratorTimestamp=true'
+ ]
+}
+
+pitestReportAggregate {
+ doLast {
+ def reportDir = layout.buildDirectory.dir("reports/pitest").get().asFile
+ def consolidatedReport = new File(reportDir, 'mutations.xml')
+ consolidatedReport.withWriter { writer ->
+ writer.write("\n")
+ subprojects.each { subproject ->
+ def xmlReport = subproject.layout.buildDirectory.file("reports/pitest/mutations.xml").get().asFile
+ if (xmlReport.exists()) {
+ def xmlContent = xmlReport.text
+ xmlContent = xmlContent.replaceAll("<\\?xml[^>]*>", "")
+ xmlContent = xmlContent.replaceAll("?mutations( partial=\"true\")?>", "")
+ writer.write(xmlContent.trim() + "\n")
+ }
+ }
+ writer.write("")
+ }
+ }
+}
+
+tasks.named('wrapper') {
+ gradleVersion = '8.10.1'
+}
\ No newline at end of file
diff --git a/src/test/resources/pitest/main-before.txt b/src/test/resources/pitest/main-before.txt
new file mode 100644
index 00000000..d4d5bd88
--- /dev/null
+++ b/src/test/resources/pitest/main-before.txt
@@ -0,0 +1,81 @@
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
+
+subprojects {
+ apply plugin: 'java-library'
+ apply plugin: 'jacoco'
+ apply plugin: 'io.spring.dependency-management'
+
+ compileJava.dependsOn validateStructure
+ sourceCompatibility = JavaVersion.VERSION_17
+
+ dependencies {
+ implementation 'io.projectreactor:reactor-core'
+ implementation 'io.projectreactor.addons:reactor-extra'
+ testImplementation 'io.projectreactor:reactor-test'
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.10.RELEASE'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+
+ compileOnly "org.projectlombok:lombok:${lombokVersion}"
+ annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
+ testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
+ testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
+ implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
+ }
+
+ tasks.withType(Test).configureEach {
+ if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) {
+ jvmArgs += [
+ "-XX:+AllowRedefinitionToAddDeleteMethods"
+ ]
+ }
+ }
+
+ test.finalizedBy(project.tasks.jacocoTestReport)
+
+ jacocoTestReport {
+ dependsOn test
+ reports {
+ xml.setRequired true
+ xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml")
+ csv.setRequired false
+ html.setOutputLocation layout.buildDirectory.dir("reports/jacocoHtml")
+ }
+ }
+
+ test {
+ useJUnitPlatform()
+ }
+
+}
+
+jacoco {
+ toolVersion = "${jacocoVersion}"
+ reportsDirectory.set(layout.buildDirectory.dir("reports"))
+}
+
+tasks.register('jacocoMergedReport', JacocoReport) {
+ dependsOn subprojects.jacocoTestReport,test
+ additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
+ sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
+ classDirectories.setFrom files(subprojects.sourceSets.main.output)
+ executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec')
+ reports {
+ xml.setRequired true
+ csv.setRequired false
+ html.setRequired true
+ }
+}
+
+tasks.withType(JavaCompile).configureEach {
+ options.compilerArgs = [
+ '-Amapstruct.suppressGeneratorTimestamp=true'
+ ]
+}
+tasks.named('wrapper') {
+ gradleVersion = '8.10.1'
+}
\ No newline at end of file