mirror of
https://github.com/esphome/esphome.git
synced 2026-10-08 12:04:03 +00:00
[esp8266] Normalize misspelled boards and fall back to PlatformIO for unknown ones (#20322)
This commit is contained in:
@@ -114,9 +114,37 @@ _validate_toolchain = cv.toolchain_enum(_TOOLCHAINS)
|
||||
_resolve_toolchain = cv.resolve_toolchain("ESP8266", _TOOLCHAINS, Toolchain.ARDUINO)
|
||||
|
||||
|
||||
# Known boards keyed by spelling with case and "-" / "_" folded away
|
||||
_FOLDED_BOARDS = {board.lower().replace("-", "_"): board for board in BOARDS}
|
||||
|
||||
|
||||
def _resolve_board(config: ConfigType) -> ConfigType:
|
||||
"""Fix a misspelled board, else build an unknown one with PlatformIO."""
|
||||
board = config[CONF_BOARD]
|
||||
if board in BOARDS:
|
||||
return config
|
||||
if canonical := _FOLDED_BOARDS.get(board.lower().replace("-", "_")):
|
||||
_LOGGER.warning(
|
||||
"Board '%s' is not a known ESP8266 board; using '%s'", board, canonical
|
||||
)
|
||||
return {**config, CONF_BOARD: canonical}
|
||||
if CORE.toolchain is None and CONF_TOOLCHAIN not in config:
|
||||
return {**config, CONF_TOOLCHAIN: Toolchain.PLATFORMIO}
|
||||
return config
|
||||
|
||||
|
||||
def _warn_platformio_toolchain(config: ConfigType) -> ConfigType:
|
||||
# Remove before 2027.4.0
|
||||
if CORE.using_toolchain_platformio:
|
||||
if not CORE.using_toolchain_platformio:
|
||||
return config
|
||||
if config[CONF_BOARD] not in BOARDS:
|
||||
_LOGGER.warning(
|
||||
"Board '%s' is not supported by the native 'arduino' toolchain, so it "
|
||||
"builds with the deprecated 'platformio' toolchain, which will be "
|
||||
"removed in ESPHome 2027.4.0",
|
||||
config[CONF_BOARD],
|
||||
)
|
||||
else:
|
||||
_LOGGER.warning(
|
||||
"The 'platformio' toolchain for ESP8266 is deprecated and will be "
|
||||
"removed in ESPHome 2027.4.0; the native 'arduino' toolchain is the "
|
||||
@@ -329,6 +357,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
): _validate_toolchain,
|
||||
}
|
||||
),
|
||||
_resolve_board,
|
||||
_resolve_toolchain,
|
||||
_warn_platformio_toolchain,
|
||||
_validate_native_toolchain,
|
||||
|
||||
@@ -12,10 +12,12 @@ import pytest
|
||||
from esphome.components import esp8266
|
||||
from esphome.components.esp8266 import (
|
||||
ARDUINO_FRAMEWORK_SCHEMA,
|
||||
_resolve_board,
|
||||
_resolve_toolchain,
|
||||
_validate_native_toolchain,
|
||||
_warn_platformio_toolchain,
|
||||
)
|
||||
from esphome.components.esp8266.const import KEY_BOARD, KEY_ESP8266
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BOARD,
|
||||
@@ -118,6 +120,57 @@ def test_unsupported_board_rejected() -> None:
|
||||
_validate_native_toolchain(_config(board="not_a_board"))
|
||||
|
||||
|
||||
def test_known_board_passes_unchanged() -> None:
|
||||
config = {CONF_BOARD: "esp01_1m"}
|
||||
assert _resolve_board(config) is config
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("board", "expected"),
|
||||
[("ESP01-1M", "esp01_1m"), ("SPARKFUNBLYNK", "sparkfunBlynk")],
|
||||
)
|
||||
def test_misspelled_board_normalized(
|
||||
board: str, expected: str, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
assert _resolve_board({CONF_BOARD: board})[CONF_BOARD] == expected
|
||||
assert f"using '{expected}'" in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("board", "expected_board", "expected_toolchain"),
|
||||
[
|
||||
("esp01-1m", "esp01_1m", Toolchain.ARDUINO),
|
||||
("my_custom_board", "my_custom_board", Toolchain.PLATFORMIO),
|
||||
],
|
||||
)
|
||||
def test_config_schema_resolves_board_before_toolchain(
|
||||
board: str,
|
||||
expected_board: str,
|
||||
expected_toolchain: Toolchain,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""The full chain normalizes or falls back, and warns once."""
|
||||
CORE.toolchain = None
|
||||
config = esp8266.CONFIG_SCHEMA({CONF_BOARD: board})
|
||||
assert config[CONF_BOARD] == expected_board
|
||||
assert CORE.data[KEY_ESP8266][KEY_BOARD] == expected_board
|
||||
assert CORE.toolchain == expected_toolchain
|
||||
assert len(caplog.records) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("cli_toolchain", "yaml"),
|
||||
[(Toolchain.ARDUINO, {}), (None, {CONF_TOOLCHAIN: Toolchain.ARDUINO})],
|
||||
)
|
||||
def test_unknown_board_keeps_explicit_toolchain(
|
||||
cli_toolchain: Toolchain | None, yaml: ConfigType
|
||||
) -> None:
|
||||
"""A CLI or YAML toolchain is not overridden."""
|
||||
CORE.toolchain = cli_toolchain
|
||||
config = {CONF_BOARD: "my_custom_board", **yaml}
|
||||
assert _resolve_board(config) is config
|
||||
|
||||
|
||||
def test_yaml_toolchain_key_resolves() -> None:
|
||||
"""The documented `toolchain: arduino` YAML key selects the native path."""
|
||||
CORE.toolchain = None
|
||||
|
||||
Reference in New Issue
Block a user