Skip to content

Commit f2436b0

Browse files
committed
Enable configuration cache
Enable the configuration cache feature in Gradle, and adjust various pieces of build logic that aren't configuration cache compatible.
1 parent 8b6b90d commit f2436b0

15 files changed

Lines changed: 151 additions & 107 deletions

build-logic/src/main/kotlin/BuildInfo.kt

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -372,35 +372,33 @@ open class BuildInfo(private val project: Project) {
372372
org.gradle.internal.os.OperatingSystem.current()
373373
}
374374

375-
// could be `commitId: Provider<String> = project.provider { ... }`
376-
val commitId: String by lazy {
377-
// allow -DcommitId=abc123 for build environments that don't have git.
378-
System.getProperty("commitId").let { if (it != null) return@lazy it }
375+
private val computedCommitId: Provider<String> =
379376
// only run command once per build invocation
380377
if (project.path == project.rootProject.path) {
381-
val process =
382-
ProcessBuilder()
383-
.command("git", "rev-parse", "--short", "HEAD")
384-
.directory(project.rootDir)
385-
.start()
386-
process.waitFor().also { exitCode ->
387-
if (exitCode == -1) throw RuntimeException(process.errorStream.reader().readText())
388-
}
389-
process.inputStream.reader().readText().trim()
378+
project.providers
379+
.exec { commandLine("git", "rev-parse", "--short", "HEAD") }
380+
.standardOutput
381+
.asText
382+
.map { it.trim() }
390383
} else {
391384
project.rootProject.extensions.getByType(BuildInfo::class.java).commitId
392385
}
393-
}
394386

395-
val commitish: String by lazy { if (isReleaseBuild) project.version.toString() else commitId }
387+
val commitId: Provider<String> =
388+
// allow -DcommitId=abc123 for build environments that don't have git.
389+
System.getProperty("commitId")?.let { project.providers.provider { it } } ?: computedCommitId
396390

397-
val pklVersion: String by lazy {
391+
val commitish: Provider<String> =
392+
if (isReleaseBuild) project.providers.provider { project.version.toString() } else commitId
393+
394+
val pklVersion: Provider<String> =
398395
if (isReleaseBuild) {
399-
project.version.toString()
396+
project.providers.provider { project.version.toString() }
400397
} else {
401-
project.version.toString().replace("-SNAPSHOT", "-dev+$commitId")
398+
project.providers
399+
.provider { project.version.toString() }
400+
.zip(commitId) { version, id -> version.replace("-SNAPSHOT", "-dev+$id") }
402401
}
403-
}
404402

405403
val pklVersionNonUnique: String by lazy {
406404
if (isReleaseBuild) {

build-logic/src/main/kotlin/PklFormatterSpotless.kt

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
import com.diffplug.spotless.FormatterFunc
1717
import com.diffplug.spotless.FormatterStep
18+
import java.io.File
1819
import java.io.Serial
1920
import java.io.Serializable
2021
import java.net.URLClassLoader
@@ -26,33 +27,36 @@ class PklFormatterStep(@Transient private val configuration: Configuration) : Se
2627
}
2728

2829
fun create(): FormatterStep {
30+
val files = configuration.files.toList()
2931
return FormatterStep.createLazy(
3032
"pkl",
31-
{ PklFormatterStep(configuration) },
32-
{ PklFormatterFunc(configuration) },
33+
{ PklFormatterState(files) },
34+
{ PklFormatterFunc(it.files) },
3335
)
3436
}
3537
}
3638

