ci(tools): Fix worktree submodule copy of gitlink files

This commit is contained in:
Jakub Kocka
2026-08-17 13:19:20 +02:00
committed by Fu Hanxi
parent eaeaf2f87a
commit e962d4e60f

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import datetime
import logging
@@ -11,10 +11,10 @@ from tempfile import mkdtemp
import pytest
from _pytest.fixtures import FixtureRequest
from test_build_system_helpers import EnvDict
from test_build_system_helpers import EXT_IDF_PATH
from test_build_system_helpers import get_idf_build_env
from test_build_system_helpers import EnvDict
from test_build_system_helpers import IdfPyFunc
from test_build_system_helpers import get_idf_build_env
from test_build_system_helpers import run_idf_py
@@ -66,10 +66,11 @@ def _create_idf_copy_via_worktree(path_from: Path, path_to: Path) -> str:
# Only copy if source submodule exists and has content
if src_submodule.exists() and any(src_submodule.iterdir()):
logging.debug(f'copying submodule {submodule_rel_path}')
# Remove the empty directory created by worktree
if dst_submodule.exists():
shutil.rmtree(dst_submodule, ignore_errors=True)
# Copy the submodule content
# Worktree submodule paths may be gitlink files; rmtree() does not remove those.
if dst_submodule.is_file() or dst_submodule.is_symlink():
dst_submodule.unlink()
elif dst_submodule.exists():
shutil.rmtree(dst_submodule)
shutil.copytree(src_submodule, dst_submodule, symlinks=True, ignore=shutil.ignore_patterns('.git'))
# Match old shutil-based idf_copy: no top-level .git (see docstring above).
@@ -131,13 +132,15 @@ def should_clean_test_dir(request: FixtureRequest) -> bool:
def pytest_addoption(parser: pytest.Parser) -> None:
parser.addoption(
'--work-dir', action='store', default=None,
help='Directory for temporary files. If not specified, an OS-specific '
'temporary directory will be used.'
'--work-dir',
action='store',
default=None,
help='Directory for temporary files. If not specified, an OS-specific temporary directory will be used.',
)
parser.addoption(
'--cleanup-idf-copy', action='store_true',
help='Always clean up the IDF copy after the test. By default, the copy is cleaned up only if the test passes.'
'--cleanup-idf-copy',
action='store_true',
help='Always clean up the IDF copy after the test. By default, the copy is cleaned up only if the test passes.',
)
@@ -166,7 +169,9 @@ def _session_work_dir(request: FixtureRequest) -> typing.Generator[typing.Tuple[
@pytest.fixture(name='func_work_dir', autouse=True)
def work_dir(request: FixtureRequest, _session_work_dir: typing.Tuple[Path, bool]) -> typing.Generator[Path, None, None]:
def work_dir(
request: FixtureRequest, _session_work_dir: typing.Tuple[Path, bool]
) -> typing.Generator[Path, None, None]:
session_work_dir, is_temp_dir = _session_work_dir
if request._pyfuncitem.keywords.get('force_temp_work_dir') and not is_temp_dir:
@@ -209,7 +214,9 @@ def test_app_copy(func_work_dir: Path, request: FixtureRequest) -> typing.Genera
ignore = shutil.ignore_patterns(
path_to.name,
# also ignore files which may be present in the work directory
'build', 'sdkconfig')
'build',
'sdkconfig',
)
logging.debug(f'copying {path_from} to {path_to}')
shutil.copytree(path_from, path_to, ignore=ignore, symlinks=True)
@@ -222,7 +229,7 @@ def test_app_copy(func_work_dir: Path, request: FixtureRequest) -> typing.Genera
os.chdir(old_cwd)
if should_clean_test_dir(request):
logging.debug('cleaning up work directory after a successful test: {}'.format(path_to))
logging.debug(f'cleaning up work directory after a successful test: {path_to}')
shutil.rmtree(path_to, ignore_errors=True)
@@ -236,8 +243,22 @@ def test_git_template_app(func_work_dir: Path, request: FixtureRequest) -> typin
logging.debug(f'cloning git-template app to {path_to}')
path_to.mkdir()
# No need to clone full repository, just a single master branch
subprocess.run(['git', 'clone', '--single-branch', '-b', 'master', '--depth', '1', 'https://github.com/espressif/esp-idf-template.git', '.'],
cwd=path_to, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run( # noqa: UP022
[
'git',
'clone',
'--single-branch',
'-b',
'master',
'--depth',
'1',
'https://github.com/espressif/esp-idf-template.git',
'.',
],
cwd=path_to,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
old_cwd = Path.cwd()
os.chdir(path_to)
@@ -247,7 +268,7 @@ def test_git_template_app(func_work_dir: Path, request: FixtureRequest) -> typin
os.chdir(old_cwd)
if should_clean_test_dir(request):
logging.debug('cleaning up work directory after a successful test: {}'.format(path_to))
logging.debug(f'cleaning up work directory after a successful test: {path_to}')
shutil.rmtree(path_to, ignore_errors=True)
@@ -305,4 +326,5 @@ def fixture_default_idf_env() -> EnvDict:
def idf_py(default_idf_env: EnvDict) -> IdfPyFunc:
def result(*args: str, check: bool = True, input_str: typing.Optional[str] = None) -> subprocess.CompletedProcess:
return run_idf_py(*args, env=default_idf_env, workdir=os.getcwd(), check=check, input_str=input_str) # type: ignore
return result