mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
Keep no-op rebuilds quiet
A -n dry-run probe answers 'no work to do' without the real ninja spawn, and running with cwd instead of -C drops the 'Entering directory' banner on real builds too.
This commit is contained in:
@@ -89,16 +89,33 @@ def run_compile(config: ConfigType, verbose: bool) -> int:
|
||||
if ninja_changed or not (build_dir / "compile_commands.json").is_file():
|
||||
_write_compile_commands(paths.ninja, build_dir, env)
|
||||
|
||||
cmd = [str(paths.ninja), "-C", str(build_dir)]
|
||||
cmd = [str(paths.ninja)]
|
||||
if verbose:
|
||||
cmd.append("-v")
|
||||
if jobs := config[CONF_ESPHOME].get(CONF_COMPILE_PROCESS_LIMIT):
|
||||
cmd += ["-j", str(jobs)]
|
||||
|
||||
_LOGGER.debug("Running: %s", " ".join(cmd))
|
||||
rc = subprocess.run(cmd, env=env, check=False, close_fds=False).returncode
|
||||
if rc != 0:
|
||||
return rc
|
||||
# A dry-run probe keeps a no-op rebuild quiet: ninja would only print
|
||||
# "no work to do". cwd instead of -C also drops the "Entering
|
||||
# directory" banner on real builds.
|
||||
probe = subprocess.run(
|
||||
[str(paths.ninja), "-n"],
|
||||
cwd=build_dir,
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
close_fds=False,
|
||||
)
|
||||
if probe.returncode == 0 and "no work to do" in probe.stdout:
|
||||
_LOGGER.debug("ninja: nothing to rebuild")
|
||||
else:
|
||||
_LOGGER.debug("Running: %s", " ".join(cmd))
|
||||
rc = subprocess.run(
|
||||
cmd, cwd=build_dir, env=env, check=False, close_fds=False
|
||||
).returncode
|
||||
if rc != 0:
|
||||
return rc
|
||||
|
||||
_print_size_summary(build_dir, paths)
|
||||
try:
|
||||
|
||||
@@ -92,13 +92,41 @@ def test_run_compile_success(tmp_path: Path) -> None:
|
||||
{CONF_ESPHOME: {CONF_COMPILE_PROCESS_LIMIT: 4}}, verbose=False
|
||||
)
|
||||
assert rc == 0
|
||||
cmd = mock_run.call_args[0][0]
|
||||
# The -n probe runs first, then the real build (cwd, no -C banner)
|
||||
ninja_calls = [c for c in mock_run.call_args_list if "ninja" in str(c[0][0][0])]
|
||||
assert ninja_calls[0][0][0][-1] == "-n"
|
||||
cmd = ninja_calls[1][0][0]
|
||||
assert cmd[-2:] == ["-j", "4"]
|
||||
assert "-C" not in cmd
|
||||
assert ninja_calls[1][1]["cwd"] is not None
|
||||
mock_compdb.assert_called_once()
|
||||
mock_size.assert_called_once()
|
||||
mock_idedata.assert_called_once()
|
||||
|
||||
|
||||
def test_run_compile_noop_skips_the_build_spawn(tmp_path: Path) -> None:
|
||||
"""A no-op rebuild stays quiet: the -n probe answers "no work to do"
|
||||
and the real ninja spawn (and its banner) never happens."""
|
||||
with (
|
||||
patch.object(framework, "check_and_install", return_value=_paths(tmp_path)),
|
||||
patch.object(framework, "get_build_env", return_value={}),
|
||||
patch("esphome.build_gen.arduino8266.write_project"),
|
||||
patch.object(
|
||||
toolchain.subprocess,
|
||||
"run",
|
||||
return_value=MagicMock(returncode=0, stdout="ninja: no work to do.\n"),
|
||||
) as mock_run,
|
||||
patch.object(toolchain, "_write_compile_commands"),
|
||||
patch.object(toolchain, "_print_size_summary"),
|
||||
patch.object(toolchain, "get_idedata"),
|
||||
):
|
||||
rc = toolchain.run_compile({CONF_ESPHOME: {}}, verbose=False)
|
||||
assert rc == 0
|
||||
ninja_calls = [c for c in mock_run.call_args_list if "ninja" in str(c[0][0][0])]
|
||||
assert len(ninja_calls) == 1
|
||||
assert ninja_calls[0][0][0][-1] == "-n"
|
||||
|
||||
|
||||
def test_run_compile_warns_when_idedata_fails(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user