-
Notifications
You must be signed in to change notification settings - Fork 977
Open
Description
Description
Right now, HOCON lets you substitute variables and even mark them as optional. A common pattern looks like this:
port = ${?PORT}
port = 32
It works, but it feels a bit clunky. You end up writing two lines (or relying on layered configs) just to say “use this value, otherwise fall back to that one.” For people new to HOCON, the ordering rules can also be a little confusing.
Proposal
Add support for an inline fallback syntax, for example:
port = ${PORT:32}
Meaning:
- If
PORT
is set → use its value. - If not → just use
32
.
Motivation
- Keeps configs shorter and easier to scan.
- Matches what other systems already do (Spring Boot’s
${VAR:default}
, for instance). - Saves you from repeating the same “optional + fallback” boilerplate across dozens of keys.
Considerations
- Backward compatibility: today
${VAR:default}
is just a literal string, so this would be a new behavior. - Parser ambiguity: the parser needs to clearly distinguish between a fallback and a literal
:
. - Consistency: ideally this should work for both environment variables and config keys.
Compatibility / Migration Plan
- Existing configs that rely on
${VAR:literal}
as a string would resolve differently. - Could be introduced behind a flag (e.g.,
ConfigParseOptions.enableInlineFallback(true)
) or in a major version bump. - Tooling and linters may need updates to catch conflicts.
Grammar Changes
- Extend substitution grammar so
:
inside${}
is treated as a fallback separator. - Only apply this rule when
:
is not inside quotes. - Nested substitutions should continue to work.
Implementation Notes
- Requires changes in both the parser and substitution resolver.
- Defaults should be type-safe: numbers, booleans, lists, and objects should all be valid, not just strings.
Testing / Edge Cases
- Variables whose values actually contain
:
. - Nested fallbacks:
${VAR1:${VAR2:default}}
. - Defaults with spaces or quoted strings.
- Composite defaults, e.g.:
list = ${LIST:[1,2,3]} map = ${MAP:{a=1, b=2}}
Open Questions
- Should defaults themselves allow interpolation (e.g.,
${VAR:${OTHER:42}}
)? - Should whitespace around
:
be allowed? - Should this apply only to environment variables, or also to config keys and system properties?
Example
db.host = ${DB_HOST:localhost}
db.port = ${DB_PORT:5432}
If DB_HOST
and DB_PORT
are not set, the config resolves to:
db.host = "localhost"
db.port = 5432
Metadata
Metadata
Assignees
Labels
No labels