lightbend / config

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

When rendering unresolved ConfigConcatenation, whitespaces are erroneously included #806

Open guerrillalg opened 4 months ago

guerrillalg commented 4 months 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.

guerrillalg commented 2 weeks ago

So, the fix is there and everyone is ignoring it.. :(

ekrich commented 2 weeks ago

See https://github.com/lightbend/config/issues/789 I have a Scala port mentioned there that is also Cross platform to Scala.js and Scala Native if you are interested.