diff --git a/build.gradle b/build.gradle index 92a8e603..afa8e13c 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ version = '0.0.1-SNAPSHOT' wrapper { distributionType = Wrapper.DistributionType.BIN - gradleVersion = '8.5' + gradleVersion = '8.12.1' } // TODO.impl: self-attaching is deprecated, see: @@ -42,8 +42,8 @@ configurations { repositories { mavenCentral() - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } + maven { url = 'https://repo.spring.io/milestone' } + maven { url = 'https://repo.spring.io/snapshot' } } java { @@ -109,14 +109,14 @@ dependencyManagement { } // Java Compiler Options -tasks.withType(JavaCompile) { +tasks.withType(JavaCompile).configureEach { options.compilerArgs += [ "-parameters" // keep parameter names => no need for @Param for SpringData ] } // Configure tests -tasks.named('test') { +tasks.withType(Test).configureEach { useJUnitPlatform() jvmArgs '-Duser.language=en' jvmArgs '-Duser.country=US' @@ -342,8 +342,11 @@ tasks.register('unitTest', Test) { 'officeIntegrationTest', 'bookingIntegrationTest', 'hostingIntegrationTest' } - group 'verification' - description 'runs all unit-tests which do not need a database' + group = 'verification' + description = 'runs all unit-tests which do not need a database' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -354,8 +357,11 @@ tasks.register('generalIntegrationTest', Test) { includeTags 'generalIntegrationTest' } - group 'verification' - description 'runs integration tests which are not specific to a module, like base, rbac, config etc.' + group = 'verification' + description = 'runs integration tests which are not specific to a module, like base, rbac, config etc.' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -366,8 +372,11 @@ tasks.register('officeIntegrationTest', Test) { includeTags 'officeIntegrationTest' } - group 'verification' - description 'runs integration tests of the office module' + group = 'verification' + description = 'runs integration tests of the office module' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -378,8 +387,11 @@ tasks.register('bookingIntegrationTest', Test) { includeTags 'bookingIntegrationTest' } - group 'verification' - description 'runs integration tests of the booking module' + group = 'verification' + description = 'runs integration tests of the booking module' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -390,8 +402,11 @@ tasks.register('hostingIntegrationTest', Test) { includeTags 'hostingIntegrationTest' } - group 'verification' - description 'runs integration tests of the hosting module' + group = 'verification' + description = 'runs integration tests of the hosting module' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -401,8 +416,11 @@ tasks.register('importOfficeData', Test) { includeTags 'importOfficeData' } - group 'verification' - description 'run the import jobs as tests' + group = 'verification' + description = 'run the import jobs as tests' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -412,8 +430,11 @@ tasks.register('importHostingAssets', Test) { includeTags 'importHostingAssets' } - group 'verification' - description 'run the import jobs as tests' + group = 'verification' + description = 'run the import jobs as tests' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } @@ -423,8 +444,11 @@ tasks.register('scenarioTest', Test) { includeTags 'scenarioTest' } - group 'verification' - description 'run the import jobs as tests' + group = 'verification' + description = 'run the import jobs as tests' + + testClassesDirs = testing.suites.test.sources.output.classesDirs + classpath = testing.suites.test.sources.runtimeClasspath mustRunAfter spotlessJava } diff --git a/build.gradle.kotlin b/build.gradle.kotlin new file mode 100644 index 00000000..e9ca6c46 --- /dev/null +++ b/build.gradle.kotlin @@ -0,0 +1,519 @@ +plugins { + `java-platform` + //id( "java" ) + id( "org.springframework.boot") version "3.4.1" + id( "io.spring.dependency-management") version "1.1.7" // manages implicit dependencies + id( "io.openapiprocessor.openapi-processor") version "2023.2" // generates Controller-interface and resources from API-spec + id( "com.github.jk1.dependency-license-report") version "2.9" // checks dependency-license compatibility + id( "org.owasp.dependencycheck") version "12.0.1" // checks dependencies for known vulnerabilities + id( "com.diffplug.spotless") version "7.0.2" // formats + checks formatting for source-code + id( "jacoco") // determines code-coverage of tests + id( "info.solidsoft.pitest") version "1.15.0" // performs mutation testing + id( "se.patrikerdes.use-latest-versions") version "0.2.18" // updates module and plugin versions + id( "com.github.ben-manes.versions") version "0.52.0" // determines which dependencies have updates +} + +// HOWTO: find out which dependency versions are managed by Spring Boot: +// https://docs.spring.io/spring-boot/appendix/dependency-versions/coordinates.html + +group = "net.hostsharing" +version = "0.0.1-SNAPSHOT" + +tasks.named("wrapper") { + distributionType = Wrapper.DistributionType.BIN + gradleVersion = "8.5" +} + + +// TODO.impl: self-attaching is deprecated, see: +// https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3 + +configurations { + named("compileOnly") { + extendsFrom(configurations.named("annotationProcessor").get()) + } + named("testCompile") { + extendsFrom(configurations.named("testAnnotationProcessor").get()) + + // Only JUnit 5 (Jupiter) should be used at compile time. + // For runtime it's still needed by testcontainers, though. + exclude(group = "junit", module = "junit") + exclude(group = "org.junit.vintage", module = "junit-vintage-engine") + } +} + + +extensions.configure { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + vendor.set(JvmVendorSpec.ADOPTIUM) + implementation.set(JvmImplementation.VENDOR_SPECIFIC) + } +} + +extra["testcontainersVersion"] = "1.17.3" + +allprojects { + repositories { + mavenCentral() + maven { url = uri("https://repo.spring.io/milestone") } + maven { url = uri("https://repo.spring.io/snapshot") } + } + dependencies { + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-data-rest") + implementation("org.springframework.boot:spring-boot-starter-jdbc") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-validation") + implementation("org.springframework.boot:spring-boot-starter-actuator") + implementation("org.springframework.boot:spring-boot-starter-security") + implementation("com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0") + implementation("org.springdoc:springdoc-openapi:2.8.3") + classpath("org.postgresql:postgresql") + classpath("org.liquibase:liquibase-core") + classpath("io.hypersistence:hypersistence-utils-hibernate-63:3.9.0") + classpath("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") + classpath("org.openapitools:jackson-databind-nullable:0.2.6") + classpath("org.apache.commons:commons-text:1.13.0") + classpath("net.java.dev.jna:jna:5.16.0") + classpath("org.modelmapper:modelmapper:3.2.2") + classpath("org.iban4j:iban4j:3.2.10-RELEASE") + classpath("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.3") + classpath("org.reflections:reflections:0.10.2") + + compileOnly("org.projectlombok:lombok") + testCompileOnly("org.projectlombok:lombok") + + // TODO.impl: version conflict with SpringDoc, check later and re-enable if fixed + // developmentOnly "org.springframework.boot:spring-boot-devtools" + + annotationProcessor("org.projectlombok:lombok") + testAnnotationProcessor("org.projectlombok:lombok") + + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.testcontainers:testcontainers") + testImplementation("org.testcontainers:junit-jupiter") + testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation("org.testcontainers:postgresql") + testImplementation("com.tngtech.archunit:archunit-junit5:1.3.0") + testImplementation("io.rest-assured:spring-mock-mvc") + testImplementation("org.hamcrest:hamcrest-core") + testImplementation("org.pitest:pitest-junit5-plugin:1.2.1") + testImplementation("org.junit.jupiter:junit-jupiter-api") + testImplementation("org.wiremock:wiremock-standalone:3.10.0") + } +} + +// Java Compiler Options +tasks.withType().configureEach { + options.compilerArgs.add("-parameters") // keep parameter names => no need for @Param for SpringData +} + +// Configure tests +tasks.withType { + useJUnitPlatform() + jvmArgs("-Duser.language=en", "-Duser.country=US") +} + +// OpenAPI Source Code Generation +//openapiProcessor { +// springRoot { +// processorName = "spring" +// processor = "io.openapiprocessor:openapi-processor-spring:2022.5" +// apiPath "$projectDir/src/main/resources/api-definition/api-definition.yaml" +// mapping "$projectDir/src/main/resources/api-definition/api-mappings.yaml" +// targetDir layout.buildDirectory.dir("generated/sources/openapi-javax") +// showWarnings true +// openApiNullable true +// } +// springRbac { +// processorName "spring" +// processor "io.openapiprocessor:openapi-processor-spring:2022.5" +// apiPath "$projectDir/src/main/resources/api-definition/rbac/rbac.yaml" +// mapping "$projectDir/src/main/resources/api-definition/rbac/api-mappings.yaml" +// targetDir layout.buildDirectory.dir("generated/sources/openapi-javax") +// showWarnings true +// openApiNullable true +// } +// springTest { +// processorName "spring" +// processor "io.openapiprocessor:openapi-processor-spring:2022.5" +// apiPath "$projectDir/src/main/resources/api-definition/test/test.yaml" +// mapping "$projectDir/src/main/resources/api-definition/test/api-mappings.yaml" +// targetDir layout.buildDirectory.dir("generated/sources/openapi-javax") +// showWarnings true +// openApiNullable true +// } +// springHsOffice { +// processorName "spring" +// processor "io.openapiprocessor:openapi-processor-spring:2022.5" +// apiPath "$projectDir/src/main/resources/api-definition/hs-office/hs-office.yaml" +// mapping "$projectDir/src/main/resources/api-definition/hs-office/api-mappings.yaml" +// targetDir layout.buildDirectory.dir("generated/sources/openapi-javax") +// showWarnings true +// openApiNullable true +// } +// springHsBooking { +// processorName "spring" +// processor "io.openapiprocessor:openapi-processor-spring:2022.5" +// apiPath "$projectDir/src/main/resources/api-definition/hs-booking/hs-booking.yaml" +// mapping "$projectDir/src/main/resources/api-definition/hs-booking/api-mappings.yaml" +// targetDir layout.buildDirectory.dir("generated/sources/openapi-javax") +// showWarnings true +// openApiNullable true +// } +// springHsHosting { +// processorName "spring" +// processor "io.openapiprocessor:openapi-processor-spring:2022.5" +// apiPath "$projectDir/src/main/resources/api-definition/hs-hosting/hs-hosting.yaml" +// mapping "$projectDir/src/main/resources/api-definition/hs-hosting/api-mappings.yaml" +// targetDir layout.buildDirectory.dir("generated/sources/openapi-javax") +// showWarnings true +// openApiNullable true +// } +//} +//sourceSets.main.java.srcDir "build/generated/sources/openapi" + +//abstract class ProcessSpring extends DefaultTask {} + +//tasks.register("processSpring", ProcessSpring) +//["processSpringRoot", +// "processSpringRbac", +// "processSpringTest", +// "processSpringHsOffice", +// "processSpringHsBooking", +// "processSpringHsHosting" +//].each { +// project.tasks.processSpring.dependsOn it +//} +//project.tasks.processResources.dependsOn processSpring +// project.tasks.compileJava.dependsOn processSpring + +// Rename javax to jakarta in OpenApi generated java files because +// io.openapiprocessor.openapi-processor 2022.5 does not yet support the openapiprocessor useSpringBoot3 config option. +// TODO.impl: Upgrade to io.openapiprocessor.openapi-processor >= 2024.2 +// and use either `bean-validation: true` in api-mapping.yaml or `useSpringBoot3 true` (not sure where exactly). +//task openApiGenerate(type: Copy) { +// from layout.buildDirectory.dir("generated/sources/openapi-javax") +// into layout.buildDirectory.dir("generated/sources/openapi") +// filter { line -> line.replaceAll("javax", "jakarta") } +} +//compileJava.source layout.buildDirectory.dir("generated/sources/openapi") +//compileJava.dependsOn openApiGenerate +// openApiGenerate.dependsOn processSpring + +// Spotless Code Formatting +// spotless { +// java { +// removeUnusedImports() +// leadingTabsToSpaces(4) +// endWithNewline() +// toggleOffOn() +// +// target fileTree(rootDir) { +// include "**/*.java" +// exclude "**/generated/**/*.java" +// } +// } +// } +//project.tasks.check.dependsOn(spotlessCheck) +// HACK: no idea why spotless uses the output of these tasks, but we get warnings without those +//project.tasks.spotlessJava.dependsOn( +// tasks.generateLicenseReport, +// // tasks.pitest, TODO.test: PiTest currently does not work, needs to be fixed +// tasks.jacocoTestReport, +// tasks.processResources, +// tasks.processTestResources) + +// OWASP Dependency Security Test +//dependencyCheck { +// nvd { +// apiKey = project.properties["OWASP_API_KEY"] // set it in ~/.gradle/gradle.properties +// delay = 16000 +// } +// format = "ALL" +// suppressionFile = "etc/owasp-dependency-check-suppression.xml" +// failOnError = true +// failBuildOnCVSS = 5 +//} +//project.tasks.check.dependsOn(dependencyCheckAnalyze) +//project.tasks.dependencyCheckAnalyze.doFirst { // Why not doLast? See README.md! +// println "OWASP Dependency Security Report: file:///${project.rootDir}/build/reports/dependency-check-report.html" +//} + + +// License Check +//licenseReport { +// excludeBoms = true +// allowedLicensesFile = new File("$projectDir/etc/allowed-licenses.json") +//} +//project.tasks.check.dependsOn(checkLicense) + +// HOWTO: run all tests except import- and scenario-tests: gw test +//test { +// finalizedBy jacocoTestReport // generate report after tests +// excludes = [ +// "net.hostsharing.hsadminng.**.generated.**", +// ] +// useJUnitPlatform { +// excludeTags "importOfficeData", "importHostingAssets", "scenarioTest" +// } +//} + +// JaCoCo Test Code Coverage for unit-tests +//jacoco { +// toolVersion = "0.8.10" +//} +//jacocoTestReport { +// dependsOn test +// afterEvaluate { +// classDirectories.setFrom(files(classDirectories.files.collect { +// fileTree(dir: it, exclude: [ +// "net/hostsharing/hsadminng/**/generated/**/*.class", +// "net/hostsharing/hsadminng/hs/HsadminNgApplication.class" +// ]) +// })) +// } +// doFirst { // Why not doLast? See README.md! +// println "HTML Jacoco Test Code Coverage Report: file://${reports.html.outputLocation.get()}/index.html" +// } +//} +//project.tasks.check.dependsOn(jacocoTestCoverageVerification) +//jacocoTestCoverageVerification { +// violationRules { +// rule { +// limit { +// minimum = 0.80 // TODO.test: improve instruction coverage +// } +// } +// +// // element: PACKAGE, BUNDLE, CLASS, SOURCEFILE or METHOD +// // counter: INSTRUCTION, BRANCH, LINE, COMPLEXITY, METHOD, or CLASS +// // value: TOTALCOUNT, COVEREDCOUNT, MISSEDCOUNT, COVEREDRATIO or MISSEDRATIO +// +// rule { +// element = "CLASS" +// excludes = [ +// "net.hostsharing.hsadminng.**.generated.**", +// "net.hostsharing.hsadminng.rbac.test.dom.TestDomainEntity", +// "net.hostsharing.hsadminng.HsadminNgApplication", +// "net.hostsharing.hsadminng.ping.PingController", +// "net.hostsharing.hsadminng.rbac.generator.*", +// "net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService", +// "net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService.Node", +// "net.hostsharing.hsadminng.**.*Repository", +// "net.hostsharing.hsadminng.mapper.Mapper" +// ] +// +// limit { +// counter = "LINE" +// value = "COVEREDRATIO" +// minimum = 0.75 // TODO.test: improve line coverage +// } +// } +// rule { +// element = "METHOD" +// excludes = [ +// "net.hostsharing.hsadminng.**.generated.**", +// "net.hostsharing.hsadminng.HsadminNgApplication.main", +// "net.hostsharing.hsadminng.ping.PingController.*" +// ] +// +// limit { +// counter = "BRANCH" +// value = "COVEREDRATIO" +// minimum = 0.00 // TODO.test: improve branch coverage +// } +// } +// } +//} + +// HOWTO: run all unit-tests which don"t need a database: gw-test unitTest +//tasks.register("unitTest", Test) { +// useJUnitPlatform { +// excludeTags "importOfficeData", "importHostingAssets", "scenarioTest", "generalIntegrationTest", +// "officeIntegrationTest", "bookingIntegrationTest", "hostingIntegrationTest" +// } +// +// group "verification" +// description "runs all unit-tests which do not need a database" +// +// mustRunAfter spotlessJava +//} + +// HOWTO: run all integration tests which are not specific to a module, like base, rbac, config etc. +//tasks.register("generalIntegrationTest", Test) { +// useJUnitPlatform { +// includeTags "generalIntegrationTest" +// } +// +// group "verification" +// description "runs integration tests which are not specific to a module, like base, rbac, config etc." +// +// mustRunAfter spotlessJava +//} + +// HOWTO: run all integration tests of the office module: gw-test officeIntegrationTest +//tasks.register("officeIntegrationTest", Test) { +// useJUnitPlatform { +// includeTags "officeIntegrationTest" +// } +// +// group "verification" +// description "runs integration tests of the office module" +// +// mustRunAfter spotlessJava +//} + +// HOWTO: run all integration tests of the booking module: gw-test bookingIntegrationTest +//tasks.register("bookingIntegrationTest", Test) { +// useJUnitPlatform { +// includeTags "bookingIntegrationTest" +// } +// +// group "verification" +// description "runs integration tests of the booking module" +// +// mustRunAfter spotlessJava +//} + +// HOWTO: run all integration tests of the hosting module: gw-test hostingIntegrationTest +//tasks.register("hostingIntegrationTest", Test) { +// useJUnitPlatform { +// includeTags "hostingIntegrationTest" +// } +// +// group "verification" +// description "runs integration tests of the hosting module" +// +// mustRunAfter spotlessJava +//} + +//tasks.register("importOfficeData", Test) { +// useJUnitPlatform { +// includeTags "importOfficeData" +// } +// +// group "verification" +// description "run the import jobs as tests" +// +// mustRunAfter spotlessJava +//} + +//tasks.register("importHostingAssets", Test) { +// useJUnitPlatform { +// includeTags "importHostingAssets" +// } +// +// group "verification" +// description "run the import jobs as tests" +// +// mustRunAfter spotlessJava +//} + +//tasks.register("scenarioTest", Test) { +// useJUnitPlatform { +// includeTags "scenarioTest" +// } +// +// group "verification" +// description "run the import jobs as tests" +// +// mustRunAfter spotlessJava +//} + +// pitest mutation testing +//pitest { +// targetClasses = ["net.hostsharing.hsadminng.**"] +// excludedClasses = [ +// "net.hostsharing.hsadminng.config.**", +// // "net.hostsharing.hsadminng.**.*Controller", +// "net.hostsharing.hsadminng.**.generated.**" +// ] +// +// targetTests = ["net.hostsharing.hsadminng.**.*UnitTest", "net.hostsharing.hsadminng.**.*RestTest"] +// excludedTestClasses = ["**AcceptanceTest*", "**IntegrationTest*", "**ImportOfficeData", "**ImportHostingAssets"] +// +// pitestVersion = "1.17.0" +// junit5PluginVersion = "1.1.0" +// +// threads = 4 +// +// // As Java unit tests are pretty pointless in our case, this maybe makes not much sense. +// mutationThreshold = 71 +// coverageThreshold = 57 +// testStrengthThreshold = 87 +// +// outputFormats = ["XML", "HTML"] +// timestampedReports = false +//} +// project.tasks.check.dependsOn(project.tasks.pitest) TODO.test: PiTest currently does not work, needs to be fixed +//project.tasks.pitest.doFirst { // Why not doLast? See README.md! +// println "PiTest Mutation Report: file:///${project.rootDir}/build/reports/pitest/index.html" +//} + + +// Dependency Versions Upgrade +//useLatestVersions { +// finalizedBy check +//} + +//def isNonStable = { String version -> +// def stableKeyword = ["RELEASE", "FINAL", "GA"].any { it -> version.toUpperCase().contains(it) } +// def regex = /^[0-9,.v-]+(-r)?$/ +// return !stableKeyword && !(version ==~ regex) +//} + +//tasks.named("dependencyUpdates").configure { +// rejectVersionIf { +// isNonStable(it.candidate.version) +// } +//} + + +// Generate HTML from Markdown scenario-test-reports using Pandoc: +//tasks.register("convertMarkdownToHtml") { +// description = "Generates HTML from Markdown scenario-test-reports using Pandoc." +// group = "Conversion" +// +// // Define the template file and input directory +// def templateFile = file("doc/scenarios/.template.html") +// +// // Task configuration and execution +// doFirst { +// // Check if pandoc is installed +// try { +// exec { +// commandLine "pandoc", "--version" +// } +// } catch (Exception) { +// throw new GradleException("Pandoc is not installed or not found in the system path.") +// } +// +// // Check if the template file exists +// if (!templateFile.exists()) { +// throw new GradleException("Template file "doc/scenarios/.template.html" not found.") +// } +// } +// +// doLast { +// // Gather all Markdown files in the current directory +// fileTree(dir: ".", include: "build/doc/scenarios/*.md").each { file -> +// // Corrected way to create the output file path +// def outputFile = new File(file.parent, file.name.replaceAll(/\.md$/, ".html")) +// +// // Execute pandoc for each markdown file +// exec { +// commandLine "pandoc", file.absolutePath, "--template", templateFile.absolutePath, "-o", outputFile.absolutePath +// } +// +// println "Converted ${file.name} to ${outputFile.name}" +// } +// } +//} +//convertMarkdownToHtml.dependsOn scenarioTest + +// shortcut for compiling all files +// tasks.register("compile") { +// dependsOn "compileJava", "compileTestJava" +// } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491..a4b76b95 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e093..e18bc253 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.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42..f3b75f3b 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/settings.gradle b/settings.gradle index d6f3f9eb..f72a2bbf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ pluginManagement { repositories { - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } + maven { url = 'https://repo.spring.io/milestone' } + maven { url = 'https://repo.spring.io/snapshot' } gradlePluginPortal() mavenCentral() }