mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-06 15:25:08 +00:00
fix(web): define project_root when plugins_directory is absolute (#616)
project_root was only assigned in the relative-path branch, so an absolute plugin_system.plugins_directory made web_interface/app.py raise NameError at import (first use: the SchemaManager construction). Define it before the if/else; plugins_dir resolution is unchanged. Adds a regression test that imports the real module in a fresh interpreter with an absolute and a relative plugins_directory. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
"""
|
||||||
|
web_interface/app.py must start with an absolute ``plugins_directory``.
|
||||||
|
|
||||||
|
``project_root`` used to be assigned only in the relative-path branch, so an
|
||||||
|
absolute path in config.json raised NameError at module import (the
|
||||||
|
SchemaManager construction was the first use). Each case imports the real
|
||||||
|
module in a fresh interpreter, since app.py does its setup at import time and
|
||||||
|
the test process may already hold a copy built from the real config.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||||
|
|
||||||
|
_IMPORT_APP = textwrap.dedent(
|
||||||
|
"""
|
||||||
|
import json, sys
|
||||||
|
from pathlib import Path
|
||||||
|
sys.path.insert(0, {root!r})
|
||||||
|
from src.config_manager import ConfigManager
|
||||||
|
ConfigManager.load_config = lambda self: {config!r}
|
||||||
|
import web_interface.app as web_app
|
||||||
|
print(json.dumps({{
|
||||||
|
"plugins_dir": str(web_app.plugins_dir),
|
||||||
|
"project_root": str(web_app.project_root),
|
||||||
|
"schema_project_root": str(web_app.schema_manager.project_root),
|
||||||
|
}}))
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _import_app_with(plugins_directory):
|
||||||
|
config = {"plugin_system": {"plugins_directory": plugins_directory}}
|
||||||
|
script = _IMPORT_APP.format(root=str(PROJECT_ROOT), config=config)
|
||||||
|
result = subprocess.run(
|
||||||
|
[sys.executable, "-c", script],
|
||||||
|
cwd=str(PROJECT_ROOT),
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=120,
|
||||||
|
)
|
||||||
|
assert result.returncode == 0, result.stderr
|
||||||
|
return json.loads(result.stdout.strip().splitlines()[-1])
|
||||||
|
|
||||||
|
|
||||||
|
def test_absolute_plugins_directory_imports(tmp_path):
|
||||||
|
plugins = tmp_path / "my-plugins"
|
||||||
|
plugins.mkdir()
|
||||||
|
|
||||||
|
info = _import_app_with(str(plugins))
|
||||||
|
|
||||||
|
assert Path(info["plugins_dir"]) == plugins
|
||||||
|
assert Path(info["project_root"]) == PROJECT_ROOT
|
||||||
|
assert Path(info["schema_project_root"]) == PROJECT_ROOT
|
||||||
|
|
||||||
|
|
||||||
|
def test_relative_plugins_directory_resolves_under_project_root():
|
||||||
|
info = _import_app_with("plugin-repos")
|
||||||
|
|
||||||
|
assert Path(info["plugins_dir"]) == PROJECT_ROOT / "plugin-repos"
|
||||||
|
assert Path(info["project_root"]) == PROJECT_ROOT
|
||||||
@@ -89,12 +89,15 @@ config = config_manager.load_config()
|
|||||||
plugin_system_config = config.get('plugin_system', {})
|
plugin_system_config = config.get('plugin_system', {})
|
||||||
plugins_dir_name = plugin_system_config.get('plugins_directory', 'plugin-repos')
|
plugins_dir_name = plugin_system_config.get('plugins_directory', 'plugin-repos')
|
||||||
|
|
||||||
|
# Project root (LEDMatrix directory). Needed below for data/ and assets/ paths
|
||||||
|
# whether or not the plugins directory is absolute.
|
||||||
|
project_root = Path(__file__).parent.parent
|
||||||
|
|
||||||
# Resolve plugin directory - handle both absolute and relative paths
|
# Resolve plugin directory - handle both absolute and relative paths
|
||||||
if os.path.isabs(plugins_dir_name):
|
if os.path.isabs(plugins_dir_name):
|
||||||
plugins_dir = Path(plugins_dir_name)
|
plugins_dir = Path(plugins_dir_name)
|
||||||
else:
|
else:
|
||||||
# If relative, resolve relative to the project root (LEDMatrix directory)
|
# If relative, resolve relative to the project root
|
||||||
project_root = Path(__file__).parent.parent
|
|
||||||
plugins_dir = project_root / plugins_dir_name
|
plugins_dir = project_root / plugins_dir_name
|
||||||
|
|
||||||
plugin_manager = PluginManager(
|
plugin_manager = PluginManager(
|
||||||
|
|||||||
Reference in New Issue
Block a user