mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-14 10:34:06 +02:00
294b616a63
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 4.0.5 to 4.0.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/spring-projects/spring-boot/releases">org.springframework.boot:spring-boot-dependencies's releases</a>.</em></p> <blockquote> <h2>v4.0.6</h2> <h2>🐞 Bug Fixes</h2> <ul> <li>Default security is misconfigured when spring-boot-actuator-autoconfigure is present and spring-boot-health is not <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50188">#50188</a></li> <li>Elasticsearch Rest5Client auto-configuration misconfigures underlying HTTP client <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50187">#50187</a></li> <li>ApplicationPidFileWriter does not handle symlinks correctly <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50185">#50185</a></li> <li>RandomValuePropertySource is not suitable for secrets <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50183">#50183</a></li> <li>Cassandra auto-configuration misconfigures CqlSessionBuilder <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50180">#50180</a></li> <li>ApplicationTemp does not handle symlinks correctly <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50178">#50178</a></li> <li>Remote DevTools performs comparison incorrectly <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50176">#50176</a></li> <li>spring.rabbitmq.ssl.verify-hostname is applied inconsistently <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50174">#50174</a></li> <li>Whole number values are ignored when configuring min and max expected values and SLO boundaries for a distribution summary meter <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50077">#50077</a></li> <li>Classic starters are missing several modules <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50071">#50071</a></li> <li>Module spring-boot-resttestclient is missing from spring-boot-starter-test-classic <a href="https://redirect.github.com/spring-projects/spring-boot/pull/50069">#50069</a></li> <li>Annotations like <code>@Ssl</code> don't work on <code>@Bean</code> methods when using <code>@ServiceConnection</code> <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50064">#50064</a></li> <li>EnversRevisionRepositoriesRegistrar should reuse <code>@EnableEnversRepositories</code> rather than configuring the JPA counterpart <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50039">#50039</a></li> <li>WebFlux Cloud Foundry links endpoint includes query string from received request in resolved links <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50017">#50017</a></li> <li>Imports on a containing test class are ignored when a nested class has imports <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50012">#50012</a></li> <li>With spring.jackson.use-jackson2-defaults set to true, FAIL_ON_UNKNOWN_PROPERTIES is enabled <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49951">#49951</a></li> <li>500 response from env endpoint when supplied pattern is invalid <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49946">#49946</a></li> <li>Reactive MongoDB starter has a transitive dependency on the synchronous MongoDB driver <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49945">#49945</a></li> <li>HTTP method is lost when configuring excludes in EndpointRequest <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49943">#49943</a></li> <li>Honor HttpMethod for reactive additional endpoint paths <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49880">#49880</a></li> <li>Docker Compose support doesn't work with apache/artemis image <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49869">#49869</a></li> <li>Docker Compose support doesn't work with apache/activemq image <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49866">#49866</a></li> <li>Spring Security's PathPatternRequestMatcher.Builder is not auto-configured when using WebMvcTest and spring-boot-security-test <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49854">#49854</a></li> <li>API versioning path strategy should be applied path last as it is not meant to yield <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49800">#49800</a></li> </ul> <h2>📔 Documentation</h2> <ul> <li>Update docs to encourage Java fundamentals for beginners that prefer to learn that way <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50146">#50146</a></li> <li>HTTP Service Interface Clients still document that API versioning can be configured via properties <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50126">#50126</a></li> <li>Link to the observability section of the Lettuce documentation is broken <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50097">#50097</a></li> <li>Javadoc for StaticResourceLocation.FAVICON doesn't describe icons location <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50085">#50085</a></li> <li>MySamlRelyingPartyConfiguration is missing a Kotlin sample <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50024">#50024</a></li> <li>Incorrect default value for management.httpexchanges.recording.include in configuration metadata <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50019">#50019</a></li> <li>Link to the Kubernetes documentation when discussing startup probes <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50015">#50015</a></li> <li>Typo in JdbcSessionAutoConfiguration Javadoc <a href="https://redirect.github.com/spring-projects/spring-boot/pull/49873">#49873</a></li> <li>Clarify that configuration property default values are not available through the Environment <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49851">#49851</a></li> <li>Document the need for Liquibase and Flyway starters <a href="https://redirect.github.com/spring-projects/spring-boot/pull/49839">#49839</a></li> <li>Kafka documentation refers to deprecated JSON serializer and deserializer classes <a href="https://redirect.github.com/spring-projects/spring-boot/pull/49826">#49826</a></li> </ul> <h2>🔨 Dependency Upgrades</h2> <ul> <li>Upgrade to Elasticsearch Client 9.2.8 <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50027">#50027</a></li> <li>Upgrade to Groovy 5.0.5 <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49911">#49911</a></li> <li>Upgrade to Hibernate 7.2.12.Final <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50134">#50134</a></li> <li>Upgrade to Jackson Bom 3.1.2 <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50051">#50051</a></li> <li>Upgrade to <a href="https://github.com/jaxen-xpath/jaxen/releases/tag/v2.0.1">Jaxen 2.0.1</a> <a href="https://redirect.github.com/spring-projects/spring-boot/issues/50104">#50104</a></li> <li>Upgrade to <a href="https://github.com/FirebirdSQL/jaybird/releases/tag/v6.0.5">Jaybird 6.0.5</a> <a href="https://redirect.github.com/spring-projects/spring-boot/issues/49914">#49914</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/spring-projects/spring-boot/commit/8821ad2cd381bb4b9615a61479e1de7305a8ba39"><code>8821ad2</code></a> Release v4.0.6</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/9e4048a03f17adfe78057a3c4d5b4693305c0ae0"><code>9e4048a</code></a> Merge branch '3.5.x' into 4.0.x</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/20bb11c3984802990572ddbeae8b66885a8f2462"><code>20bb11c</code></a> Next development version (v3.5.15-SNAPSHOT)</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/98daa8ea30f39a5b0ca6768b5cbc2dc8698ef4e1"><code>98daa8e</code></a> Merge branch '3.5.x' into 4.0.x</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/9dc5aa2863f598a15d3dfa116f4b89249daba7e7"><code>9dc5aa2</code></a> Polish</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/874f6294b91da18367b8b5ab7b2fad3fa23cfba6"><code>874f629</code></a> Fix default security with actuator but without health</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/e41b3bf731d1134bc18ec1f68ac01e0fe1c54923"><code>e41b3bf</code></a> Enable hostname verification for SSL connections to Elasticsearch</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/ef8527bb0ef8f564f4f9c57a7be99a7aa96c6ab0"><code>ef8527b</code></a> Merge branch '3.5.x' into 4.0.x</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/f533a4549c3999aac30cb5830f07dc304933e93d"><code>f533a45</code></a> Do not follow symlinks when writing PID file</li> <li><a href="https://github.com/spring-projects/spring-boot/commit/4a7bd332b6d19fef1aa4cf28434985f2b03a2e0f"><code>4a7bd33</code></a> Merge branch '3.5.x' into 4.0.x</li> <li>Additional commits viewable in <a href="https://github.com/spring-projects/spring-boot/compare/v4.0.5...v4.0.6">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
619 lines
22 KiB
Groovy
619 lines
22 KiB
Groovy
plugins {
|
|
id "java"
|
|
id "jacoco"
|
|
id "io.spring.dependency-management" version "1.1.7"
|
|
id "org.springframework.boot" version "4.0.6"
|
|
id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
|
|
id "io.swagger.swaggerhub" version "1.3.2"
|
|
id "com.diffplug.spotless" version "8.4.0"
|
|
id "com.github.jk1.dependency-license-report" version "3.1.2"
|
|
//id "nebula.lint" version "19.0.3"
|
|
id "org.sonarqube" version "7.2.3.7755"
|
|
}
|
|
|
|
import com.github.jk1.license.render.*
|
|
import groovy.json.JsonOutput
|
|
import groovy.json.JsonSlurper
|
|
import groovy.xml.XmlSlurper
|
|
import org.gradle.api.JavaVersion
|
|
import org.gradle.api.tasks.testing.Test
|
|
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
|
|
|
ext {
|
|
springBootVersion = "4.0.6"
|
|
pdfboxVersion = "3.0.7"
|
|
imageioVersion = "3.13.1"
|
|
lombokVersion = "1.18.46"
|
|
bouncycastleVersion = "1.83"
|
|
springSecuritySamlVersion = "7.0.5"
|
|
openSamlVersion = "5.2.1"
|
|
commonmarkVersion = "0.28.0"
|
|
googleJavaFormatVersion = "1.28.0"
|
|
logback = "1.5.32"
|
|
// junit-platform-launcher version managed by Spring Boot BOM
|
|
modernJavaVersion = 21
|
|
}
|
|
|
|
java {
|
|
sourceCompatibility = JavaVersion.VERSION_21
|
|
targetCompatibility = JavaVersion.VERSION_21
|
|
toolchain {
|
|
languageVersion = JavaLanguageVersion.of(project.findProperty('javaVersion')?.toString() ?: '25')
|
|
}
|
|
}
|
|
|
|
ext.isSecurityDisabled = { ->
|
|
System.getenv('DOCKER_ENABLE_SECURITY') == 'false' ||
|
|
System.getenv('DISABLE_ADDITIONAL_FEATURES') == 'true' ||
|
|
(project.hasProperty('DISABLE_ADDITIONAL_FEATURES') &&
|
|
System.getProperty('DISABLE_ADDITIONAL_FEATURES') == 'true')
|
|
}
|
|
|
|
ext.mavenUrl = System.getenv("MAVEN_PUBLIC_URL") ?: ""
|
|
ext.username = System.getenv('MAVEN_USER') ?: ""
|
|
ext.password = System.getenv('MAVEN_PASSWORD') ?: ""
|
|
|
|
if (rootProject.ext.mavenUrl.isEmpty()) {
|
|
println "No custom MAVEN_PUBLIC_URL set, defaulting to Maven Central"
|
|
} else {
|
|
println "MAVEN_PUBLIC_URL set"
|
|
}
|
|
|
|
jar {
|
|
enabled = false
|
|
manifest {
|
|
attributes "Implementation-Title": "Stirling-PDF",
|
|
"Implementation-Version": project.version
|
|
}
|
|
}
|
|
|
|
bootJar {
|
|
enabled = false
|
|
}
|
|
|
|
// Configure main class for the root project
|
|
springBoot {
|
|
mainClass = 'stirling.software.SPDF.SPDFApplication'
|
|
}
|
|
|
|
allprojects {
|
|
group = 'stirling.software'
|
|
version = '2.10.1'
|
|
|
|
configurations.configureEach {
|
|
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
|
|
}
|
|
}
|
|
|
|
def appVersionStr = project.version.toString()
|
|
def tauriConfigPath = layout.projectDirectory.file('frontend/src-tauri/tauri.conf.json').asFile.path
|
|
def sim1Path = layout.projectDirectory.file('frontend/src/core/testing/serverExperienceSimulations.ts').asFile.path
|
|
def sim2Path = layout.projectDirectory.file('frontend/src/proprietary/testing/serverExperienceSimulations.ts').asFile.path
|
|
def aurDesktopPkgbuildPath = layout.projectDirectory.file('.github/aur/stirling-pdf-desktop/PKGBUILD').asFile.path
|
|
def aurServerPkgbuildPath = layout.projectDirectory.file('.github/aur/stirling-pdf-server-bin/PKGBUILD').asFile.path
|
|
|
|
tasks.register('syncAppVersion') {
|
|
group = 'versioning'
|
|
description = 'Synchronizes app version across desktop, simulation, and AUR PKGBUILD configs.'
|
|
|
|
doLast {
|
|
println "Synchronizing application version to ${appVersionStr}"
|
|
|
|
def tauriConfigFile = new File(tauriConfigPath)
|
|
if (tauriConfigFile.exists()) {
|
|
def parsed = new groovy.json.JsonSlurper().parse(tauriConfigFile)
|
|
parsed.version = appVersionStr
|
|
def formatted = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(parsed)) + System.lineSeparator()
|
|
if (tauriConfigFile.getText('UTF-8') != formatted) {
|
|
tauriConfigFile.write(formatted, 'UTF-8')
|
|
}
|
|
}
|
|
|
|
[new File(sim1Path), new File(sim2Path)].each { f ->
|
|
if (f.exists()) {
|
|
def content = f.getText('UTF-8')
|
|
def matcher = (content =~ /(appVersion:\s*(['"]))(.*?)(\2)/)
|
|
if (!matcher.find()) {
|
|
throw new GradleException("Could not locate appVersion in ${f} for synchronization")
|
|
}
|
|
def updatedContent = matcher.replaceFirst("${matcher.group(1)}${appVersionStr}${matcher.group(4)}")
|
|
if (content != updatedContent) {
|
|
f.write(updatedContent, 'UTF-8')
|
|
}
|
|
}
|
|
}
|
|
|
|
[new File(aurDesktopPkgbuildPath), new File(aurServerPkgbuildPath)].each { f ->
|
|
if (f.exists()) {
|
|
def content = f.getText('UTF-8')
|
|
def matcher = (content =~ /(?m)^(pkgver=)(.*)$/)
|
|
if (!matcher.find()) {
|
|
throw new GradleException("Could not locate pkgver in ${f} for synchronization")
|
|
}
|
|
def updatedContent = matcher.replaceFirst("\$1${appVersionStr}")
|
|
if (content != updatedContent) {
|
|
f.write(updatedContent, 'UTF-8')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.register('writeVersion', WriteProperties) {
|
|
destinationFile = layout.projectDirectory.file('app/common/src/main/resources/version.properties')
|
|
println "Writing version.properties to ${destinationFile.get().asFile.path}"
|
|
comment = "${new Date()}"
|
|
property 'version', project.provider { project.version.toString() }
|
|
}
|
|
|
|
subprojects {
|
|
apply plugin: 'java'
|
|
apply plugin: 'java-library'
|
|
apply plugin: 'com.diffplug.spotless'
|
|
apply plugin: 'org.springframework.boot'
|
|
apply plugin: 'io.spring.dependency-management'
|
|
apply plugin: 'jacoco'
|
|
|
|
java {
|
|
sourceCompatibility = JavaVersion.VERSION_21
|
|
targetCompatibility = JavaVersion.VERSION_21
|
|
toolchain {
|
|
languageVersion = JavaLanguageVersion.of(25)
|
|
}
|
|
}
|
|
|
|
if (project.name != "stirling-pdf") {
|
|
bootJar {
|
|
enabled = false
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
if (!rootProject.ext.mavenUrl.isEmpty()) {
|
|
maven {
|
|
url = rootProject.ext.mavenUrl + '/releases'
|
|
credentials(PasswordCredentials) {
|
|
username = rootProject.ext.username
|
|
password = rootProject.ext.password
|
|
}
|
|
authentication {
|
|
basic(BasicAuthentication)
|
|
}
|
|
allowInsecureProtocol = true
|
|
}
|
|
}
|
|
maven { url = "https://build.shibboleth.net/maven/releases" }
|
|
maven { url = "https://repository.jboss.org/" }
|
|
mavenCentral()
|
|
}
|
|
|
|
configurations.configureEach {
|
|
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
|
|
// Exclude vulnerable BouncyCastle version used in tableau
|
|
exclude group: 'org.bouncycastle', module: 'bcpkix-jdk15on'
|
|
exclude group: 'org.bouncycastle', module: 'bcutil-jdk15on'
|
|
exclude group: 'org.bouncycastle', module: 'bcmail-jdk15on'
|
|
|
|
|
|
// Security CVE fixes - hardcoded resolution strategy to ensure safe versions
|
|
// Primary fixes via explicit dependencies in app/core/build.gradle:
|
|
// - CVE-2022-25647: gson 2.8.9+ (explicit dependency overrides tabula 2.8.7)
|
|
// - CVE-2025-66453: rhino 1.7.15 (explicit dependency overrides verapdf 1.7.13)
|
|
// Fallback strategy force declarations for additional safety:
|
|
resolutionStrategy.force 'com.google.code.gson:gson:2.13.2'
|
|
resolutionStrategy.force 'org.mozilla:rhino:1.9.1'
|
|
// CVE-2025-48924: commons-lang3 3.20.0 DoS prevention
|
|
resolutionStrategy.force 'org.apache.commons:commons-lang3:3.20.0'
|
|
// CVE-2024-47554: commons-io 2.21.0 DoS prevention
|
|
resolutionStrategy.force 'commons-io:commons-io:2.21.0'
|
|
// Bouncycastle 1.83 (from bouncycastleVersion variable)
|
|
resolutionStrategy.force 'org.bouncycastle:bcprov-jdk18on:1.83'
|
|
resolutionStrategy.force 'org.bouncycastle:bcpkix-jdk18on:1.83'
|
|
}
|
|
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
|
|
}
|
|
dependencies {
|
|
// Override BOM-managed commons-lang3 for CVE-2025-48924 fix
|
|
dependency 'org.apache.commons:commons-lang3:3.20.0'
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
|
implementation 'io.github.pixee:java-security-toolkit:1.2.3'
|
|
|
|
//tmp for security bumps
|
|
implementation "ch.qos.logback:logback-core:$logback"
|
|
implementation "ch.qos.logback:logback-classic:$logback"
|
|
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
|
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
|
|
|
// Jackson 3 (Spring Boot 4 uses tools.jackson)
|
|
implementation 'org.springframework.boot:spring-boot-starter-jackson'
|
|
|
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
|
testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
|
|
testRuntimeOnly 'org.mockito:mockito-inline:5.2.0'
|
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
|
|
|
|
testImplementation platform("com.squareup.okhttp3:okhttp-bom:5.3.2")
|
|
testImplementation "com.squareup.okhttp3:mockwebserver"
|
|
}
|
|
|
|
tasks.withType(JavaCompile).configureEach {
|
|
options.encoding = "UTF-8"
|
|
options.release = rootProject.ext.modernJavaVersion
|
|
if (!project.hasProperty("noSpotless")) {
|
|
dependsOn "spotlessApply"
|
|
}
|
|
}
|
|
|
|
tasks.named("compileJava", JavaCompile).configure {
|
|
// options.compilerArgs.add("-Xlint:deprecation")
|
|
// options.compilerArgs.add("-Xlint:unchecked")
|
|
}
|
|
|
|
def jacocoReport = tasks.named("jacocoTestReport")
|
|
|
|
tasks.withType(Test).configureEach {
|
|
useJUnitPlatform()
|
|
finalizedBy(jacocoReport)
|
|
}
|
|
|
|
jacocoReport.configure {
|
|
dependsOn(tasks.named("test"))
|
|
reports {
|
|
xml.required.set(true)
|
|
csv.required.set(false)
|
|
html.required.set(true)
|
|
}
|
|
doLast {
|
|
def xmlReport = reports.xml.outputLocation.get().asFile
|
|
if (!xmlReport.exists()) {
|
|
logger.lifecycle("Jacoco coverage report not found at ${xmlReport}")
|
|
return
|
|
}
|
|
|
|
def xmlContent = xmlReport.getText("UTF-8")
|
|
xmlContent = xmlContent.replaceFirst('(?s)<!DOCTYPE.*?>', '')
|
|
def report = new XmlSlurper(false, false).parseText(xmlContent)
|
|
def counters = report.counter.collectEntries { counter ->
|
|
def type = counter.@type.text()
|
|
def covered = counter.@covered.text() as BigDecimal
|
|
def missed = counter.@missed.text() as BigDecimal
|
|
[(type): [covered: covered, missed: missed]]
|
|
}
|
|
|
|
def thresholds = [
|
|
LINE : 0.13,
|
|
INSTRUCTION: 0.14,
|
|
BRANCH : 0.09
|
|
]
|
|
|
|
def types = ["LINE", "INSTRUCTION", "BRANCH"]
|
|
def headers = ["Metric", "Coverage", "Covered/Total", "Status", "Target"]
|
|
|
|
def rows = types.collect { String type ->
|
|
def data = counters[type]
|
|
if (!data) {
|
|
return [type, "—", "—", "No data", ""]
|
|
}
|
|
|
|
def total = data.covered + data.missed
|
|
if (total == 0) {
|
|
return [type, "—", "0/${total.toBigInteger()}", "No executions", ""]
|
|
}
|
|
|
|
def ratio = data.covered / total * 100
|
|
def coverageText = String.format(Locale.ROOT, "%.2f%%", ratio)
|
|
def coveredText = String.format(Locale.ROOT, "%d/%d",
|
|
data.covered.toBigInteger(),
|
|
total.toBigInteger())
|
|
|
|
def threshold = thresholds[type]
|
|
def thresholdPercent = threshold != null ? threshold * 100 : null
|
|
def targetText = thresholdPercent != null ?
|
|
String.format(Locale.ROOT, ">= %.2f%%", thresholdPercent) : ""
|
|
def passed = thresholdPercent != null ? ratio >= thresholdPercent : null
|
|
def statusText = passed == null ? "" : (passed ? "PASS" : "FAIL")
|
|
|
|
return [type, coverageText, coveredText, statusText, targetText]
|
|
}
|
|
|
|
def columnIndexes = (0..<headers.size())
|
|
def columnWidths = columnIndexes.collect { idx ->
|
|
Math.max(headers[idx].length(), rows.collect { row ->
|
|
row[idx] != null ? row[idx].toString().length() : 0
|
|
}.max() ?: 0)
|
|
}
|
|
|
|
def formatRow = { List<String> values ->
|
|
columnIndexes.collect { idx ->
|
|
def value = values[idx] ?: ""
|
|
value.padRight(columnWidths[idx])
|
|
}.join(" | ")
|
|
}
|
|
|
|
def separator = columnIndexes.collect { idx ->
|
|
''.padRight(columnWidths[idx], '-')
|
|
}.join("-+-")
|
|
|
|
logger.lifecycle("")
|
|
logger.lifecycle("==== JaCoCo Coverage Summary ====")
|
|
logger.lifecycle(formatRow(headers))
|
|
logger.lifecycle(separator)
|
|
rows.each { row ->
|
|
logger.lifecycle(formatRow(row))
|
|
}
|
|
logger.lifecycle(separator)
|
|
|
|
def htmlReport = reports.html.outputLocation.get().asFile
|
|
logger.lifecycle("Detailed HTML report available at: ${htmlReport}")
|
|
if (rows.any { it[3] == "FAIL" }) {
|
|
logger.lifecycle("Some coverage targets were missed. Please review the detailed report above.")
|
|
} else if (rows.any { it[3] == "PASS" }) {
|
|
logger.lifecycle("Great job! All tracked coverage metrics meet their targets.")
|
|
}
|
|
logger.lifecycle("=================================\n")
|
|
}
|
|
}
|
|
|
|
tasks.named("build") {
|
|
dependsOn jacocoReport
|
|
}
|
|
|
|
jacocoTestCoverageVerification {
|
|
dependsOn jacocoReport
|
|
violationRules {
|
|
rule {
|
|
enabled = true
|
|
element = 'BUNDLE'
|
|
// Bytecode-Anweisungen abgedeckt
|
|
limit {
|
|
counter = 'INSTRUCTION'
|
|
value = 'COVEREDRATIO'
|
|
minimum = 0.14
|
|
}
|
|
// wie viele Quellcode-Zeilen abgedeckt
|
|
limit {
|
|
counter = 'LINE'
|
|
value = 'COVEREDRATIO'
|
|
minimum = 0.13
|
|
}
|
|
// Verzweigungen (if/else, switch) abgedeckt; misst Logik-Abdeckung
|
|
limit {
|
|
counter = 'BRANCH'
|
|
value = 'COVEREDRATIO'
|
|
minimum = 0.09
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.named("processResources") {
|
|
dependsOn(rootProject.tasks.writeVersion)
|
|
}
|
|
|
|
if (name == 'stirling-pdf') {
|
|
apply plugin: 'org.springdoc.openapi-gradle-plugin'
|
|
|
|
openApi {
|
|
apiDocsUrl = "http://localhost:8080/v1/api-docs"
|
|
outputDir = file("$projectDir")
|
|
outputFileName = "SwaggerDoc.json"
|
|
waitTimeInSeconds = 60 // Increase the wait time to 60 seconds
|
|
}
|
|
|
|
tasks.named("forkedSpringBootRun") {
|
|
dependsOn(":common:jar")
|
|
dependsOn(":proprietary:jar")
|
|
}
|
|
|
|
tasks.register("copySwaggerDoc", Copy) {
|
|
doNotTrackState("Writes SwaggerDoc.json to project root")
|
|
from(layout.projectDirectory.file("SwaggerDoc.json"))
|
|
into(rootProject.projectDir)
|
|
dependsOn("generateOpenApiDocs")
|
|
}
|
|
|
|
tasks.register("cleanSwaggerInBuild", Delete) {
|
|
doNotTrackState("Cleans up SwaggerDoc.json in build directory")
|
|
delete(layout.projectDirectory.file("SwaggerDoc.json"))
|
|
dependsOn("copySwaggerDoc")
|
|
}
|
|
|
|
tasks.named("copySwaggerDoc") {
|
|
finalizedBy("cleanSwaggerInBuild")
|
|
}
|
|
|
|
tasks.named("generateOpenApiDocs") {
|
|
finalizedBy("copySwaggerDoc")
|
|
doNotTrackState("OpenAPI plugin writes outside build directory")
|
|
}
|
|
|
|
tasks.named("bootRun") {
|
|
jvmArgs = [
|
|
"-XX:+UseG1GC",
|
|
"-XX:MaxGCPauseMillis=200",
|
|
"-XX:G1HeapRegionSize=4m",
|
|
"-XX:+ExplicitGCInvokesConcurrent",
|
|
"-XX:+UseStringDeduplication",
|
|
"-XX:+UseCompactObjectHeaders"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.withType(JavaCompile).configureEach {
|
|
options.encoding = "UTF-8"
|
|
if (!project.hasProperty("noSpotless")) {
|
|
dependsOn "spotlessApply"
|
|
}
|
|
}
|
|
|
|
gradle.taskGraph.whenReady { graph ->
|
|
if (project.hasProperty("noSpotless")) {
|
|
allprojects { scopedProject ->
|
|
scopedProject.tasks.matching { it.name.startsWith("spotless") }.configureEach {
|
|
enabled = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def allProjects = ((subprojects as Set<Project>) + project) as Set<Project>
|
|
|
|
licenseReport {
|
|
projects = allProjects
|
|
renderers = [new JsonReportRenderer()]
|
|
allowedLicensesFile = project.layout.projectDirectory.file("app/allowed-licenses.json").asFile
|
|
outputDir = project.layout.buildDirectory.dir("reports/dependency-license").get().asFile.path
|
|
configurations = [ "productionRuntimeClasspath", "runtimeClasspath" ]
|
|
}
|
|
|
|
// Configure the forked spring boot run task to properly delegate to the stirling-pdf module
|
|
tasks.named('forkedSpringBootRun') {
|
|
dependsOn ':stirling-pdf:bootRun'
|
|
doFirst {
|
|
println "Delegating forkedSpringBootRun to :stirling-pdf:bootRun"
|
|
}
|
|
}
|
|
|
|
spotless {
|
|
yaml {
|
|
target '*.yml', '*.yaml'
|
|
trimTrailingWhitespace()
|
|
leadingTabsToSpaces()
|
|
endWithNewline()
|
|
}
|
|
format 'gradle', {
|
|
target 'build.gradle', 'settings.gradle', 'gradle/*.gradle', 'gradle/**/*.gradle'
|
|
trimTrailingWhitespace()
|
|
leadingTabsToSpaces()
|
|
endWithNewline()
|
|
}
|
|
}
|
|
|
|
sonar {
|
|
properties {
|
|
property "sonar.projectKey", "Stirling-Tools_Stirling-PDF"
|
|
property "sonar.organization", "stirling-tools"
|
|
|
|
property "sonar.exclusions", "**/build-wrapper-dump.json, **/src/main/java/org/apache/**, **/src/main/resources/static/pdfjs/**, **/src/main/resources/static/pdfjs-legacy/**, **/src/main/resources/static/js/thirdParty/**"
|
|
property "sonar.coverage.exclusions", "**/src/main/java/org/apache/**, **/src/main/resources/static/pdfjs/**, **/src/main/resources/static/pdfjs-legacy/**, **/src/main/resources/static/js/thirdParty/**"
|
|
property "sonar.cpd.exclusions", "**/src/main/java/org/apache/**, **/src/main/resources/static/pdfjs/**, **/src/main/resources/static/pdfjs-legacy/**, **/src/main/resources/static/js/thirdParty/**"
|
|
}
|
|
}
|
|
|
|
swaggerhubUpload {
|
|
// dependsOn = generateOpenApiDocs // Depends on your task generating Swagger docs
|
|
api = "Stirling-PDF" // The name of your API on SwaggerHub
|
|
owner = "${System.getenv().getOrDefault('SWAGGERHUB_USER', 'Frooodle')}" // Your SwaggerHub username (or organization name)
|
|
version = project.version // The version of your API
|
|
inputFile = file("SwaggerDoc.json") // The path to your Swagger docs
|
|
token = "${System.getenv("SWAGGERHUB_API_KEY")}" // Your SwaggerHub API key, passed as an environment variable
|
|
oas = "3.0.0" // The version of the OpenAPI Specification you"re using
|
|
}
|
|
|
|
repositories {
|
|
if (!rootProject.ext.mavenUrl.isEmpty()) {
|
|
maven {
|
|
url = rootProject.ext.mavenUrl + '/releases'
|
|
credentials(PasswordCredentials) {
|
|
username = rootProject.ext.username
|
|
password = rootProject.ext.password
|
|
}
|
|
authentication {
|
|
basic(BasicAuthentication)
|
|
}
|
|
allowInsecureProtocol = true
|
|
}
|
|
}
|
|
maven { url = "https://build.shibboleth.net/maven/releases" }
|
|
mavenCentral()
|
|
}
|
|
|
|
dependencies {
|
|
implementation project(':stirling-pdf')
|
|
implementation project(':common')
|
|
if (rootProject.ext.isSecurityDisabled()) {
|
|
implementation project(':proprietary')
|
|
}
|
|
|
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
|
|
|
|
testImplementation platform("com.squareup.okhttp3:okhttp-bom:5.3.2")
|
|
testImplementation "com.squareup.okhttp3:mockwebserver"
|
|
}
|
|
|
|
tasks.named("test") {
|
|
useJUnitPlatform()
|
|
}
|
|
|
|
// Make sure all relevant processes depend on writeVersion
|
|
processResources.dependsOn(writeVersion)
|
|
|
|
tasks.register('printVersion') {
|
|
doLast {
|
|
println project.version
|
|
}
|
|
}
|
|
|
|
tasks.named('bootRun') {
|
|
group = 'application'
|
|
description = 'Delegates to :stirling-pdf:bootRun'
|
|
dependsOn ':stirling-pdf:bootRun'
|
|
|
|
doFirst {
|
|
println "Delegating to :stirling-pdf:bootRun"
|
|
}
|
|
}
|
|
|
|
tasks.named('build') {
|
|
group = 'build'
|
|
description = 'Delegates to :stirling-pdf:bootJar'
|
|
dependsOn ':stirling-pdf:bootJar', 'buildRestartHelper', 'syncAppVersion'
|
|
|
|
doFirst {
|
|
println "Delegating to :stirling-pdf:bootJar"
|
|
}
|
|
}
|
|
|
|
// Task to compile RestartHelper.java
|
|
tasks.register('compileRestartHelper', JavaCompile) {
|
|
group = 'build'
|
|
description = 'Compiles the RestartHelper utility'
|
|
|
|
source = fileTree(dir: 'scripts', include: 'RestartHelper.java')
|
|
classpath = files()
|
|
destinationDirectory = layout.buildDirectory.dir("restart-helper-classes")
|
|
def restartMajorVersion = project.ext.modernJavaVersion
|
|
def restartCompatibility = JavaVersion.toVersion(restartMajorVersion.toString())
|
|
sourceCompatibility = restartCompatibility
|
|
targetCompatibility = restartCompatibility
|
|
options.release.set(restartMajorVersion)
|
|
}
|
|
|
|
// Task to create restart-helper.jar
|
|
tasks.register('buildRestartHelper', Jar) {
|
|
group = 'build'
|
|
description = 'Builds the restart-helper.jar'
|
|
dependsOn 'compileRestartHelper'
|
|
|
|
from layout.buildDirectory.dir("restart-helper-classes")
|
|
archiveFileName = 'restart-helper.jar'
|
|
destinationDirectory = layout.buildDirectory.dir("libs")
|
|
|
|
manifest {
|
|
attributes 'Main-Class': 'RestartHelper'
|
|
}
|
|
|
|
doLast {
|
|
println "restart-helper.jar created at: ${destinationDirectory.get()}/restart-helper.jar"
|
|
}
|
|
}
|