Skip to content

Commit 65e2a82

Browse files
jamesarichclaude
andcommitted
chore(build): parallel configuration cache, and make version assignment IP-safe
Enables org.gradle.configuration-cache.parallel, and removes the one thing in this build that Isolated Projects rejects. The root build script set the git-derived version through `allprojects { }`. Under Isolated Projects that fails outright — "Project ':' cannot access 'Project.version' functionality on subprojects via 'allprojects'" — because the root project may not reach into its subprojects' state. The supported equivalent is gradle.lifecycle.beforeProject in settings.gradle.kts, which needs no cross-project access, so the derivation moves there wholesale. One subtlety worth the comment it carries: the beforeProject lambda must close over a *local* copy of the resolved version. A top-level `val` in a settings script is a field of the script object, so referencing it directly makes the configuration cache try to serialise the script itself and fail with "cannot serialize Gradle script object references". Isolated Projects is still not enabled, and the remaining blocker is not ours: KGP's WasmNpmResolverPlugin reaches from :sample into the root project ("Project ':sample' cannot access 'Project.plugins' functionality on another project ':'"). gradle.properties records this so the next reader does not rediscover it. With the build's own side now clean, turning the feature on is a one-line change once JetBrains isolates the Wasm/npm plugins. Verified with spotlessCheck detektAll allTests apiCheck koverVerify. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 4689a54 commit 65e2a82

3 files changed

Lines changed: 49 additions & 33 deletions

File tree

build.gradle.kts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,6 @@ plugins {
1616
alias(libs.plugins.kover)
1717
}
1818

19-
// ---------------------------------------------------------------------------
20-
// Version: derived from the latest git tag (e.g. v0.3.6 → 0.3.6).
21-
// Between tags: next patch + "-SNAPSHOT" (e.g. v0.3.6-4-gabcdef → 0.3.7-SNAPSHOT).
22-
// Overridable via -PVERSION_NAME=... (used by CI snapshot publishing).
23-
// ---------------------------------------------------------------------------
24-
val gitVersion: Provider<String> = providers.exec {
25-
commandLine("git", "describe", "--tags", "--match", "v*")
26-
isIgnoreExitValue = true
27-
}.standardOutput.asText.map { raw ->
28-
val desc = raw.trim()
29-
if (desc.isBlank()) {
30-
return@map providers.gradleProperty("VERSION_NAME").getOrElse("0.0.0-SNAPSHOT")
31-
}
32-
val stripped = desc.removePrefix("v")
33-
if ('-' in stripped) {
34-
// Not on an exact tag — compute next-patch SNAPSHOT
35-
val base = stripped.substringBefore('-')
36-
val parts = base.split('.').map(String::toInt)
37-
"${parts[0]}.${parts[1]}.${parts[2] + 1}-SNAPSHOT"
38-
} else {
39-
stripped
40-
}
41-
}
42-
43-
val resolvedVersion: String =
44-
providers.gradleProperty("VERSION_NAME")
45-
.orElse(gitVersion)
46-
.get()
47-
48-
allprojects {
49-
version = resolvedVersion
50-
}
51-
5219
// ---------------------------------------------------------------------------
5320
// Aggregate API docs (Dokka) and coverage (Kover) across the published library
5421
// modules. The ≥80% coverage gate is enforced on the merged report so that

gradle.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
33
org.gradle.caching=true
44
org.gradle.configuration-cache=true
5+
org.gradle.configuration-cache.parallel=true
56
org.gradle.parallel=true
7+
#Isolated Projects is NOT enabled, and the blocker is not ours: KGP's
8+
#WasmNpmResolverPlugin reaches from :sample into the root project
9+
#("Project ':sample' cannot access 'Project.plugins' functionality on another project ':'").
10+
#The build's own side is already IP-ready — see the beforeProject version assignment in
11+
#settings.gradle.kts — so this is a one-line flip once KGP's Wasm/npm plugins isolate cleanly.
612
org.gradle.vfs.watch=true
713
org.gradle.welcome=never
814
#Kotlin

settings.gradle.kts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,49 @@ dependencyResolutionManagement {
2323
}
2424
}
2525

26+
// ---------------------------------------------------------------------------
27+
// Version: derived from the latest git tag (e.g. v0.3.6 -> 0.3.6).
28+
// Between tags: next patch + "-SNAPSHOT" (e.g. v0.3.6-4-gabcdef -> 0.3.7-SNAPSHOT).
29+
// Overridable via -PVERSION_NAME=... (used by CI snapshot publishing).
30+
//
31+
// Assigned from settings via gradle.lifecycle.beforeProject rather than an
32+
// `allprojects { }` block in the root build script: under Isolated Projects the
33+
// root project may not reach into its subprojects' state, and setting `version`
34+
// that way fails configuration outright. beforeProject is the supported
35+
// equivalent and needs no cross-project access.
36+
// ---------------------------------------------------------------------------
37+
val gitVersion: Provider<String> = providers.exec {
38+
commandLine("git", "describe", "--tags", "--match", "v*")
39+
isIgnoreExitValue = true
40+
}.standardOutput.asText.map { raw ->
41+
val desc = raw.trim()
42+
if (desc.isBlank()) {
43+
return@map providers.gradleProperty("VERSION_NAME").getOrElse("0.0.0-SNAPSHOT")
44+
}
45+
val stripped = desc.removePrefix("v")
46+
if ('-' in stripped) {
47+
// Not on an exact tag - compute next-patch SNAPSHOT
48+
val base = stripped.substringBefore('-')
49+
val parts = base.split('.').map(String::toInt)
50+
"${parts[0]}.${parts[1]}.${parts[2] + 1}-SNAPSHOT"
51+
} else {
52+
stripped
53+
}
54+
}
55+
56+
val resolvedVersion: String =
57+
providers.gradleProperty("VERSION_NAME")
58+
.orElse(gitVersion)
59+
.get()
60+
61+
// Copied into a local before the lambda closes over it: a top-level `val` in a settings script is a
62+
// field of the script object, so referencing it directly would capture the script itself — which the
63+
// configuration cache cannot serialize ("cannot serialize Gradle script object references").
64+
run {
65+
val projectVersion = resolvedVersion
66+
gradle.lifecycle.beforeProject { version = projectVersion }
67+
}
68+
2669
rootProject.name = "MQTTastic-Client-KMP"
2770
include(":core")
2871
include(":transport-tcp")

0 commit comments

Comments
 (0)