From f60d6c11b6e498cdbf764243f3647f1d4adb891b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Guillermo=20G=C3=B3mez=20Galeano?= <44306301+luisgomez29@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:43:40 -0500 Subject: [PATCH] feat(gradle): add UpgradeAction for gradle 8.11 (#580) * feat(gradle): Add UpgradeAction for gradle 8.11 --- build.gradle | 30 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- .../java/co/com/bancolombia/Constants.java | 2 +- .../actions/UpgradeY2024M11D16Gradle.java | 49 +++++++ .../structure/root/main.gradle.mustache | 8 +- .../actions/UpgradeY2024M11D16GradleTest.java | 61 +++++++++ .../gradle-8.11-sample/main-after.txt | 129 ++++++++++++++++++ .../gradle-8.11-sample/main-before.txt | 127 +++++++++++++++++ 8 files changed, 390 insertions(+), 18 deletions(-) create mode 100644 src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16Gradle.java create mode 100644 src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16GradleTest.java create mode 100644 src/test/resources/gradle-8.11-sample/main-after.txt create mode 100644 src/test/resources/gradle-8.11-sample/main-before.txt diff --git a/build.gradle b/build.gradle index 7e77e58a..2caab862 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ plugins { id 'com.gradle.plugin-publish' version '1.3.0' id 'com.github.sherter.google-java-format' version '0.9' id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' - id 'org.owasp.dependencycheck' version '10.0.4' + id 'org.owasp.dependencycheck' version '11.1.0' } ext { @@ -175,16 +175,16 @@ if (project.hasProperty('signing.keyId')) { // publish as library in maven centr dependencies { api 'com.github.spullara.mustache.java:compiler:0.9.14' - api 'com.fasterxml.jackson.core:jackson-databind:2.18.0' - api 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.0' - api 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.18.0' + api 'com.fasterxml.jackson.core:jackson-databind:2.18.1' + api 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1' + api 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.18.1' api 'commons-io:commons-io:2.17.0' api gradleApi() - implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.0' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.1' implementation 'org.reflections:reflections:0.10.2' // swagger generators - implementation('io.swagger.codegen.v3:swagger-codegen-generators:1.0.53') { + implementation('io.swagger.codegen.v3:swagger-codegen-generators:1.0.54') { exclude group: 'net.sf.jopt-simple', module: 'jopt-simple' } constraints { // for previous swagger dependency @@ -197,13 +197,13 @@ dependencies { testImplementation gradleTestKit() testImplementation 'org.mockito:mockito-junit-jupiter:5.14.2' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.2' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.2' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.11.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.3' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.3' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.11.3' - compileOnly 'org.projectlombok:lombok:1.18.34' - annotationProcessor 'org.projectlombok:lombok:1.18.34' + compileOnly 'org.projectlombok:lombok:1.18.36' + annotationProcessor 'org.projectlombok:lombok:1.18.36' implementation 'com.squareup.okhttp3:okhttp:4.12.0' testImplementation 'com.squareup.okhttp3:mockwebserver:4.12.0' } @@ -261,7 +261,9 @@ tasks.register('copyPreCommit', Copy) { tasks.register('downloadCommitMessage') { def f = new File('.git/hooks/commit-msg.sample2') if (!f.exists()) { - new URL('https://raw.githubusercontent.com/hazcod/semantic-commit-hook/master/commit-msg').withInputStream { i -> f.withOutputStream { it << i } } + new URL('https://raw.githubusercontent.com/hazcod/semantic-commit-hook/master/commit-msg').withInputStream { + i -> f.withOutputStream { it << i } + } } } @@ -281,7 +283,7 @@ tasks.register('installGitHooks') { } tasks.named('wrapper') { - gradleVersion = '8.10.2' + gradleVersion = '8.11' } tasks.register('ci-updater', JavaExec) { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72b..94113f20 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/co/com/bancolombia/Constants.java b/src/main/java/co/com/bancolombia/Constants.java index 2f68a8cd..518da785 100644 --- a/src/main/java/co/com/bancolombia/Constants.java +++ b/src/main/java/co/com/bancolombia/Constants.java @@ -32,7 +32,7 @@ public final class Constants { public static final String DEPENDENCY_CHECK_VERSION = "11.1.0"; public static final String PITEST_VERSION = "1.15.0"; // custom - public static final String GRADLE_WRAPPER_VERSION = "8.10.2"; + public static final String GRADLE_WRAPPER_VERSION = "8.11"; @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class MainFiles { diff --git a/src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16Gradle.java b/src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16Gradle.java new file mode 100644 index 00000000..435dd4b6 --- /dev/null +++ b/src/main/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16Gradle.java @@ -0,0 +1,49 @@ +package co.com.bancolombia.factory.upgrades.actions; + +import static co.com.bancolombia.Constants.MainFiles.MAIN_GRADLE; + +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 UpgradeY2024M11D16Gradle implements UpgradeAction { + private static final String JAVA_BLOCK_CONFIG = + "java {\n {{sourceCompatibilityLoaded}}\n }"; + + @Override + @SneakyThrows + public boolean up(ModuleBuilder builder) { + return builder.updateFile( + MAIN_GRADLE, + content -> { + String sourceCompatibilityLoaded = + builder + .findExpressions( + MAIN_GRADLE, "sourceCompatibility = JavaVersion.VERSION_(\\d{2})") + .stream() + .findFirst() + .orElse(null); + + if (sourceCompatibilityLoaded == null) { + sourceCompatibilityLoaded = "sourceCompatibility = JavaVersion.{{javaVersion}}"; + } + + return UpdateUtils.replace( + content, + sourceCompatibilityLoaded, + JAVA_BLOCK_CONFIG.replace( + "{{sourceCompatibilityLoaded}}", sourceCompatibilityLoaded)); + }); + } + + @Override + public String name() { + return "3.18.2->3.18.3"; + } + + @Override + public String description() { + return "Add java { } configuration block, backed by JavaPluginExtension"; + } +} diff --git a/src/main/resources/structure/root/main.gradle.mustache b/src/main/resources/structure/root/main.gradle.mustache index 17f5a7de..549c729b 100644 --- a/src/main/resources/structure/root/main.gradle.mustache +++ b/src/main/resources/structure/root/main.gradle.mustache @@ -19,7 +19,10 @@ subprojects { {{/mutation}} compileJava.dependsOn validateStructure - sourceCompatibility = JavaVersion.{{javaVersion}} + + java { + sourceCompatibility = JavaVersion.{{javaVersion}} + } {{#mutation}} //build.dependsOn 'pitest' @@ -66,11 +69,12 @@ subprojects { targetClasses = ['{{package}}.*'] excludedClasses = [] excludedTestClasses = [] - pitestVersion = '1.16.1' + pitestVersion = '1.17.1' verbose = true outputFormats = ['XML', 'HTML'] threads = 8 exportLineCoverage = true + useClasspathFile = true timestampedReports = false //mutators = ['STRONGER', 'DEFAULTS'] fileExtensionsToFilter.addAll('xml', 'orbit') diff --git a/src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16GradleTest.java b/src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16GradleTest.java new file mode 100644 index 00000000..0492bf6f --- /dev/null +++ b/src/test/java/co/com/bancolombia/factory/upgrades/actions/UpgradeY2024M11D16GradleTest.java @@ -0,0 +1,61 @@ +package co.com.bancolombia.factory.upgrades.actions; + +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 UpgradeY2024M11D16GradleTest { + + @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 UpgradeY2024M11D16Gradle(); + + assertNotNull(updater.name()); + assertNotNull(updater.description()); + } + + @Test + void shouldApplyUpdate() throws IOException { + DefaultResolver resolver = new DefaultResolver(); + // Arrange + builder.addFile( + MAIN_GRADLE, FileUtils.getResourceAsString(resolver, "gradle-8.11-sample/main-before.txt")); + // Act + boolean applied = updater.up(builder); + // Assert + assertTrue(applied); + verify(builder) + .addFile( + MAIN_GRADLE, + FileUtils.getResourceAsString(resolver, "gradle-8.11-sample/main-after.txt")); + } +} diff --git a/src/test/resources/gradle-8.11-sample/main-after.txt b/src/test/resources/gradle-8.11-sample/main-after.txt new file mode 100644 index 00000000..288577d4 --- /dev/null +++ b/src/test/resources/gradle-8.11-sample/main-after.txt @@ -0,0 +1,129 @@ +apply plugin: 'info.solidsoft.pitest.aggregator' + +allprojects { + repositories { + mavenCentral() + maven { url "https://repo.spring.io/snapshot" } + maven { url "https://repo.spring.io/milestone" } + } +} + +subprojects { + apply plugin: 'info.solidsoft.pitest' + apply plugin: 'java' + apply plugin: 'jacoco' + apply plugin: 'io.spring.dependency-management' + + compileJava.dependsOn validateStructure + java { + sourceCompatibility = JavaVersion.VERSION_17 + } + + test { + useJUnitPlatform() + } + + dependencies { + implementation platform('software.amazon.awssdk:bom:2.29.15') + implementation 'io.projectreactor:reactor-core' + implementation 'io.projectreactor.addons:reactor-extra' + + testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.10.RELEASE' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + testImplementation 'io.projectreactor:reactor-test' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + 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") + } + } + +} + +jacoco { + toolVersion = "${jacocoVersion}" + reportsDirectory.set(layout.buildDirectory.dir("reports")) +} + +tasks.register('jacocoMergedReport', JacocoReport) { + 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) + 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("", "") + writer.write(xmlContent.trim() + "\n") + } + } + writer.write("") + } + } +} + +tasks.named('wrapper') { + gradleVersion = '8.10.2' +} \ No newline at end of file diff --git a/src/test/resources/gradle-8.11-sample/main-before.txt b/src/test/resources/gradle-8.11-sample/main-before.txt new file mode 100644 index 00000000..36f5a067 --- /dev/null +++ b/src/test/resources/gradle-8.11-sample/main-before.txt @@ -0,0 +1,127 @@ +apply plugin: 'info.solidsoft.pitest.aggregator' + +allprojects { + repositories { + mavenCentral() + maven { url "https://repo.spring.io/snapshot" } + maven { url "https://repo.spring.io/milestone" } + } +} + +subprojects { + apply plugin: 'info.solidsoft.pitest' + apply plugin: 'java' + apply plugin: 'jacoco' + apply plugin: 'io.spring.dependency-management' + + compileJava.dependsOn validateStructure + sourceCompatibility = JavaVersion.VERSION_17 + + test { + useJUnitPlatform() + } + + dependencies { + implementation platform('software.amazon.awssdk:bom:2.29.15') + implementation 'io.projectreactor:reactor-core' + implementation 'io.projectreactor.addons:reactor-extra' + + testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.10.RELEASE' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + testImplementation 'io.projectreactor:reactor-test' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + 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") + } + } + +} + +jacoco { + toolVersion = "${jacocoVersion}" + reportsDirectory.set(layout.buildDirectory.dir("reports")) +} + +tasks.register('jacocoMergedReport', JacocoReport) { + 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) + 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("", "") + writer.write(xmlContent.trim() + "\n") + } + } + writer.write("") + } + } +} + +tasks.named('wrapper') { + gradleVersion = '8.10.2' +} \ No newline at end of file