103 lines
4.1 KiB
Python
103 lines
4.1 KiB
Python
import os
|
|
import sys
|
|
import shutil
|
|
import importlib.util
|
|
import tempfile
|
|
import yaml
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from idf_component_manager.dependencies import download_project_dependencies
|
|
from idf_component_tools.manager import ManifestManager
|
|
from idf_component_tools.utils import ProjectRequirements
|
|
except ImportError:
|
|
download_project_dependencies = ManifestManager = ProjectRequirements = None
|
|
|
|
def _bmgr_config_callback(target_name: str, ctx, args, **kwargs) -> None:
|
|
raise Exception("should not be called")
|
|
|
|
_FAKE_ACTIONS = {
|
|
"actions": {
|
|
"gen-bmgr-config": {
|
|
"callback": _bmgr_config_callback,
|
|
"options": [],
|
|
"short_help": "Generate ESP Board Manager configuration files",
|
|
},
|
|
}
|
|
}
|
|
|
|
def _load_module(file_path, module_name=None):
|
|
module_name = module_name or file_path.stem
|
|
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
|
if spec is None or spec.loader is None:
|
|
raise ImportError(f'Failed to create spec for {file_path}')
|
|
mod = importlib.util.module_from_spec(spec)
|
|
sys.modules[module_name] = mod
|
|
spec.loader.exec_module(mod)
|
|
return mod
|
|
|
|
def _download_bmgr_component(project_path: str) -> None:
|
|
"""Extract the esp_board_manager dependency from the manifest file in the project's main directory and download it."""
|
|
if not all([download_project_dependencies, ManifestManager, ProjectRequirements]):
|
|
print("Warning: idf-component-manager is not available, cannot download component")
|
|
return
|
|
|
|
MANIFEST_NAMES = ["idf_component.yml", "idf_component.yaml"]
|
|
BMGR_KEYS = ["espressif/esp_board_manager", "esp_board_manager"]
|
|
proj = Path(project_path)
|
|
main_dir = proj / "main"
|
|
managed_path = proj / "managed_components"
|
|
lock_path = proj / "dependencies.lock"
|
|
|
|
manifest_path = next((p for f in MANIFEST_NAMES if (p := main_dir / f).exists()), None)
|
|
if not manifest_path:
|
|
print(f"Warning: Manifest file not found at {main_dir}/idf_component.yml or {main_dir}/idf_component.yaml")
|
|
return
|
|
|
|
managed_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
try:
|
|
with open(manifest_path, 'r', encoding='utf-8') as f:
|
|
deps = (yaml.safe_load(f) or {}).get('dependencies', {})
|
|
|
|
bmgr_key = next((k for k in BMGR_KEYS if k in deps), None)
|
|
if not bmgr_key:
|
|
print(f"Warning: esp_board_manager dependency not found in {manifest_path}")
|
|
return
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
temp_manifest = Path(temp_dir) / "idf_component.yml"
|
|
with open(temp_manifest, 'w', encoding='utf-8') as f:
|
|
yaml.dump({'dependencies': {bmgr_key: deps[bmgr_key]}}, f)
|
|
|
|
manifest = ManifestManager(str(temp_dir), "temp").load()
|
|
download_project_dependencies(
|
|
ProjectRequirements([manifest]),
|
|
str(lock_path),
|
|
str(managed_path),
|
|
)
|
|
print(f"Successfully downloaded esp_board_manager component to {managed_path}")
|
|
except Exception as e:
|
|
print(f"Error downloading esp_board_manager component: {e}")
|
|
raise
|
|
|
|
def action_extensions(base_actions: dict, project_path: str) -> dict:
|
|
bmgr_path = Path(project_path) / "managed_components" / "espressif__esp_board_manager"
|
|
|
|
if len(sys.argv) > 2 and sys.argv[1] == "gen-bmgr-config":
|
|
is_updating = os.getenv("_IDF_EXT_UPDATING_DEPS") == "1"
|
|
shutil.rmtree(Path(project_path) / "components" / "gen_bmgr_codes", ignore_errors=True)
|
|
if not bmgr_path.exists() and not is_updating:
|
|
os.environ["_IDF_EXT_UPDATING_DEPS"] = "1"
|
|
os.environ.setdefault("IDF_TARGET", "esp32")
|
|
try:
|
|
_download_bmgr_component(project_path)
|
|
finally:
|
|
os.environ.pop("_IDF_EXT_UPDATING_DEPS", None)
|
|
|
|
if not bmgr_path.exists():
|
|
return _FAKE_ACTIONS
|
|
else:
|
|
bmgr_config = _load_module(bmgr_path / "idf_ext.py")
|
|
return bmgr_config.action_extensions(base_actions, project_path)
|