@@ -54,27 +54,18 @@ fun getPinnedVersions(): Map<String, String> {
5454fun lookupPinnedVersion (group : String? , name : String , version : String? ): String? {
5555 if (! pinLatestDeps || group == null ) return null
5656 val pinned = getPinnedVersions()
57- return if (version == " latest.release" ) {
58- pinned[ " $group :$name #+" ]
57+ val key = if (version == " latest.release" ) {
58+ " $group :$name #+"
5959 } else if (version != null && version.contains(" +" )) {
60- val rangeKey = " $group :$name #$version "
61- val rangeVersion = pinned[rangeKey]
62- if (rangeVersion != null ) {
63- rangeVersion
64- } else {
65- // Range-specific key is missing from the pinned versions JSON.
66- // Do NOT fall back to the base key because it could be a different major version
67- // (e.g. base key resolves to 4.x but the range "2.+" expects 2.x).
68- // Run resolveLatestDepVersions to populate the missing key.
69- throw GradleException (
70- " Pinned version missing for range key \" $rangeKey \" . " +
71- " Run ./gradlew resolveLatestDepVersions -PtestLatestDeps=true -PresolveLatestDeps=true " +
72- " to regenerate .github/config/latest-dep-versions.json"
73- )
74- }
60+ " $group :$name #$version "
7561 } else {
76- null
62+ return null
7763 }
64+ return pinned[key] ? : throw GradleException (
65+ " Pinned version missing for key \" $key \" . " +
66+ " Run ./gradlew resolveLatestDepVersions -PtestLatestDeps=true -PresolveLatestDeps=true " +
67+ " to regenerate .github/config/latest-dep-versions.json"
68+ )
7869}
7970
8071@CacheableRule
@@ -171,22 +162,50 @@ configurations {
171162 // "latest.release" or "+" versions (e.g. transitive deps) gets pinned to a concrete
172163 // version from the JSON file.
173164 if (otelProps.testLatestDeps) {
174- // Only apply to test-related configurations, not build tool configurations like Zinc
175- // (the Scala compiler). Overriding scala-library in Zinc's configuration breaks compilation.
165+ // Pinning and overrides must NOT leak into build-tool configurations like Zinc (the
166+ // Scala compiler), where forcing e.g. scala-library to a JSON-pinned version breaks
167+ // compilation. They also must not affect e.g. japicmp's `tempConfig`, which resolves
168+ // `opentelemetry-instrumentation-bom:latest.release` directly against Maven Central.
169+ // Use an allow-list of configuration names rather than a deny-list so new build-tool
170+ // configurations stay safe by default.
176171 configureEach {
177- if (isCanBeResolved && (name.startsWith(" test" ) || name.startsWith(" latestDepTest" ))) {
178- resolutionStrategy.eachDependency {
172+ if (! isCanBeResolved) return @configureEach
173+ // `latestDepTestLibrary` overrides apply ONLY to the main test/latestDepTest
174+ // configurations. They must NOT touch `compileClasspath`, because the whole point of
175+ // `library(old)` + `latestDepTestLibrary(newRange)` is to keep the agent compiling
176+ // against the old API while testing against the new one. Forcing the override onto
177+ // compileClasspath would upgrade the compileOnly `library(...)` version and break
178+ // compilation (e.g. scala-fork-join-2.8 compiles against scala 2.8 APIs,
179+ // vertx-sql-client-4.0 against generic vertx 4.0 APIs, elasticsearch-transport-5.0
180+ // against generic ES 5.0 APIs). Overrides must also NOT touch custom JvmTestSuite
181+ // source sets (e.g. `play24Test*`, `version20Test*`, `tapirTest*`) which declare
182+ // their own explicit older versions; using `contains("test")` here would let the
183+ // main suite's `latestDepTestLibrary("...:2.5.+")` upgrade play-mvc-2.4's
184+ // `play24Test` classpath off Play 2.4. Use a strict prefix match instead.
185+ val applyOverrides = name.startsWith(" test" ) || name.startsWith(" latestDepTest" )
186+ // Pinning of `latest.release`/`+` versions is applied across test-related
187+ // configurations and the main `compileClasspath`. compileClasspath is included so
188+ // that modules whose `library(...)` declarations resolve `latest.release` in latest
189+ // mode (e.g. gwt-2.0, which uses the post-2.10 `org.gwtproject` group only in latest
190+ // mode) get pinned versions on the agent's compile classpath. Pinning is safe on
191+ // compileClasspath because `lookupPinnedVersion` is a no-op for the concrete versions
192+ // declared via `library(...)`; only dynamic versions (latest.release / +) are affected.
193+ val applyPinning = pinLatestDeps &&
194+ (name.contains(" test" , ignoreCase = true ) || name == " compileClasspath" )
195+ if (! applyOverrides && ! applyPinning) return @configureEach
196+ resolutionStrategy.eachDependency {
197+ if (applyOverrides) {
179198 // latestDepTestLibrary overrides take priority over pinned versions
180199 val override = latestDepTestLibraryOverrides[" ${requested.group} :${requested.name} " ]
181200 if (override != null ) {
182201 useVersion(override )
183202 return @eachDependency
184203 }
185- if (pinLatestDeps) {
186- val pinnedVersion = lookupPinnedVersion(requested.group, requested.name, requested.version)
187- if (pinnedVersion != null ) {
188- useVersion (pinnedVersion)
189- }
204+ }
205+ if (applyPinning) {
206+ val pinnedVersion = lookupPinnedVersion(requested.group, requested.name, requested.version)
207+ if (pinnedVersion != null ) {
208+ useVersion(pinnedVersion)
190209 }
191210 }
192211 }
0 commit comments