Paradaux

PAR-253

0

Merge missing config.yml keys from the jar default on upgrade, preserving surrounding comments

BacklogUnassignedHiberniaFrameworkFeature

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:

  1. For every key path present in the jar default but missing on disk, insert it with the jar's default value.
  2. Carry across the comment block that surrounds each inserted key in the jar default (the header/explanatory comments above it, and any inline comment).
  3. Leave every existing operator value, comment, and the overall ordering/structure intact.
  4. Then let reloadConfig() / ConfigurationProcessor run 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 YamlConfiguration comment APIsoptions().parseComments(true), getComments()/setComments(), setInlineComments(). Load both docs, walk the jar default, and for each missing path set(...) the value then setComments(...) 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.yml with 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