Paradaux

PAR-251

0

Reconcile operator config.yml & messages.properties against shipped jar defaults on plugin upgrade

BacklogUnassignedHiberniaFrameworkFeature

Problem

When a plugin is upgraded, HiberniaFramework deliberately never overwrites the operator's on-disk config.yml / messages.properties (to preserve their edits). The side effect: keys that a new version newly ships in the jar are never merged into the operator's existing files. Until the operator hand-diffs the jar, new config options silently fall back to code defaults, and new message keys render as the literal key.

Both loaders have the same "write-only-if-absent" behaviour:

  • MessagesMessage.ensureDefaultFile() (i18n/Message.java:265-276) calls plugin.saveResource("messages.properties", false) only when the base file is missing; reload() (:279-301) reads bundles from disk only. A plugin-defined key absent on disk → findRaw returns null → the key text is shown (only framework built-ins get a componentOr(...) fallback).
  • ConfigConfigurationLoader ctor (configurator/ConfigurationLoader.java:33) calls plugin.saveDefaultConfig(), which writes config.yml only when absent. New @ConfigurationValue keys missing on disk fall to the annotation/code default; the operator never sees the new option in their file.

Goal

On detecting a version change, additively reconcile each on-disk file against its jar-bundled default: add keys present in the jar but missing on disk, and never touch existing operator values or operator-added keys.

Shared design

  • Detect "new version deployed" by comparing the running plugin version — plugin.yml version, read via getPluginMeta().getVersion() (or getDescription().getVersion()) — against a recorded marker (a small state file in the data folder, e.g. .hibernia-state, or a managed key). The merge is additive and idempotent, so it could also safely run every boot; version-gating just avoids needless rewrites and gives a clean "an upgrade happened" signal.
  • Read jar defaults via plugin.getResource("config.yml") / plugin.getResource("messages.properties") (the bundled copies), not the on-disk files.
  • Ordering: the reconcile must run before Message (ctor does ensureDefaultFile() + reload()) and ConfigurationLoader (ctor does saveDefaultConfig()) read their files — i.e. in the framework bootstrap where both are constructed — so they load the freshly-merged files.
  • A re-added key the operator had deliberately deleted will reappear — acceptable and matches the "fill in missing defaults" intent; note it in docs.

Sub-tasks

  • Messages: merge missing keys from the jar messages.properties into the on-disk base bundle.
  • Config: merge missing keys from the jar config.yml, carrying across the comments that surround them (the harder half).

Done when

  • A plugin upgrade that adds new config options / message keys results in those keys appearing in the operator's pre-existing files with their shipped defaults, with all prior operator values, extra keys, and structure preserved.

Ref: hibernia-framework @ efc3f9b. Consumed by Treasury/Business/etc. as a published dependency, so this lands for every plugin at once.

Comments

No comments yet.

Activity

  • tesks created the issue