Track the per-platform shell quoting in the emission drift tests

The asm -D/-I filter also strips a leading single quote now that POSIX
tokens are single-quoted.
This commit is contained in:
J. Nick Koston
2026-08-21 12:28:11 -05:00
parent 2d89ca3dd0
commit afe12061d2
2 changed files with 15 additions and 12 deletions
+3 -2
View File
@@ -590,12 +590,13 @@ def write_project(paths: InstalledPaths) -> bool:
)
# PlatformIO's ASPPCOM carries defines and includes but not CCFLAGS,
# so only -D/-I user flags reach assembly there; match it. The tokens
# are already shell-quoted, so test past a leading quote too.
# are already shell-quoted (per-platform style), so test past a
# leading quote too.
asflags = (
_ASFLAGS
+ defines
+ includes
+ [f for f in project_compile_flags if f.lstrip('"').startswith(("-D", "-I"))]
+ [f for f in project_compile_flags if f.lstrip("\"'").startswith(("-D", "-I"))]
)
# build_unflags applies to the framework flag sets too (compile and link),
+12 -10
View File
@@ -61,6 +61,11 @@ def _set_flags(*flags: str) -> None:
CORE.build_flags = set(flags)
def _shq(tok: str) -> str:
"""The platform's shell_token quote wrapper (argv rule on Windows)."""
return f'"{tok}"' if os.name == "nt" else f"'{tok}'"
def test_rule_map_covers_all_source_suffixes() -> None:
"""Every suffix a library manifest can select must map to a ninja rule."""
from esphome.platformio.library import SRC_FILE_EXTENSIONS
@@ -256,9 +261,9 @@ def test_write_project_link_line_and_exclusions(tmp_path: Path) -> None:
# str(Path(...)) so the separator matches the host platform.
opt_blobs = str(Path("/opt/blobs"))
spc_blobs = str(Path("/spc/blobs"))
assert f'-L"{opt_blobs}"' in content
assert f"-L{_shq(opt_blobs)}" in content
assert "-luser_blob" in content
assert f'-L"{spc_blobs}"' in content
assert f"-L{_shq(spc_blobs)}" in content
assert "-lspaced_blob" in content
for line in content.splitlines():
if line.split(" = ")[0] in ("cflags", "cxxflags", "asflags"):
@@ -495,11 +500,11 @@ def test_write_project_libraries_and_variant(
# Library link flags reach the firmware link line; .cc compiles as C++
assert "-Wl,--wrap=malloc" in content
assert "impl.cc.o: cxx" in content
assert f'-L"{lib_dir / "blobs"}"' in content
assert f"-L{_shq(str(lib_dir / 'blobs'))}" in content
# Exceptions knob: -fexceptions and the exception-enabled stdc++
assert "-fexceptions" in content
assert "-lstdc++-exc" in content
assert 'ccache = "/cc/ccache"' in content
assert f"ccache = {_shq('/cc/ccache')}" in content
def test_get_flash_ld_path(tmp_path: Path) -> None:
@@ -638,10 +643,7 @@ def test_project_flags_requotes_lexed_defines() -> None:
)
# shlex folds the quotes (as PIO's ParseFlags does); _shell_token
# re-quotes the spaced token so the shell passes one argv element
expected = (
'"-DGREETING=hello world"' if os.name == "nt" else "'-DGREETING=hello world'"
)
assert compile_flags == [expected]
assert compile_flags == [_shq("-DGREETING=hello world")]
def test_write_project_empty_core_raises(tmp_path: Path) -> None:
@@ -666,7 +668,7 @@ def test_flag_defines_joins_spaced_define() -> None:
def test_ninja_path_escaping() -> None:
"""Build-statement paths and command-line paths escape differently."""
assert arduino8266._e("a b:$c") == "a$ b$:$$c"
assert arduino8266._q("/a b/$x") == '"/a b/$$x"'
assert arduino8266._q("/a b/$x") == _shq("/a b/$$x")
def test_write_project_asm_excludes_non_define_user_flags(tmp_path: Path) -> None:
@@ -821,7 +823,7 @@ def test_write_project_asm_keeps_quoted_defines(tmp_path: Path) -> None:
_set_flags('-DGREETING="hello world"', "-Wno-volatile")
content = _write_ninja(paths)
asflags = next(line for line in content.splitlines() if line.startswith("asflags"))
assert '"-DGREETING=hello world"' in asflags
assert _shq("-DGREETING=hello world") in asflags
assert "-Wno-volatile" not in asflags