37-
class PklFormatterFunc(@Transient private val configuration: Configuration) :
38-
FormatterFunc, Serializable {
39+
data class PklFormatterState(val files: List<File>) : Serializable
40+
41+
class PklFormatterFunc(private val files: List<File>) : FormatterFunc, Serializable {
3942
companion object {
4043
@Serial private const val serialVersionUID: Long = 1L
4144
}
4245

43-
private val classLoader by lazy {
44-
val urls = configuration.files.map { it.toURI().toURL() }
46+
private fun getClassLoader(): ClassLoader {
47+
val urls = files.map { it.toURI().toURL() }
4548
// Use the platform classloader as parent to isolate from Gradle's classloader
46-
URLClassLoader(urls.toTypedArray(), ClassLoader.getPlatformClassLoader())
49+
return URLClassLoader(urls.toTypedArray(), ClassLoader.getPlatformClassLoader())
4750
}
4851

49-
private val formatterClass by lazy { classLoader.loadClass("org.pkl.formatter.Formatter") }
50-
51-
private val formatMethod by lazy { formatterClass.getMethod("format", String::class.java) }
52-
53-
private val formatterInstance by lazy { formatterClass.getConstructor().newInstance() }
52+
private fun loadFormatterClass(): Class<*> {
53+
return getClassLoader().loadClass("org.pkl.formatter.Formatter")
54+
}
5455

5556
override fun apply(input: String): String {
57+
val formatterClass = loadFormatterClass()
58+
val formatMethod = formatterClass.getMethod("format", String::class.java)
59+
val formatterInstance = formatterClass.getConstructor().newInstance()
5660
return formatMethod(formatterInstance, input) as String
5761
}
5862
}

build-logic/src/main/kotlin/pklFatJar.gradle.kts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
*/
1616
import org.gradle.api.GradleException
1717
import org.gradle.api.artifacts.Configuration
18+
import org.gradle.api.file.ArchiveOperations
1819
import org.gradle.api.publish.maven.MavenPublication
1920
import org.gradle.api.tasks.bundling.Jar
2021
import org.gradle.api.tasks.testing.Test
2122
import org.gradle.kotlin.dsl.*
23+
import org.gradle.kotlin.dsl.support.serviceOf
2224

2325
plugins {
2426
`java-library`
@@ -150,17 +152,19 @@ tasks.check { dependsOn(testFatJar) }
150152

151153
val validateFatJar by tasks.registering {
152154
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
153-
inputs.files(tasks.shadowJar)
155+
val shadowJarFile = tasks.shadowJar.flatMap { it.archiveFile }
156+
val archiveOps = serviceOf<ArchiveOperations>()
157+
inputs.file(shadowJarFile)
154158
inputs.property("nonRelocations", nonRelocations)
155159
outputs.file(outputFile)
160+
val nonRelocations = nonRelocations
156161

157162
doLast {
158163
val unshadowedFiles = mutableListOf<String>()
159-
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
160-
val fileDetails = this
161-
val path = fileDetails.relativePath.pathString
164+
archiveOps.zipTree(shadowJarFile.get().asFile).visit {
165+
val path = relativePath.pathString
162166
if (
163-
!(fileDetails.isDirectory ||
167+
!(isDirectory ||
164168
path.startsWith("org/pkl/") ||
165169
path.startsWith("META-INF/") ||
166170
nonRelocations.any { path.startsWith(it) })

build-logic/src/main/kotlin/pklHtmlValidator.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ val validateHtml by
6868
// write a basic result file s.t. gradle can consider task up-to-date
6969
// writing a result file in case validation fails is not easily possible with JavaExec, but also
7070
// not strictly necessary
71-
doFirst { project.delete(resultFile) }
71+
doFirst { resultFile.get().asFile.delete() }
7272
doLast { resultFile.get().asFile.writeText("Success.") }
7373
}
7474

build-logic/src/main/kotlin/pklJavaExecutable.gradle.kts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
4747
val outputFile = layout.buildDirectory.file("testStartJavaExecutable/$name")
4848
outputs.file(outputFile)
4949

50+
val executableFile = javaExecutable.flatMap { it.outJar }
51+
val pklVersion = buildInfo.pklVersionNonUnique
5052
val execOutput = providers.exec {
51-
val executablePath = javaExecutable.get().outputs.files.singleFile
53+
val executablePath = executableFile.get().asFile
5254
if (launcher?.isPresent == true) {
5355
commandLine(
5456
launcher.get().executablePath.asFile.absolutePath,
@@ -63,9 +65,9 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
6365

6466
doLast {
6567
val outputText = execOutput.standardOutput.asText.get()
66-
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
68+
if (!outputText.contains(pklVersion)) {
6769
throw GradleException(
68-
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
70+
"Expected version output to contain current version ($pklVersion), but got '$outputText'"
6971
)
7072
}
7173
outputFile.get().asFile.toPath().apply {

build.gradle.kts

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,47 @@ idea {
5353
}
5454
}
5555

56-
val clean by tasks.existing { delete(layout.buildDirectory) }
56+
val clean by tasks.existing {
57+
val buildDirectory = layout.buildDirectory
58+
doLast { delete(buildDirectory) }
59+
}
5760

58-
val printVersion by tasks.registering { doFirst { println(buildInfo.pklVersion) } }
61+
val printVersion by tasks.registering {
62+
val pklVersion = buildInfo.pklVersion
63+
doFirst { println(pklVersion.get()) }
64+
}
5965

60-
val message =
61-
"""
62-
====
63-
Gradle version : ${gradle.gradleVersion}
64-
Java version : ${System.getProperty("java.version")}
65-
isParallel : ${gradle.startParameter.isParallelProjectExecutionEnabled}
66-
maxWorkerCount : ${gradle.startParameter.maxWorkerCount}
67-
Architecture : ${buildInfo.arch}
66+
val printInfo by tasks.registering {
67+
val arch = buildInfo.arch
68+
val pklVersion = buildInfo.pklVersion
69+
val pklVersionNonUnique = buildInfo.pklVersionNonUnique
70+
val commitId = buildInfo.commitId
71+
val gradleVerison = gradle.gradleVersion
72+
val javaVersion = System.getProperty("java.version")
73+
val isParallel = gradle.startParameter.isParallelProjectExecutionEnabled
74+
val maxWorkerCount = gradle.startParameter.maxWorkerCount
75+
val projectVersion = project.version
76+
doFirst {
77+
val message =
78+
"""
79+
====
80+
Gradle version : $gradleVerison
81+
Java version : $javaVersion
82+
isParallel : $isParallel
83+
maxWorkerCount : $maxWorkerCount
84+
Architecture : $arch
6885
69-
Project Version : ${project.version}
70-
Pkl Version : ${buildInfo.pklVersion}
71-
Pkl Non-Unique Version : ${buildInfo.pklVersionNonUnique}
72-
Git Commit ID : ${buildInfo.commitId}
73-
====
74-
"""
86+
Project Version : $projectVersion
87+
Pkl Version : ${pklVersion.get()}
88+
Pkl Non-Unique Version : $pklVersionNonUnique
89+
Git Commit ID : ${commitId.get()}
90+
====
91+
"""
92+
.trimIndent()
7593

76-
val formattedMessage =
77-
message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
94+
val formattedMessage =
95+
message.replace("====", "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
7896

79-
logger.info(formattedMessage)
97+
println(formattedMessage)
98+
}
99+
}

gradle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ org.gradle.jvmargs= \
1515

1616
org.gradle.parallel=true
1717
org.gradle.caching=true
18+
org.gradle.configuration-cache=true
19+
1820
kotlin.stdlib.default.dependency=false
1921
kotlin.daemon.jvmargs=-XX:+UseParallelGC
2022
#org.gradle.workers.max=1

pkl-cli/pkl-cli.gradle.kts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import java.io.ByteArrayOutputStream
1716
import java.io.OutputStream
1817
import org.gradle.kotlin.dsl.support.serviceOf
1918

@@ -118,7 +117,8 @@ private fun setupJavaExecutableRun(
118117
null -> "java"
119118
else -> launcher.get().executablePath.asFile.absolutePath
120119
}
121-
standardOutput = OutputStream.nullOutputStream()
120+
121+
doFirst { standardOutput = OutputStream.nullOutputStream() }
122122

123123
args("-jar", tasks.javaExecutable.get().outputs.files.singleFile.toString(), *args)
124124

@@ -133,7 +133,10 @@ val evalTestFlags = arrayOf("eval", "-x", "1 + 1", "pkl:base")
133133

134134
fun Exec.useRootDirAndSuppressOutput() {
135135
workingDir = rootProject.layout.projectDirectory.asFile
136-
standardOutput = ByteArrayOutputStream() // we only care that this exec doesn't fail
136+
doFirst {
137+
// we only care that this exec doesn't fail
138+
standardOutput = OutputStream.nullOutputStream()
139+
}
137140
}
138141

139142
// 0.28 Preparing for JDK21 toolchains revealed that `testStartJavaExecutable` may pass, even though

pkl-commons-test/pkl-commons-test.gradle.kts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,29 @@ for (packageDir in file("src/main/files/packages").listFiles()!!) {
7070
into(destinationDir)
7171
val shasumFile = destinationDir.map { it.file("${packageDir.name}.json.sha256") }
7272
outputs.file(shasumFile)
73+
val hexDigits =
74+
charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
75+
val computeChecksum: (File) -> String = { file ->
76+
val hash = MessageDigest.getInstance("SHA-256").digest(file.readBytes())
77+
buildString(hash.size * 2) {
78+
for (b in hash) {
79+
append(hexDigits[b.toInt() shr 4 and 0xF])
80+
append(hexDigits[b.toInt() and 0xF])
81+
}
82+
}
83+
}
7384
filter { line ->
74-
line.replaceFirst("\$computedChecksum", archiveFile.get().asFile.computeChecksum())
85+
line.replaceFirst("\$computedChecksum", computeChecksum(archiveFile.get().asFile))
7586
}
87+
val isWindows = buildInfo.os.isWindows
7688
doLast {
7789
val outputFile = destinationDir.get().asFile.resolve("${packageDir.name}.json")
78-
if (buildInfo.os.isWindows) {
90+
if (isWindows) {
7991
val contents = outputFile.readText()
8092
// workaround for https://github.com/gradle/gradle/issues/1151
8193
outputFile.writeText(contents.replace("\r\n", "\n"))
8294
}
83-
shasumFile.get().asFile.writeText(outputFile.computeChecksum())
95+
shasumFile.get().asFile.writeText(computeChecksum(outputFile))
8496
}
8597
}
8698

@@ -111,6 +123,9 @@ val generateKeys by
111123
"CN=localhost",
112124
)
113125
workingDir(keystoreDir)
126+
// capture keystoreFile inside closure so we don't reference `this$0`; which breaks Gradle
127+
// configuration cache
128+
val keystoreFile = keystoreFile
114129
doFirst {
115130
workingDir.mkdirs()
116131
keystoreFile.get().asFile.delete()
@@ -143,20 +158,3 @@ val exportCerts by
143158
outputFile.get().asFile.delete()
144159
}
145160
}
146-
147-
fun toHex(hash: ByteArray): String {
148-
val hexDigitTable =
149-
charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
150-
return buildString(hash.size * 2) {
151-
for (b in hash) {
152-
append(hexDigitTable[b.toInt() shr 4 and 0xF])
153-
append(hexDigitTable[b.toInt() and 0xF])
154-
}
155-
}
156-
}
157-
158-
fun File.computeChecksum(): String {
159-
val md = MessageDigest.getInstance("SHA-256")
160-
val hash = md.digest(readBytes())
161-
return toHex(hash)
162-
}

pkl-config-java/pkl-config-java.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ val generateTestConfigClasses by
3333

3434
classpath = pklCodegenJava
3535
mainClass.set("org.pkl.codegen.java.Main")
36+
val codegenSources = fileTree("src/test/resources/codegenPkl")
3637
argumentProviders.add(
3738
CommandLineArgumentProvider {
3839
listOf("--output-dir", outputDir.get().asFile.path, "--generate-javadoc") +
39-
fileTree("src/test/resources/codegenPkl").map { it.path }
40+
codegenSources.map { it.path }
4041
}
4142
)
4243
}

0 commit comments

Comments
 (0)