Fix invalid prefix when generating spring boot config (#1862)

Fix invalid prefix when generating spring boot config

In Spring Boot, the prefix passed to `@ConfigurationProperties` must
be in "canonical form".

The presence of this annotation allows spring boot to directly inject
properties into a class, but is not actually needed.

The correct behavior here is to omit this annotation if the property
name does not match Spring Boot's canonical form.
This commit is contained in:
Daniel Chao
2026-09-11 15:49:04 -07:00
committed by GitHub
parent 9b52a4fd82
commit e3881f6149
6 changed files with 173 additions and 3 deletions
@@ -36,6 +36,7 @@ import kotlin.let
import kotlin.takeIf
import kotlin.to
import org.pkl.commons.NameMapper
import org.pkl.commons.isValidConfigurationPropertiesPrefix
import org.pkl.core.*
import org.pkl.core.util.CodeGeneratorUtils
import org.pkl.core.util.IoUtils
@@ -540,7 +541,11 @@ class JavaCodeGenerator(
}
propertyType is PType.Class && propertyType.pClass == pClass
}
if (modulePropertiesWithMatchingType.size == 1) {
val singleProperty = modulePropertiesWithMatchingType.singleOrNull()
if (
singleProperty != null && singleProperty.simpleName.isValidConfigurationPropertiesPrefix
) {
// exactly one module property has this type -> make it available for direct injection
// (potential improvement: make type available for direct injection if it occurs exactly
// once in property tree)
@@ -1555,6 +1555,56 @@ class JavaCodeGeneratorTest {
assertThat(javaCodeWithoutSpringAnnotations).compilesSuccessfully()
}
@Test
fun `spring boot -- single module property has type but invalid prefix`() {
val javaCode =
generateJavaCode(
"""
module my.mod
fooBar: FooBar
class FooBar
"""
.trimIndent(),
JavaCodeGeneratorOptions(generateSpringBootConfig = true),
)
// "fooBar" is not a valid prefix for `@ConfigurationProperties` annotations, so no
// annotation is added
assertThat(javaCode)
.contains(
"""
|
| public static final class FooBar {
"""
.trimMargin()
)
}
@Test
fun `spring boot -- single module property has type and valid prefix`() {
val javaCode =
generateJavaCode(
"""
module my.mod
server: Server
class Server
"""
.trimIndent(),
JavaCodeGeneratorOptions(generateSpringBootConfig = true),
)
assertThat(javaCode)
.contains(
"""
| @ConfigurationProperties("server")
| public static final class Server {
"""
.trimMargin()
)
}
@Test
fun `import module`() {
val library =