mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'fix/windows_tests' into 'master'
ci(tools): Fix Windows pytest_build_system idf_copy gitlinks and log_cli hang See merge request espressif/esp-idf!52181
This commit is contained in:
@@ -67,10 +67,13 @@ def _create_idf_copy_via_worktree(path_from: Path, path_to: Path) -> str:
|
||||
src_submodule = path_from / submodule_rel_path
|
||||
dst_submodule = path_to / submodule_rel_path
|
||||
|
||||
# Only copy if source submodule exists and has content
|
||||
if src_submodule.exists() and any(src_submodule.iterdir()):
|
||||
# Only copy if the source submodule is a populated directory. A gitlink
|
||||
# file or empty dir means the source checkout did not materialize it.
|
||||
if src_submodule.is_dir() and any(src_submodule.iterdir()):
|
||||
logging.debug(f'copying submodule {submodule_rel_path}')
|
||||
# Worktree submodule paths may be gitlink files; rmtree() does not remove those.
|
||||
# Worktree submodule paths are often gitlink files; rmtree() cannot
|
||||
# remove those (even with ignore_errors=True), and copytree() then
|
||||
# leaves a file where CMake expects a directory (e.g. mbedtls/include).
|
||||
if dst_submodule.is_file() or dst_submodule.is_symlink():
|
||||
dst_submodule.unlink()
|
||||
elif dst_submodule.exists():
|
||||
|
||||
@@ -19,6 +19,55 @@ EnvDict = dict[str, str]
|
||||
IdfPyFunc = typing.Callable[..., subprocess.CompletedProcess]
|
||||
|
||||
|
||||
_LOG_ERROR_MARKERS = (
|
||||
'CMake Error',
|
||||
'FAILED:',
|
||||
'fatal error',
|
||||
'ninja: build stopped',
|
||||
'HINT:',
|
||||
)
|
||||
|
||||
|
||||
def _clip_log_output(text: str | None, max_lines: int = 80, max_line_len: int = 400) -> str:
|
||||
"""Last ``max_lines`` of process output for logging, plus failure lines.
|
||||
|
||||
pytest.ini enables ``log_cli``, so ``logging.error(full_stdout)`` after a
|
||||
failed build is one record. On Windows CI that live-log can stall for hours
|
||||
even when the line count is small: CMake's ``-- Component paths:`` line is
|
||||
a single multi-KB (sometimes multi-MB) string.
|
||||
"""
|
||||
if not text:
|
||||
return ''
|
||||
lines = text.splitlines()
|
||||
|
||||
def _short(line: str) -> str:
|
||||
if len(line) <= max_line_len:
|
||||
return line
|
||||
return line[:max_line_len] + f'... [{len(line) - max_line_len} chars omitted]'
|
||||
|
||||
omitted = max(0, len(lines) - max_lines)
|
||||
tail_start = len(lines) - max_lines if omitted else 0
|
||||
tail = lines[tail_start:]
|
||||
|
||||
failures: list[str] = []
|
||||
for idx, line in enumerate(lines):
|
||||
if idx >= tail_start:
|
||||
break
|
||||
if any(marker in line for marker in _LOG_ERROR_MARKERS):
|
||||
failures.append(line)
|
||||
if len(failures) >= 40:
|
||||
break
|
||||
|
||||
parts: list[str] = []
|
||||
if failures:
|
||||
parts.append('[... failure lines ...]')
|
||||
parts.extend(_short(line) for line in failures)
|
||||
if omitted:
|
||||
parts.append(f'[... {omitted} lines omitted ...]')
|
||||
parts.extend(_short(line) for line in tail)
|
||||
return '\n'.join(parts)
|
||||
|
||||
|
||||
def normalize_output(text: str) -> str:
|
||||
"""Collapse all whitespace runs to a single space.
|
||||
|
||||
@@ -108,8 +157,8 @@ def run_idf_py(
|
||||
except subprocess.CalledProcessError as e:
|
||||
logging.error('The following idf.py command has failed: {}'.format(' '.join(cmd)))
|
||||
logging.error(f'Working directory: {workdir}')
|
||||
logging.error(f'Stdout: {e.stdout}')
|
||||
logging.error(f'Stderr: {e.stderr}')
|
||||
logging.error(f'Stdout: {_clip_log_output(e.stdout)}')
|
||||
logging.error(f'Stderr: {_clip_log_output(e.stderr)}')
|
||||
raise
|
||||
|
||||
|
||||
@@ -153,8 +202,8 @@ def run_cmake(
|
||||
except subprocess.CalledProcessError as e:
|
||||
logging.error('The following cmake command has failed: {}'.format(' '.join(cmd)))
|
||||
logging.error(f'Working directory: {workdir}')
|
||||
logging.error(f'Stdout: {e.stdout}')
|
||||
logging.error(f'Stderr: {e.stderr}')
|
||||
logging.error(f'Stdout: {_clip_log_output(e.stdout)}')
|
||||
logging.error(f'Stderr: {_clip_log_output(e.stderr)}')
|
||||
raise
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user