Files
claude-code 250019a033
werkator build succeeded after 02:58
werkator/publish build succeeded after 00:18
werkcrappit's nightly mutation build green, with the structure pages (0.26.1) (#56)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-11 11:32:58 +02:00

151 lines
6.3 KiB
Kotlin

plugins {
`java-library`
`maven-publish`
id("info.solidsoft.pitest") version "1.19.0"
// the released Gradle plugin; the PIT plugin it adds is this project, see the pitest task below
id("de.javagil.werkcrappit") version "0.26.0"
}
val pitVersion = "1.30.0"
dependencies {
// PIT loads this JAR into its own process, so its API is there at run time.
compileOnly("org.pitest:pitest-entry:$pitVersion")
implementation("org.jacoco:org.jacoco.core:0.8.15")
// the same ASM JaCoCo and PIT 1.30.0 bring, used to list the methods a class file declares
implementation("org.ow2.asm:asm:9.10.1")
testImplementation("org.pitest:pitest-entry:$pitVersion")
testImplementation("io.cucumber:gherkin:42.0.1")
testImplementation("com.networknt:json-schema-validator:3.0.8")
}
tasks.jar {
manifest {
attributes("Implementation-Title" to project.name, "Implementation-Version" to project.version)
}
}
publishing {
publications {
create<MavenPublication>("pitPlugin") {
from(components["java"])
}
}
repositories {
// What the functional test consumes: the packaged JAR with its published
// metadata, never the classes of this build.
maven {
name = "functionalTest"
url = uri(rootProject.layout.buildDirectory.dir("functional-test-repo"))
}
}
}
val functionalTest = sourceSets.create("functionalTest")
configurations[functionalTest.implementationConfigurationName].extendsFrom(configurations.testImplementation.get())
configurations[functionalTest.runtimeOnlyConfigurationName].extendsFrom(configurations.testRuntimeOnly.get())
dependencies {
"functionalTestImplementation"(gradleTestKit())
"functionalTestImplementation"(sourceSets.test.get().output)
"functionalTestImplementation"("com.fasterxml.jackson.core:jackson-databind:2.22.3")
}
val functionalTestTask =
tasks.register<Test>("functionalTest") {
description = "Runs PIT with the packaged plugin in a real Gradle build."
group = "verification"
testClassesDirs = functionalTest.output.classesDirs
classpath = functionalTest.runtimeClasspath
dependsOn("publishPitPluginPublicationToFunctionalTestRepository")
systemProperty("werkcrappit.repo", rootProject.layout.buildDirectory.dir("functional-test-repo").get().asFile.absolutePath)
systemProperty("werkcrappit.version", project.version.toString())
systemProperty("werkcrappit.pitestVersion", pitVersion)
}
// The pages of the CodeCharta export draw with a script; these tests run it in a headless Chromium
// (RFC 0003). The browser is downloaded once into .playwright/, outside build/, so a clean keeps it.
val browserTest = sourceSets.create("browserTest")
configurations[browserTest.implementationConfigurationName].extendsFrom(configurations.testImplementation.get())
configurations[browserTest.runtimeOnlyConfigurationName].extendsFrom(configurations.testRuntimeOnly.get())
val playwrightVersion = "1.63.0"
val playwrightBrowsers = rootProject.layout.projectDirectory.dir(".playwright").asFile.absolutePath
dependencies {
"browserTestImplementation"(sourceSets.main.get().output)
"browserTestImplementation"(sourceSets.test.get().output)
"browserTestImplementation"("com.microsoft.playwright:playwright:$playwrightVersion")
}
val installBrowser =
tasks.register<JavaExec>("installBrowser") {
description = "Downloads the headless Chromium of Playwright, unless it is there already."
group = "verification"
classpath = browserTest.runtimeClasspath
mainClass = "com.microsoft.playwright.CLI"
args("install", "--only-shell", "chromium")
environment("PLAYWRIGHT_BROWSERS_PATH", playwrightBrowsers)
}
val browserTestTask =
tasks.register<Test>("browserTest") {
description = "Runs the scripts of the report pages in a headless Chromium."
group = "verification"
testClassesDirs = browserTest.output.classesDirs
classpath = browserTest.runtimeClasspath
dependsOn(installBrowser)
environment("PLAYWRIGHT_BROWSERS_PATH", playwrightBrowsers)
environment("PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD", "1")
}
tasks.check {
dependsOn(functionalTestTask)
dependsOn(browserTestTask)
}
// Mutation testing of this module with its own Mutation-CRAP: not part of `check`, run by the nightly
// build definition `mutation` in .werkator.yml. The unit tests only; the functional tests start
// real Gradle builds with PIT, minutes per mutant.
pitest {
pitestVersion = pitVersion
junit5PluginVersion = "1.2.3"
targetClasses = setOf("de.javagil.werkcrappit.pit.*")
targetTests = setOf("de.javagil.werkcrappit.pit.*")
// what the Test tasks set, PIT's minions need too
jvmArgs = listOf("-Dwerkcrappit.version=${project.version}")
threads = providers.gradleProperty("pitestThreads").map { it.toInt() }.orElse(2)
// incremental: unchanged classes take their results from the history, which lives outside
// build/, so that the clean command keeps it, and per worktree, so per branch
enableDefaultIncrementalAnalysis = true
historyInputLocation = rootProject.layout.projectDirectory.file(".pitest/werkcrappit-pit-history.bin")
historyOutputLocation = rootProject.layout.projectDirectory.file(".pitest/werkcrappit-pit-history.bin")
outputFormats = setOf("HTML", "XML")
timestampedReports = false
}
// The Gradle plugin adds werkcrappit-pit to PIT's classpath by its coordinates, which are this project's,
// and Gradle takes this project for them, whatever the version: werkcrappit measures itself with the
// listener of the same commit. The PIT plugin does not know that this needs the JAR built first.
tasks.named("pitest") {
dependsOn(tasks.jar)
}
dependencies {
// PIT 1.30 keeps its incremental history only through this plugin
pitest("org.pitest:pitest-history-plugin:0.0.1")
}
werkcrappit {
// a ratchet: the highest value, rounded up (2026-10-03: 9, three methods of complexity 9 with every
// mutant killed); lower it as the hotspots shrink, never raise it. Red starts at 90 % of it, 8.1.
maxMutationCrap = 9
// ratchets as well (RFC 0002), today's highest values: ExclusionRules and JacocoComplexity at LCOM4 3,
// MutationCrapListener with 21 other classes it depends on
maxLcom4 = 3
maxEfferentCoupling = 21
}