mirror of
https://github.com/esphome/esphome.git
synced 2026-10-22 05:46:12 +00:00
[ci] Ignore BUILD_ALWAYS external project byproducts in the idf.py check (#21291)
This commit is contained in:
@@ -51,6 +51,11 @@ def _ninja_logs(skip_bootloader: bool) -> list[str]:
|
||||
|
||||
|
||||
BOOTLOADER_BYPRODUCT = re.compile(r"(^|/build/)bootloader/")
|
||||
# The build step of any CMake ExternalProject. One with BUILD_ALWAYS (ESP-IDF's
|
||||
# ulp_embed_binary) re-runs on every build, and ninja re-records all of that
|
||||
# edge's byproducts with the new end time even though the files are untouched.
|
||||
# Real work on them still changes the hashed firmware.
|
||||
EXTERNAL_PROJECT_BUILD_STAMP = re.compile(r"-stamp/[^/]+-build$")
|
||||
MACRO_CHANGED = (
|
||||
"IDF changed __build_process_project_includes; update "
|
||||
"IDF_BOOTLOADER_OVERRIDE in esphome/build_gen/espidf.py"
|
||||
@@ -96,10 +101,24 @@ def _ninja_mtimes(build_path: Path, logs: list[str]) -> dict[tuple[str, str], st
|
||||
for name in logs:
|
||||
log = build_path / name
|
||||
lines = log.read_text(encoding="utf-8").splitlines() if log.is_file() else []
|
||||
for fields in (line.split("\t") for line in lines if not line.startswith("#")):
|
||||
if len(fields) >= 4 and (
|
||||
name != TOP_NINJA_LOG or not BOOTLOADER_BYPRODUCT.search(fields[3])
|
||||
):
|
||||
rows = [
|
||||
fields
|
||||
for fields in (
|
||||
line.split("\t") for line in lines if not line.startswith("#")
|
||||
)
|
||||
if len(fields) >= 5
|
||||
]
|
||||
# Every output of an edge shares its command hash, so the stamp names
|
||||
# the whole external project group.
|
||||
external = {
|
||||
fields[4]
|
||||
for fields in rows
|
||||
if EXTERNAL_PROJECT_BUILD_STAMP.search(fields[3])
|
||||
}
|
||||
for fields in rows:
|
||||
if fields[4] in external:
|
||||
continue
|
||||
if name != TOP_NINJA_LOG or not BOOTLOADER_BYPRODUCT.search(fields[3]):
|
||||
mtimes[name, fields[3]] = fields[2]
|
||||
return mtimes
|
||||
|
||||
|
||||
@@ -156,6 +156,34 @@ def test_check_reports_changed_files_and_rebuilt_outputs(tmp_path: Path) -> None
|
||||
]
|
||||
|
||||
|
||||
def test_check_ignores_a_build_always_external_project(tmp_path: Path) -> None:
|
||||
"""ESP-IDF's ULP app is an ExternalProject with BUILD_ALWAYS: its step
|
||||
re-runs on every build and ninja re-records its byproducts with the new
|
||||
end time, so a moved mtime on that edge is not work. The same outputs
|
||||
under another edge still are."""
|
||||
tree = _make_tree(tmp_path)
|
||||
build = tree / "build"
|
||||
ulp = (
|
||||
"1\t2\t{t}\tesp-idf/src/ulp_main-prefix/src/ulp_main-stamp/ulp_main-build\tab\n"
|
||||
"1\t2\t{t}\tesp-idf/src/ulp_main/ulp_main.bin\tab\n"
|
||||
"1\t2\t{t}\tesp-idf/src/ulp_main/ulp_main.ld\tab\n"
|
||||
)
|
||||
(build / ".ninja_log").write_text(
|
||||
"# ninja log v7\n1\t2\t10\tesp-idf/a.obj\t0\n"
|
||||
"1\t2\t10\tesp-idf/other.ld\tcd\n" + ulp.format(t=10)
|
||||
)
|
||||
|
||||
def rerun(cmd: list[str]) -> None:
|
||||
if cmd[-1] == "build":
|
||||
(build / ".ninja_log").write_text(
|
||||
"# ninja log v7\n1\t2\t10\tesp-idf/a.obj\t0\n"
|
||||
"3\t4\t20\tesp-idf/other.ld\tcd\n" + ulp.format(t=30)
|
||||
)
|
||||
|
||||
problems, _ = _run_check(tree, rerun)
|
||||
assert problems == ["idf.py rebuilt esp-idf/other.ld"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("after_build", "problem"),
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user