Metadata-Version: 2.4
Name: esp-bmgr-assist
Version: 0.4.0
Summary: ESP Board Manager Python package for idf.py extensions
Author: ESP Board Manager Team
License: Apache-2.0
Keywords: esp-idf,board-manager,idf.py,extensions
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=5.1
Dynamic: license-file
Dynamic: requires-python

# esp-bmgr-assist

PyPI 发行版名：**`esp-bmgr-assist`**（`pip install esp-bmgr-assist`）。Python 包目录仍为 **`esp_bmgr_py`**（含 `.pth` 引导），与旧文档中的 `esp-bmgr-py` 仓库路径可并存。

这个包通过自动注入一段代码到 `idf.py`，为 [ESP Board Manager](https://components.espressif.com/components/espressif/esp_board_manager) 功能提供便捷使用支持。

## 功能特性

- 通过 `.pth` 文件实现自动注入
- 自动查找和设置 board manager 组件路径
- 支持 `-C` / `--project-dir` 等 `idf.py` 项目目录参数
- 支持本地组件（`components/esp_board_manager`）和托管组件（`managed_components/espressif__esp_board_manager`）
- 在执行 `idf.py gen-bmgr-config ...` 时按项目依赖图解析并发现 board manager 组件
- 支持通过直接依赖或传递依赖定位 board manager 组件

## 安装

注意：必须要安装在 esp-idf 的虚拟环境中

从 `0.3.1` 开始，本包**不再声明 `idf-component-manager` 等由 ESP-IDF 自身管理的核心 Python 依赖**，避免 `pip install esp-bmgr-assist` 时把 IDF 虚拟环境中的 `click`、`pyparsing`、`idf-component-manager` 升级到与当前 IDF 版本不兼容的版本。

如果你之前安装过 `0.3.0`，并且发现 `check-python-dependencies` 失败，请先重新执行当前 IDF 版本对应的 `install.sh` 修复虚拟环境，再安装新版本的 `esp-bmgr-assist`。

### 从 PyPI 安装

```bash
pip install esp-bmgr-assist
```

### 从源码安装

```bash
pip install /path/to/esp-bmgr-py
```

### 安装失败：`InvalidVersion` / `4.0.0-unsupported`（Anaconda、旧环境）

这与 **Python 小版本（如 3.8）无关**，也与本包元数据无关。常见原因是当前环境里 **已有** 某些发行版（例如 conda 自带的 `pyodbc`）在 `METADATA` 里写了 **不符合 PEP 440** 的版本号（如 `4.0.0-unsupported`），新版 `pip` 在解析已安装包时会直接报错，**在安装任意新包时都可能触发**。

建议按优先顺序处理：

1. **推荐**：在 **ESP-IDF 官方虚拟环境**里安装（`export.sh` / `get_idf` 激活后的那个 Python），不要在 Anaconda **base** 或杂糅大量科学计算包的环境里装。
2. **修环境**：对报错中点名的包重装或卸载，例如  
   `pip install --force-reinstall 'pyodbc>=4.0.34'`  
   或若不用则 `pip uninstall pyodbc`。对日志里的 `pyzmq` 等同理。
3. **干净环境**：`python -m venv bmgr-venv && source bmgr-venv/bin/activate`，再 `pip install esp-bmgr-assist`。
4. **可尝试**：较旧解析行为有时能绕过部分问题：  
   `pip install esp-bmgr-assist --use-deprecated=legacy-resolver`  
   （取决于你当前的 `pip` 版本是否仍支持该选项。）

本包无法在自身 wheel 里“屏蔽”环境里其他用损坏版本号的包；兼容手段是 **使用 IDF 推荐环境** 或 **修复/隔离该 Python 环境**。

## 工作原理

1. **自动注入**: 通过 `.pth` 文件在 Python 启动时自动导入 `idf_injector` 模块，注册导入钩子

2. **延迟执行**: 使用导入钩子机制，仅在 `idf.py` 导入 `idf_py_actions` 模块时才执行初始化代码（此时 logging 系统已初始化，避免过早执行干扰 CMake 的 Python 检测）

3. **组件查找**: `_main()` 函数执行时，按以下优先级查找 board manager 组件：
   - 优先查找本地组件：检查 `components/esp_board_manager` 或 `components/espressif__esp_board_manager`
   - 检查 manifest 文件中的 `override_path` 配置
   - 检查 `dependencies.lock` 中已解析出的本地 board manager
   - 检查已下载的托管组件：`managed_components/espressif__esp_board_manager`

4. **主动自举**: 如果执行的是 `idf.py gen-bmgr-config ...` 且当前工程还没有可用的 board manager 组件：
   - 自动解析真实工程目录（支持 `-C` / `--project-dir`）
   - 收集项目中的本地组件 manifest
   - 使用 ESP-IDF Component Manager 按项目依赖图解析依赖
   - 从 `dependencies.lock` 或 `managed_components` 中定位最终的 board manager 组件

5. **环境变量设置**: 将找到的 board manager 组件路径添加到 `IDF_EXTRA_ACTIONS_PATH` 环境变量

6. **自动发现**: `idf.py` 会自动扫描 `IDF_EXTRA_ACTIONS_PATH` 目录，发现并加载 board manager 扩展

### `IDF_EXTRA_ACTIONS_PATH` 多路径写法

与 ESP-IDF `tools/idf.py` 一致：**多个目录必须用英文分号 `;` 分隔**（各平台相同）。不要使用 `os.pathsep`（例如 Linux/macOS 上常见的 `:`）：IDF 只会按 `;` 拆分，否则整段会被当成一个目录名，扩展无法按预期加载。本包内合并/解析该变量时也仅按 `;` 处理，与 IDF 行为对齐。

## 使用方法

安装后，直接使用 `idf.py` 命令：

```bash
idf.py gen-bmgr-config
```

## 调试

设置 `ESP_BMGR_DEBUG=1` 环境变量可查看调试信息：

```bash
export ESP_BMGR_DEBUG=1
idf.py gen-bmgr-config
```

调试输出来自 **esp_bmgr_py**（`idf_injector`），与 board 管理组件内部的日志系统无关。`idf_injector loaded` 仅在 **当前 `idf.py` 进程** 进入扩展自举时打印一次——不会在组件下载等环节启动的每个 Python 子进程里重复打印。
