Re-glue spaced -D tokens so knob defines are detected like PlatformIO

This commit is contained in:
J. Nick Koston
2026-08-20 11:37:28 -05:00
parent 7a2eaad9ce
commit 100dc04b38
4 changed files with 24 additions and 6 deletions
+9 -4
View File
@@ -176,10 +176,15 @@ def _flag_defines() -> dict[str, str]:
defines: dict[str, str] = {}
for flag in CORE.build_flags:
# Shell-lex multi-token entries the way PlatformIO does, so a knob
# in "-DKNOB -DOTHER" is still detected; single tokens pass verbatim
# to keep any quoting in their bodies intact.
for tok in split_flag_entry(flag, "esphome") if " " in flag else (flag,):
if tok.startswith("-D"):
# in "-DKNOB -DOTHER" or a spaced "-D KNOB" is still detected;
# single tokens pass verbatim to keep quoting in their bodies intact.
tokens = (
join_flag_args(split_flag_entry(flag, "esphome"), "esphome")
if " " in flag
else (flag,)
)
for tok in tokens:
if tok.startswith("-D") and len(tok) > 2:
body = tok[2:]
defines[body.split("=", 1)[0]] = body
return defines
+3 -2
View File
@@ -564,11 +564,12 @@ def split_flag_entry(entry: str, owner: str) -> list[str]:
def join_flag_args(tokens: Iterable[str], owner: str) -> list[str]:
"""Join a bare ``-I``/``-L``/``-l`` with its following token (PIO lexing)."""
"""Join a bare ``-I``/``-L``/``-l``/``-D`` with its following token,
the way PlatformIO's ParseFlags lexes them."""
out: list[str] = []
it = iter(tokens)
for tok in it:
if tok in ("-I", "-L", "-l"):
if tok in ("-I", "-L", "-l", "-D"):
arg = next(it, None)
if arg is None:
_LOGGER.warning("Ignoring trailing '%s' in %s build flags", tok, owner)
@@ -665,3 +665,11 @@ def test_write_project_empty_core_raises(tmp_path: Path) -> None:
pytest.raises(EsphomeError, match="no core sources"),
):
arduino8266.write_project(paths)
def test_flag_defines_joins_spaced_define() -> None:
"""A spaced "-D KNOB" entry is detected exactly as PlatformIO detects it."""
_set_flags("-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH")
defines = _flag_defines()
assert "PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH" in defines
assert "" not in defines
@@ -538,5 +538,9 @@ def test_split_flag_entry_unbalanced_quote_is_clean() -> None:
from esphome.platformio.library import split_flag_entry
assert split_flag_entry('-DX="a b"', "library x") == ["-DX=a b"]
# join_flag_args re-glues a spaced -D like ParseFlags does
from esphome.platformio.library import join_flag_args
assert join_flag_args(["-D", "FOO=1", "-Os"], "x") == ["-DFOO=1", "-Os"]
with pytest.raises(EsphomeError, match=r"Malformed build flag.*library x"):
split_flag_entry('-DX="unclosed', "library x")