lightbend / config

configuration library for JVM languages using HOCON files
https://lightbend.github.io/config/
6.12k stars 968 forks source link

When rendering unresolved ConfigConcatenation, whitespaces are erroneously included #806

Open guerrillalg opened 2 weeks ago

guerrillalg commented 2 weeks ago

Given we have a following config, where we want to merge two maps (objects) and for formatting purposes we add a whitespace between them. When we render an unresolved ConfigObject, we get a wrong unparseable result:

var rendered = ConfigFactory.parseString(
                """
                        objectA {
                          a = "A"
                        }
                        objectB {
                         b = "B"
                        }
                        objectC = ${?objectA} ${objectB}
                        """,
                ConfigParseOptions.defaults().setClassLoader(Thread.currentThread().getContextClassLoader()))
                .root()
                .render(ConfigRenderOptions.defaults());

Result: {"objectA":{"a":"A"},"objectB":{"b":"B"},"objectC":${?objectA}" "${objectB}}

The whitespace between objects is turned to a string containing a whitespace.

However, when we do resolve:

var rendered = ConfigFactory.parseString(
                """
                        objectA {
                          a = "A"
                        }
                        objectB {
                         b = "B"
                        }
                        objectC = ${?objectA} ${objectB}
                        """,
                ConfigParseOptions.defaults().setClassLoader(Thread.currentThread().getContextClassLoader()))
                .resolve()
                .root()
                .render(ConfigRenderOptions.defaults());

we get the correct result: {"objectA":{"a":"A"},"objectB":{"b":"B"},"objectC":{"a":"A","b":"B"}}

A workaround for this problem can be to not have a whitespace in the concatenation: objectC = ${?objectA}${objectB}

However, the actual fix of the bug should be done in the ConfigConcatenation#render. This class already contains a method isIgnoredWhitespace and it is used in join method to skip those formatting whitespaces. The solution can be easily applied by using the same isIgnoredWhitespace method to filter pieces in render method.