Preserve GString/StringTemplate in ChangeDependency when version unchanged#6830
Draft
Preserve GString/StringTemplate in ChangeDependency when version unchanged#6830
Conversation
…rsion is unchanged
When `ChangeDependency` renames a dependency that uses a GString or Kotlin
StringTemplate (e.g. `"group:artifact:${version}"`), and the version is not
being changed, the GString/StringTemplate structure is now preserved instead
of being collapsed to a literal with a pinned version.
Previously, the GString and Kotlin StringTemplate code paths unconditionally
applied `newVersion` without checking the `overrideManagedVersion` guard that
the literal path already had. This caused recipes like the Spring Boot 4
migration to pin hardcoded versions on dependencies that used property
references for their version (e.g. `${springBootVersion}`).
The fix adds the same `overrideManagedVersion` guard to both the GString and
Kotlin StringTemplate paths, and when only group/artifact changes (not
version), updates only the literal prefix while preserving the interpolated
structure.
timtebeek
commented
Feb 26, 2026
| def version = '2.6' | ||
| dependencies { | ||
| implementation platform("org.apache.commons:commons-lang3:3.11") | ||
| implementation platform("org.apache.commons:commons-lang3:${version}") |
Member
Author
There was a problem hiding this comment.
Now we're effectively not making any change, other than the markers; We should add gradle.properties files here and assert those are updated.
Move version variables from inline definitions to gradle.properties in worksWithGString and kotlinDslStringInterpolation tests, making them closer to real-world usage patterns. The properties file remains unchanged, confirming the GString/StringTemplate structure is preserved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
overrideManagedVersionguard to GString and Kotlin StringTemplate code paths inChangeDependency, matching the existing guard on the literal pathworksWithGString,kotlinDslStringInterpolation) to expect the new behaviorProblem
When
ChangeDependencyrenames a dependency that uses a GString or Kotlin StringTemplate (e.g."group:artifact:${version}"), it unconditionally collapsed the interpolated string to a literal and pinned the resolved version. This caused the Spring Boot 4 migration recipe to turn"org.springframework.boot:spring-boot-starter-web:${springBootVersion}"into"org.springframework.boot:spring-boot-starter-webmvc:4.0.3", destroying the property reference.The literal code path already had the correct guard: it only pins a new version when the original dependency had an explicit version or
overrideManagedVersion=true. The GString and Kotlin StringTemplate paths were missing this guard.Test plan
worksWithGStringtest updated to expect GString preservationkotlinDslStringInterpolationtest updated to expect StringTemplate preservationChangeDependencyTesttests pass