Skip to content

Commit a8bb94b

Browse files
committed
Making the build script fit for the future.
1 parent 51cf67e commit a8bb94b

File tree

13 files changed

+412
-75
lines changed

13 files changed

+412
-75
lines changed

buildSrc/build.gradle.kts

Whitespace-only changes.

buildSrc/settings.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dependencyResolutionManagement {
2+
versionCatalogs {
3+
create("libs") {
4+
from(files("../gradle/libs.versions.toml"))
5+
}
6+
}
7+
}
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
import java.util.*
2+
3+
4+
plugins {
5+
java
6+
`java-library`
7+
`maven-publish`
8+
signing // GPG siging of artifacts, required by maven central
9+
idea
10+
eclipse
11+
checkstyle
12+
pmd
13+
14+
// Code formatting
15+
id("com.diffplug.spotless") version "6.25.0"
16+
17+
// EISOP Checker Framework
18+
id("org.checkerframework") version "0.6.48"
19+
}
20+
21+
repositories {
22+
mavenCentral()
23+
}
24+
25+
val implementation by configurations
26+
dependencies {
27+
implementation(libs.slf4j)
28+
29+
compileOnly(libs.jspecify)
30+
testCompileOnly(libs.jspecify)
31+
32+
compileOnly(libs.eisopCheckerQual)
33+
compileOnly(libs.eisopUtil)
34+
testCompileOnly(libs.eisopCheckerQual)
35+
checkerFramework(libs.eisopCheckerQual)
36+
checkerFramework(libs.eisopChecker)
37+
38+
testImplementation(libs.bundles.testing)
39+
testImplementation(project(":key.util"))
40+
testRuntimeOnly(libs.junitEngine)
41+
}
42+
43+
java {
44+
sourceCompatibility = JavaVersion.VERSION_21
45+
targetCompatibility = JavaVersion.VERSION_21
46+
}
47+
48+
49+
tasks.withType<JavaCompile>().configureEach {
50+
options.encoding = "UTF-8"
51+
options.release.set(21)
52+
}
53+
54+
tasks.withType<Javadoc>().configureEach {
55+
isFailOnError = false
56+
options.addBooleanOption("Xdoclint:none", true)
57+
options.encoding = "UTF-8"
58+
options.addBooleanOption("html5", true)
59+
}
60+
61+
tasks.withType<Test>().configureEach {
62+
systemProperty("test-resources", "src/test/resources")
63+
systemProperty("testcases", "src/test/resources/testcase")
64+
systemProperty("TACLET_PROOFS", "tacletProofs")
65+
systemProperty("EXAMPLES_DIR", file("${rootProject.projectDir}/key.ui/examples"))
66+
systemProperty("RUNALLPROOFS_DIR", "$buildDir/report/runallproves")
67+
68+
systemProperty("key.disregardSettings", "true")
69+
maxHeapSize = "4g"
70+
71+
forkEvery = 0
72+
maxParallelForks = 1
73+
}
74+
75+
tasks.withType<Test>().configureEach {
76+
useJUnitPlatform {
77+
includeEngines("junit-jupiter")
78+
}
79+
}
80+
81+
tasks.named<Test>("test") {
82+
// Before we switched to JUnit 5, we used JUnit 4 with a customized discovery of test class.
83+
// This discovery called AutoSuite and searched in the compiled classes. AutoSuite was
84+
// necessary due to bugs caused in some execution order.
85+
// AutoSuites made the test order deterministic. A last known commit to find AutoSuite (for the case),
86+
// is 980294d04008f6b3798986bce218bac2753b4783.
87+
88+
useJUnitPlatform {
89+
excludeTags("owntest", "interactive", "performance")
90+
}
91+
92+
afterTest { desc, result ->
93+
logger.error("${result.resultType}: ${desc.className}#${desc.name}")
94+
}
95+
beforeTest { desc ->
96+
logger.error("> ${desc.className}#${desc.name}")
97+
}
98+
99+
testLogging {
100+
outputs.upToDateWhen { false }
101+
showStandardStreams = true
102+
}
103+
}
104+
105+
tasks.register<Test>("testFast") {
106+
group = "verification"
107+
useJUnitPlatform {
108+
excludeTags("slow", "performance", "interactive")
109+
}
110+
111+
testLogging {
112+
// set options for log level LIFECYCLE
113+
events("failed")
114+
exceptionFormat = TestExceptionFormat.SHORT
115+
116+
// set options for log level DEBUG
117+
debug {
118+
events("started", "skipped", "failed")
119+
exceptionFormat = TestExceptionFormat.FULL
120+
}
121+
122+
info {
123+
// remove standard output/error logging from --info builds
124+
// by assigning only 'failed' and 'skipped' events
125+
events("failed", "skipped")
126+
}
127+
}
128+
}
129+
130+
// The following two tasks can be used to execute main methods from the project
131+
// The main class is set via "gradle -DmainClass=... execute --args ..."
132+
// see https://stackoverflow.com/questions/21358466/gradle-to-execute-java-class-without-modifying-build-gradle
133+
tasks.register<JavaExec>("execute") {
134+
description = "Execute main method from the project. Set main class via 'gradle -DmainClass=... execute --args ...'"
135+
group = "application"
136+
mainClass.set(System.getProperty("mainClass"))
137+
classpath = sourceSets.main.get().runtimeClasspath
138+
}
139+
140+
tasks.register<JavaExec>("executeInTests") {
141+
description =
142+
"Execute main method from the project (tests loaded). Set main class via 'gradle -DmainClass=... execute --args ...'"
143+
group = "application"
144+
mainClass.set(System.getProperty("mainClass"))
145+
classpath = sourceSets.test.get().runtimeClasspath
146+
}
147+
148+
pmd {
149+
isIgnoreFailures = true
150+
toolVersion = "6.53.0"
151+
consoleOutput = false
152+
ruleSets = listOf("category/java/errorprone.xml", "category/java/bestpractices.xml")
153+
}
154+
155+
tasks.register<Pmd>("pmdMainChanged") {
156+
val changedFiles = getChangedFiles()
157+
source = files(pmdMain.source.filter { it.absolutePath in changedFiles })
158+
classpath = checkstyleMain.classpath
159+
reports {
160+
html.required.set(true)
161+
html.outputLocation.set(file("build/reports/pmd/main_diff.html"))
162+
xml.required.set(true)
163+
xml.outputLocation.set(file("build/reports/pmd/main_diff.xml"))
164+
}
165+
}
166+
167+
checkstyle {
168+
toolVersion = "10.6.0"
169+
isIgnoreFailures = true
170+
configFile = file("$rootDir/gradle/key_checks.xml")
171+
showViolations = false // disable console output
172+
}
173+
174+
tasks.register<Checkstyle>("checkstyleMainChanged") {
175+
val changedFiles = getChangedFiles()
176+
source = files(checkstyleMain.source.filter { it.absolutePath in changedFiles })
177+
classpath = checkstyleMain.classpath
178+
reports {
179+
html.required.set(true)
180+
html.outputLocation.set(file("build/reports/checkstyle/main_diff.html"))
181+
xml.required.set(true)
182+
xml.outputLocation.set(file("build/reports/checkstyle/main_diff.xml"))
183+
}
184+
}
185+
186+
tasks.withType<Pmd>().configureEach {
187+
reports {
188+
xml.required.set(true)
189+
html.required.set(true)
190+
}
191+
}
192+
193+
tasks.register<Jar>("sourcesJar") {
194+
description = "Create a jar file with the sources from this project"
195+
from(sourceSets.main.get().allJava)
196+
archiveClassifier.set("sources")
197+
}
198+
199+
tasks.register<Jar>("javadocJar") {
200+
description = "Create a jar file with the javadocs from this project"
201+
from(tasks.javadoc)
202+
archiveClassifier.set("javadoc")
203+
}
204+
205+
license {
206+
header = file("$rootDir/gradle/header")
207+
mapping {
208+
java = "SLASHSTAR_STYLE"
209+
javascript = "SLASHSTAR_STYLE"
210+
}
211+
mapping("key", "SLASHSTAR_STYLE")
212+
}
213+
214+
eclipse {
215+
classpath {
216+
file {
217+
whenMerged {
218+
entries.findAll { it.path.endsWith("src/test/antlr") }.forEach { it.excludes = listOf("**/*.java") }
219+
entries.findAll { it.path.endsWith("/resources") }.forEach { it.excludes = listOf("**/*.java") }
220+
}
221+
}
222+
}
223+
}
224+
225+
spotless {
226+
format("Key") {
227+
target("src/main/resources/**/*.key")
228+
trimTrailingWhitespace()
229+
endWithNewline()
230+
}
231+
232+
antlr4 {
233+
target("src/*/antlr4/**/*.g4")
234+
}
235+
236+
java {
237+
targetExclude("build/**")
238+
toggleOffOn()
239+
removeUnusedImports()
240+
eclipse().configFile("$rootDir/scripts/tools/checkstyle/keyCodeStyle.xml")
241+
trimTrailingWhitespace()
242+
importOrder("java|javax", "de.uka", "org.key_project", "", "\\#")
243+
if (project.name == "recoder") {
244+
licenseHeaderFile("$rootDir/gradle/header-recoder", "(package|import|//)")
245+
} else {
246+
licenseHeaderFile("$rootDir/gradle/header", "(package|import|//)")
247+
}
248+
}
249+
}
250+
251+
afterEvaluate {
252+
publishing {
253+
publications {
254+
create<MavenPublication>("mavenJava") {
255+
from(components["java"])
256+
artifact(tasks["sourcesJar"])
257+
artifact(tasks["javadocJar"])
258+
pom {
259+
name.set(project.name)
260+
description.set(project.description)
261+
url.set("https://key-project.org/")
262+
licenses {
263+
license {
264+
name.set("GNU General Public License (GPL), Version 2")
265+
url.set("https://www.gnu.org/licenses/old-licenses/gpl-2.0.html")
266+
}
267+
}
268+
developers {
269+
developer {
270+
id.set("key")
271+
name.set("KeY Developers")
272+
email.set("[email protected]")
273+
url.set("https://www.key-project.org/about/people/")
274+
}
275+
}
276+
scm {
277+
connection.set("scm:git:git://github.com/keyproject/key.git")
278+
developerConnection.set("scm:git:git://github.com/keyproject/key.git")
279+
url.set("https://github.com/keyproject/key/")
280+
}
281+
}
282+
}
283+
}
284+
repositories {
285+
maven {
286+
if (project.version.toString().endsWith("-SNAPSHOT")) {
287+
name = "mavenSnapshot"
288+
url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
289+
credentials {
290+
username = project.findProperty("ossrhUsername") as String? ?: ""
291+
password = project.findProperty("ossrhPassword") as String? ?: ""
292+
}
293+
} else {
294+
name = "mavenStaging"
295+
url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
296+
credentials {
297+
username = project.findProperty("ossrhUsername") as String? ?: ""
298+
password = project.findProperty("ossrhPassword") as String? ?: ""
299+
}
300+
}
301+
}
302+
}
303+
}
304+
305+
signing {
306+
useGpgCmd()
307+
sign(publishing.publications["mavenJava"])
308+
}
309+
}
310+
311+
//conditionally enable jacoco coverage when `-DjacocoEnabled=true` is given on CLI.
312+
val jacocoEnabled = System.properties.getProperty("jacocoEnabled") ?: "false"
313+
if (jacocoEnabled.toBoolean()) {
314+
project.logger.lifecycle("Jacoco enabled. Test performance will be slower.")
315+
apply from : rootProject . file ("scripts/jacocokey.gradle")
316+
}
317+
318+
val changedFiles by lazy {
319+
// Get the target and source branch
320+
val anchor = "git merge-base HEAD origin/main".execute().text.trim()
321+
322+
// Get list of all changed files including status
323+
val allFiles = "git diff --name-status --diff-filter=dr $anchor".execute().text.trim().split("\n")
324+
325+
// Remove the status prefix
326+
val files = TreeSet<String>()
327+
for (file in allFiles) {
328+
if (file.length > 1) {
329+
val a = file.substring(1).trim()
330+
if (a.isNotBlank()) {
331+
files.add("$rootDir/$a")
332+
}
333+
}
334+
}
335+
// Return the list of touched files
336+
files
337+
}
338+
339+
fun String.execute(): Process {
340+
return Runtime.getRuntime().exec(this)
341+
}

