PAR-253
Merge missing config.yml keys from the jar default on upgrade, preserving surrounding comments
Part of PAR-251. This is the harder half — the "ideally also copy across the comments" ask.
Today
ConfigurationLoader ctor (configurator/ConfigurationLoader.java:33) calls plugin.saveDefaultConfig(), which writes config.yml only when it doesn't already exist. No merge happens on upgrade, so a @ConfigurationValue key a new release ships is absent from an operator's existing config.yml; ConfigurationProcessor then reads it as the annotation/code default and the operator never sees the new option (or its documentation) in their file.
Want
On upgrade (trigger per PAR-251), deep-merge the jar default config.yml (plugin.getResource("config.yml")) into the on-disk config.yml:
- For every key path present in the jar default but missing on disk, insert it with the jar's default value.
- Carry across the comment block that surrounds each inserted key in the jar default (the header/explanatory comments above it, and any inline comment).
- Leave every existing operator value, comment, and the overall ordering/structure intact.
- Then let
reloadConfig()/ConfigurationProcessorrun as normal.
The catch — Bukkit strips comments
config.options().copyDefaults(true) + setDefaults(jarDefaults) + save() will add missing keys but drops comments and reorders the file — so it can't satisfy the comment requirement.
Options to evaluate:
- Paper/Bukkit ≥1.18
YamlConfigurationcomment APIs —options().parseComments(true),getComments()/setComments(),setInlineComments(). Load both docs, walk the jar default, and for each missing pathset(...)the value thensetComments(...)from the jar. Works within Bukkit; verify behaviour for nested maps and that it doesn't reflow existing comments. - SnakeYAML / Configurate node-level merge for finer control over comment nodes and insert position, if the Bukkit APIs prove too lossy.
Scope / notes
- Deep/recursive merge: only insert missing leaf paths; never overwrite a populated subtree or a key the operator set (including ones they set to a non-default value).
- Output must remain valid YAML and re-parse to the same values.
- Idempotent: a run with no new keys is a no-op (byte-identical file).
Done when
- Deploying a version that adds a config option leaves the operator's
config.ymlwith the new key at its default and the explanatory comments from the jar default around it, with all existing values/comments/structure preserved.
Ref: hibernia-framework @ efc3f9b.
Comments
No comments yet.
Activity
- tesks created the issue