Copy boards directory to the build directory.
(project_root: Path, build_dir: Path)
| 294 | |
| 295 | |
| 296 | def copy_boards_directory(project_root: Path, build_dir: Path) -> bool: |
| 297 | """Copy boards directory to the build directory.""" |
| 298 | boards_src = project_root / "ci" / "boards" |
| 299 | boards_dst = build_dir / "boards" |
| 300 | |
| 301 | if not boards_src.exists(): |
| 302 | warnings.warn(f"Boards directory not found: {boards_src}") |
| 303 | return False |
| 304 | |
| 305 | try: |
| 306 | # Ensure target directory exists for dirsync |
| 307 | boards_dst.mkdir(parents=True, exist_ok=True) |
| 308 | |
| 309 | # Use sync for better caching - purge=True removes extra files |
| 310 | # Only pass content=True in Docker environments (content-based comparison) |
| 311 | # On other systems, use default behavior (timestamp/size) by omitting the parameter |
| 312 | # On Windows, add retry logic for file locking issues |
| 313 | max_retries = 3 if sys.platform == "win32" else 1 |
| 314 | retry_delay = 0.5 # seconds |
| 315 | |
| 316 | for attempt in range(max_retries): |
| 317 | try: |
| 318 | _is_docker = os.environ.get("DOCKER_CONTAINER", "") != "" |
| 319 | _scandir_sync( |
| 320 | str(boards_src), |
| 321 | str(boards_dst), |
| 322 | purge=True, |
| 323 | content=_is_docker, |
| 324 | ) |
| 325 | break # Success, exit retry loop |
| 326 | except OSError as e: |
| 327 | # Handle Windows file locking errors (WinError 32) |
| 328 | if sys.platform == "win32" and attempt < max_retries - 1: |
| 329 | print( |
| 330 | f"File access error during boards sync, retrying ({attempt + 1}/{max_retries}): {e}" |
| 331 | ) |
| 332 | time.sleep(retry_delay) |
| 333 | else: |
| 334 | raise |
| 335 | except KeyboardInterrupt as ki: |
| 336 | handle_keyboard_interrupt(ki) |
| 337 | raise |
| 338 | except Exception as e: |
| 339 | warnings.warn(f"Failed to sync boards directory: {e}") |
| 340 | return False |
| 341 | |
| 342 | return True |
| 343 | |
| 344 | |
| 345 | def copy_fastled_library(project_root: Path, build_dir: Path) -> bool: |
no test coverage detected