gradle/libs.versions.toml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
[versions]
2+
jspecify = "1.0.0"
3+
eisop = "3.42.0-eisop5"
4+
5+
[libraries]
6+
jspecify = { module = "org.jspecify:jspecify", version.ref = "jspecify" }
7+
slf4j = { module = "org.slf4j:slf4j-api", version = "2.0.16" }
8+
9+
eisopCheckerQual = { module = "io.github.eisop:checker-qual", version.ref = "eisop" }
10+
eisopUtil = { module = "io.github.eisop:checker-util", version.ref = "eisop" }
11+
eisopChecker = { module = "io.github.eisop:checker", version.ref = "eisop" }
12+
13+
assertj = { module = "org.assertj:assertj-core", version = "3.27.3" }
14+
logback = { module = "ch.qos.logback:logback-classic", version = "1.5.15" }
15+
junitApi = { module = "org.junit.jupiter:junit-jupiter-api", version = "5.11.4" }
16+
junitParams = { module = "org.junit.jupiter:junit-jupiter-params", version = "5.11.4" }
17+
18+
yaml = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", version = "2.18.2" }
19+
yamljsr = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version = "2.18.2" }
20+
21+
junitEngine = { module = "org.junit.jupiter:junit-jupiter-engine", version = "5.11.4" }
22+
23+
javacc = { module = "net.java.dev.javacc:javacc", version = "4.0" }
24+
antlr = { module = "org.antlr:antlr4", version = "4.13.2" }
25+
antlrRuntime = { module = "org.antlr:antlr4-runtime", version = "4.13.2" }
26+
miglayout = { module = "com.miglayout:miglayout-swing", version = "11.4.2" }
27+
28+
dockingFramesCommon = { module = "org.key-project:docking-frames-common", version = "1.1.3p1" }
29+
dockingFramesCore = { module = "org.key-project:docking-frames-core", version = "1.1.3p1" }
30+
31+
stringtemplate = { module = "org.antlr:ST4", version = "4.3.4" }
32+
33+
34+
[bundles]
35+
junit = ["junitApi", "junitParams", "junitEngine"]
36+
testing = ["junitApi", "junitParams", "junitEngine", "assertj", "logback", "yaml", "yamljsr"]
37+
38+
[plugins]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)