diff --git a/esphome/platformio/library.py b/esphome/platformio/library.py index 12f076edd4..fd94197c93 100644 --- a/esphome/platformio/library.py +++ b/esphome/platformio/library.py @@ -655,6 +655,21 @@ def lex_build_flags(entries: str | list[str], owner: str) -> list[str]: BARE_ARG_FLAGS = frozenset({"-I", "-L", "-l", "-D"}) +def raise_on_empty_arg_flags(tokens: list[str], owner: str) -> None: + """Reject bare ``-I``/``-D``/``-L``/``-l`` tokens left by an empty glued + argument (``-D ""``). + + Lives next to ``join_flag_args`` because the bare token is its + postcondition: a trailing bare flag is warned and dropped there, so a + surviving one always means an empty argument. gcc would eat the next + flag as the argument (or add the CWD for ``-L``); always a typo. + """ + if empty := sorted({tok for tok in tokens if tok in BARE_ARG_FLAGS}): + raise EsphomeError( + f"{owner} contain empty-argument flag(s): {', '.join(empty)}" + ) + + def join_flag_args(tokens: Iterable[str], owner: str) -> list[str]: """Join a bare ``-I``/``-L``/``-l``/``-D`` with its following token, the way PlatformIO's ParseFlags lexes them.""" diff --git a/tests/unit_tests/test_platformio_library.py b/tests/unit_tests/test_platformio_library.py index 927f561236..fcf5931245 100644 --- a/tests/unit_tests/test_platformio_library.py +++ b/tests/unit_tests/test_platformio_library.py @@ -690,6 +690,13 @@ def test_prefetch_wave_unknown_size_falls_back_to_sequential( assert "No Content-Length for https://x/b.tar.gz" in caplog.text +def test_raise_on_empty_arg_flags() -> None: + """A surviving bare flag means an empty glued argument; reject by name.""" + with pytest.raises(EsphomeError, match=r"build_flags contain empty-argument"): + lib.raise_on_empty_arg_flags(["-DFOO", "-D", "-l"], "build_flags") + lib.raise_on_empty_arg_flags(["-DFOO", "-Iinc"], "build_flags") + + def test_content_lengths_head_requests(monkeypatch: pytest.MonkeyPatch) -> None: """Sizes come from HEAD Content-Length; a failing HEAD reads as 0 so the combined bar is skipped rather than wrong."""