MCPcopy Create free account
hub / github.com/FastLED/FastLED / copy_fastled_library

Function copy_fastled_library

ci/compiler/source_manager.py:345–440  ·  view source on GitHub ↗

Copy FastLED library to build directory with proper library.json structure.

(project_root: Path, build_dir: Path)

Source from the content-addressed store, hash-verified

343
344
345def copy_fastled_library(project_root: Path, build_dir: Path) -> bool:
346 """Copy FastLED library to build directory with proper library.json structure."""
347 lib_dir = build_dir / "lib" / "FastLED"
348 lib_parent = build_dir / "lib"
349
350 # Copy src/ directory into lib/FastLED using dirsync for better caching
351 fastled_src_path = project_root / "src"
352 try:
353 # Create lib directory if it doesn't exist
354 lib_parent.mkdir(parents=True, exist_ok=True)
355
356 # Try to remove existing FastLED directory if it exists
357 # On Windows, files may be locked by antivirus or explorer, so handle gracefully
358 if lib_dir.exists():
359 if lib_dir.is_symlink():
360 lib_dir.unlink()
361 else:
362 # On Windows, add retry logic for rmtree since files may still be locked
363 # This can happen when antivirus software or explorer.exe still has handles open
364 max_rmtree_retries = 5 if sys.platform == "win32" else 1
365 rmtree_delay_ms = 100 if sys.platform == "win32" else 0
366
367 for rmtree_attempt in range(max_rmtree_retries):
368 try:
369 shutil.rmtree(lib_dir)
370 break # Success
371 except OSError as e:
372 if (
373 sys.platform == "win32"
374 and rmtree_attempt < max_rmtree_retries - 1
375 ):
376 delay_seconds = rmtree_delay_ms / 1000.0
377 time.sleep(delay_seconds)
378 elif rmtree_attempt == max_rmtree_retries - 1:
379 # On last attempt failure, just warn and continue with update instead
380 print(
381 f"Warning: Could not remove old FastLED library, will update existing: {e}"
382 )
383 break
384
385 # Ensure target directory exists for dirsync
386 lib_dir.mkdir(parents=True, exist_ok=True)
387
388 # Use dirsync.sync for efficient incremental synchronization
389 # Only pass content=True in Docker environments (content-based comparison)
390 # On other systems, use default behavior (timestamp/size) by omitting the parameter
391 # On Windows, add retry logic for file locking issues
392 max_retries = 3 if sys.platform == "win32" else 1
393 retry_delay = 0.5 # seconds
394
395 for attempt in range(max_retries):
396 try:
397 _is_docker = os.environ.get("DOCKER_CONTAINER", "") != ""
398 _scandir_sync(
399 str(fastled_src_path),
400 str(lib_dir),
401 purge=True,
402 content=_is_docker,

Callers 1

_init_platformio_buildFunction · 0.90

Calls 5

_scandir_syncFunction · 0.85
unlinkMethod · 0.80
printFunction · 0.50
getMethod · 0.45

Tested by

no test coverage detected