mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-13 02:26:37 +00:00
fix(plugins): prepare plugin configs one way for load, saves, GET, hot reload and dev tools
Plugin config was prepared differently depending on how it arrived:
- JSON POST /plugins/config built a partial body on schema defaults, so
{"enabled": true} reset every other setting of the plugin. It now merges
onto the stored section first, as the form path already did.
- Legacy-boolean normalization (#588) ran only at load: GET /plugins/config
returned the raw boolean, posting it back failed validation, and hot
reload handed plugins the raw section (a legacy dynamic_duration: true
came back as a boolean). schema_manager.prepare_plugin_config (normalize,
then defaults) is now used by PluginManager.load_plugin, both save paths,
GET, the save notifications and DisplayController's hot-reload callback.
- The JSON save's filter kept only enabled/display_duration/live_priority
and dropped a submitted skin, skin_options or vegas_* tuning key. There
is now one core-owned per-plugin list, schema_manager.CORE_PLUGIN_PROPERTIES,
used by validation and by the save filter; PluginManager's
CORE_OWNED_CONFIG_KEYS is its vegas subset.
- Plugin sections posted to /config/main were stored verbatim, including
values /plugins/config rejects. They now go through the same preparation
(_prepare_plugin_config_for_save, extracted from save_plugin_config), and
a failing section rejects the whole save before anything is written.
- dev_server read only top-level defaults and let a schema enabled:false
win; build_full_config shallow-merged overrides, dropping sibling
defaults; the harness extracted defaults differently from the device.
loading.build_config now uses the device's extraction and preparation,
and dev_server, check_plugin, render_plugin and the harness all use it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+16
-12
@@ -142,17 +142,18 @@ def find_plugin_dir(plugin_id: str) -> Optional[Path]:
|
||||
|
||||
|
||||
def load_config_defaults(plugin_dir: 'str | Path') -> Dict[str, Any]:
|
||||
"""Extract default values from config_schema.json."""
|
||||
"""Extract default values from config_schema.json.
|
||||
|
||||
The same extraction a device and the plugin harness use
|
||||
(src/plugin_system/testing/loading.py), nested defaults included.
|
||||
"""
|
||||
from src.plugin_system.testing.loading import (
|
||||
load_config_defaults as _load_config_defaults,
|
||||
)
|
||||
schema_path = resolve_under(plugin_dir, 'config_schema.json')
|
||||
if schema_path is None or not schema_path.exists():
|
||||
return {}
|
||||
with open(schema_path, 'r') as f:
|
||||
schema = json.load(f)
|
||||
defaults: Dict[str, Any] = {}
|
||||
for key, prop in schema.get('properties', {}).items():
|
||||
if 'default' in prop:
|
||||
defaults[key] = prop['default']
|
||||
return defaults
|
||||
return _load_config_defaults(schema_path.parent)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
@@ -303,10 +304,13 @@ def _parse_render_request(data):
|
||||
with open(manifest_path, 'r') as f:
|
||||
manifest = json.load(f)
|
||||
|
||||
# Build config: schema defaults + user overrides
|
||||
config = {'enabled': True}
|
||||
config.update(load_config_defaults(trusted_dir))
|
||||
config.update(data.get('config', {}))
|
||||
# Build config the way a device would: schema defaults under a forced
|
||||
# enabled, with the user's overrides deep-merged on top
|
||||
from src.plugin_system.testing.loading import build_config
|
||||
overrides = data.get('config') or {}
|
||||
if not isinstance(overrides, dict):
|
||||
raise ValueError('config must be a JSON object')
|
||||
config = build_config(trusted_dir, overrides)
|
||||
|
||||
return trusted_dir, manifest, config, data.get('mock_data', {}), data.get('skip_update', False)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user