|
45 | 45 |
|
46 | 46 |
|
47 | 47 | def download_raylib(platform, ext): |
48 | | - if not os.path.exists(platform): |
| 48 | + """Download and extract raylib with proper error handling for CI environments.""" |
| 49 | + import tempfile |
| 50 | + import time |
| 51 | + |
| 52 | + # Use a lock file to prevent concurrent downloads |
| 53 | + lock_file = platform + ".lock" |
| 54 | + max_wait = 60 # seconds |
| 55 | + start_time = time.time() |
| 56 | + |
| 57 | + # Wait for any ongoing download to complete |
| 58 | + while os.path.exists(lock_file) and (time.time() - start_time) < max_wait: |
| 59 | + print(f"Waiting for another process to finish downloading {platform}...") |
| 60 | + time.sleep(1) |
| 61 | + |
| 62 | + # Check if already successfully downloaded |
| 63 | + success_marker = platform + ".success" |
| 64 | + if os.path.exists(success_marker) and os.path.exists(platform): |
| 65 | + print(f"{platform} already downloaded successfully") |
| 66 | + return |
| 67 | + |
| 68 | + # Clean up any partial downloads |
| 69 | + if os.path.exists(platform) and not os.path.exists(success_marker): |
| 70 | + print(f"Cleaning up partial download of {platform}") |
| 71 | + shutil.rmtree(platform, ignore_errors=True) |
| 72 | + |
| 73 | + # Create lock file |
| 74 | + try: |
| 75 | + with open(lock_file, "w") as f: |
| 76 | + f.write(str(os.getpid())) |
| 77 | + |
| 78 | + # Download to a temporary file first |
| 79 | + temp_file = None |
49 | 80 | try: |
50 | 81 | print(f"Downloading {platform}{ext}...") |
51 | | - urllib.request.urlretrieve(RAYLIB_URL + platform + ext, platform + ext) |
| 82 | + temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=ext) |
| 83 | + urllib.request.urlretrieve(RAYLIB_URL + platform + ext, temp_file.name) |
| 84 | + temp_file.close() |
| 85 | + |
| 86 | + # Extract to a temporary directory first |
| 87 | + temp_dir = tempfile.mkdtemp() |
52 | 88 | if ext == ".zip": |
53 | | - with zipfile.ZipFile(platform + ext, "r") as zip_ref: |
54 | | - zip_ref.extractall() |
| 89 | + with zipfile.ZipFile(temp_file.name, "r") as zip_ref: |
| 90 | + zip_ref.extractall(temp_dir) |
| 91 | + else: |
| 92 | + with tarfile.open(temp_file.name, "r") as tar_ref: |
| 93 | + tar_ref.extractall(temp_dir) |
| 94 | + |
| 95 | + # Move the extracted content to the final location |
| 96 | + extracted_dir = os.path.join(temp_dir, platform) |
| 97 | + if os.path.exists(extracted_dir): |
| 98 | + shutil.move(extracted_dir, platform) |
55 | 99 | else: |
56 | | - with tarfile.open(platform + ext, "r") as tar_ref: |
57 | | - tar_ref.extractall() |
| 100 | + # Sometimes the archive extracts directly without a parent folder |
| 101 | + shutil.move(temp_dir, platform) |
58 | 102 |
|
59 | | - os.remove(platform + ext) |
60 | | - # Create the include directory if it doesn't exist |
| 103 | + # Download rlights.h |
61 | 104 | include_dir = os.path.join(platform, "include") |
62 | 105 | os.makedirs(include_dir, exist_ok=True) |
63 | 106 | urllib.request.urlretrieve( |
64 | 107 | RLIGHTS_URL, os.path.join(include_dir, "rlights.h") |
65 | 108 | ) |
| 109 | + |
| 110 | + # Mark as successfully downloaded |
| 111 | + with open(success_marker, "w") as f: |
| 112 | + f.write("success") |
| 113 | + |
66 | 114 | print(f"Successfully downloaded and extracted {platform}") |
| 115 | + |
67 | 116 | except Exception as e: |
68 | 117 | print(f"Error downloading {platform}: {e}") |
| 118 | + # Clean up on error |
| 119 | + if os.path.exists(platform): |
| 120 | + shutil.rmtree(platform, ignore_errors=True) |
69 | 121 | raise |
| 122 | + finally: |
| 123 | + # Clean up temp files |
| 124 | + if temp_file and os.path.exists(temp_file.name): |
| 125 | + os.unlink(temp_file.name) |
| 126 | + if "temp_dir" in locals() and os.path.exists(temp_dir): |
| 127 | + shutil.rmtree(temp_dir, ignore_errors=True) |
| 128 | + |
| 129 | + finally: |
| 130 | + # Remove lock file |
| 131 | + if os.path.exists(lock_file): |
| 132 | + try: |
| 133 | + os.unlink(lock_file) |
| 134 | + except: |
| 135 | + pass |
70 | 136 |
|
71 | 137 |
|
72 | 138 | download_raylib("raylib-5.5_webassembly", ".zip") |
|
0 commit comments