Skip to content

Commit f92fbda

Browse files
authored
prevent reinstall of too-esp_install at every run
1 parent 7da0853 commit f92fbda

File tree

1 file changed

+111
-43
lines changed

1 file changed

+111
-43
lines changed

platform.py

Lines changed: 111 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -162,78 +162,139 @@ def packages_dir(self) -> str:
162162

163163
def _check_tl_install_version(self) -> bool:
164164
"""
165-
Prüft ob tool-esp_install in der korrekten Version installiert ist.
166-
Installiert die korrekte Version falls erforderlich.
165+
Check if tool-esp_install is installed in the correct version.
166+
Install the correct version only if version differs.
167+
168+
Returns:
169+
bool: True if correct version is available, False on error
167170
"""
168-
169-
# Hole die erforderliche Version aus platform.json
171+
172+
# Get required version from platform.json
170173
required_version = self.packages.get(tl_install_name, {}).get("version")
171174
if not required_version:
172-
logger.debug(f"Keine Versionsprüfung für {tl_install_name} erforderlich")
175+
logger.debug(f"No version check required for {tl_install_name}")
173176
return True
174-
175-
# Prüfe ob das Tool bereits installiert ist
177+
178+
# Check if tool is already installed
176179
tl_install_path = os.path.join(self.packages_dir, tl_install_name)
177180
package_json_path = os.path.join(tl_install_path, "package.json")
178-
181+
179182
if not os.path.exists(package_json_path):
180-
logger.info(f"{tl_install_name} nicht installiert, installiere Version {required_version}")
183+
logger.info(f"{tl_install_name} not installed, installing version {required_version}")
181184
return self._install_tl_install(required_version)
182-
183-
# Lese die installierte Version
185+
186+
# Read installed version
184187
try:
185188
with open(package_json_path, 'r', encoding='utf-8') as f:
186189
package_data = json.load(f)
187-
190+
188191
installed_version = package_data.get("version")
189192
if not installed_version:
190-
logger.warning(f"Installierte Version für {tl_install_name} unbekannt")
193+
logger.warning(f"Installed version for {tl_install_name} unknown, installing {required_version}")
191194
return self._install_tl_install(required_version)
192-
193-
# Vergleiche Versionen
194-
if installed_version != required_version:
195+
196+
# IMPORTANT: Compare versions correctly
197+
if self._compare_tl_install_versions(installed_version, required_version):
198+
logger.debug(f"{tl_install_name} version {installed_version} is already correctly installed")
199+
# IMPORTANT: Set package as available, but do NOT reinstall
200+
self.packages[tl_install_name]["optional"] = True
201+
return True
202+
else:
195203
logger.info(
196-
f"Versionsfehler für {tl_install_name}: "
197-
f"{installed_version} != {required_version}, installiere korrekte Version"
204+
f"Version mismatch for {tl_install_name}: "
205+
f"installed={installed_version}, required={required_version}, installing correct version"
198206
)
199207
return self._install_tl_install(required_version)
200-
201-
logger.debug(f"{tl_install_name} Version {installed_version} ist korrekt")
202-
return True
203-
208+
204209
except (json.JSONDecodeError, FileNotFoundError) as e:
205-
logger.error(f"Fehler beim Lesen der Paketdaten für {tl_install_name}: {e}")
210+
logger.error(f"Error reading package data for {tl_install_name}: {e}")
206211
return self._install_tl_install(required_version)
207212

213+
def _compare_tl_install_versions(self, installed: str, required: str) -> bool:
214+
"""
215+
Compare installed and required version of tool-esp_install.
216+
217+
Args:
218+
installed: Currently installed version string
219+
required: Required version string from platform.json
220+
221+
Returns:
222+
bool: True if versions match, False otherwise
223+
"""
224+
# For URL-based versions: Extract version string from URL
225+
installed_clean = self._extract_version_from_url(installed)
226+
required_clean = self._extract_version_from_url(required)
227+
228+
logger.debug(f"Version comparison: installed='{installed_clean}' vs required='{required_clean}'")
229+
230+
return installed_clean == required_clean
231+
232+
def _extract_version_from_url(self, version_string: str) -> str:
233+
"""
234+
Extract version information from URL or return version directly.
235+
236+
Args:
237+
version_string: Version string or URL containing version
238+
239+
Returns:
240+
str: Extracted version string
241+
"""
242+
if version_string.startswith(('http://', 'https://')):
243+
# Extract version from URL like: .../v5.1.0/esp_install-v5.1.0.zip
244+
import re
245+
version_match = re.search(r'v(\d+\.\d+\.\d+)', version_string)
246+
if version_match:
247+
return version_match.group(1) # Returns "5.1.0"
248+
else:
249+
# Fallback: Use entire URL
250+
return version_string
251+
else:
252+
# Direct version number
253+
return version_string.strip()
254+
208255
def _install_tl_install(self, version: str) -> bool:
209256
"""
210-
Installiert tool-esp_install in der angegebenen Version.
257+
Install tool-esp_install ONLY when necessary.
258+
259+
Args:
260+
version: Version string or URL to install
261+
262+
Returns:
263+
bool: True if installation successful, False otherwise
211264
"""
212265
tl_install_path = os.path.join(self.packages_dir, tl_install_name)
213-
266+
214267
try:
215-
# Entferne alte Installation
268+
# Remove old installation completely
216269
if os.path.exists(tl_install_path):
217-
logger.info(f"Entferne alte {tl_install_name} Installation")
270+
logger.info(f"Removing old {tl_install_name} installation")
218271
safe_remove_directory(tl_install_path)
219-
220-
# Entferne auch versionierte Verzeichnisse
272+
273+
# Remove versioned directories as well
221274
safe_remove_directory_pattern(self.packages_dir, f"{tl_install_name}@*")
222275
safe_remove_directory_pattern(self.packages_dir, f"{tl_install_name}.*")
223-
224-
# Installiere neue Version
225-
logger.info(f"Installiere {tl_install_name} Version {version}")
276+
277+
# Install new version
278+
logger.info(f"Installing {tl_install_name} version {version}")
279+
280+
# Set package configuration
226281
self.packages[tl_install_name]["optional"] = False
227282
self.packages[tl_install_name]["version"] = version
228-
229-
# Verwende den Package Manager für die Installation
283+
284+
# Install via package manager
230285
pm.install(version)
231-
232-
logger.info(f"{tl_install_name} Version {version} erfolgreich installiert")
233-
return True
234-
286+
287+
# Verify installation
288+
if os.path.exists(os.path.join(tl_install_path, "package.json")):
289+
logger.info(f"{tl_install_name} successfully installed and verified")
290+
self.packages[tl_install_name]["optional"] = True
291+
return True
292+
else:
293+
logger.error(f"{tl_install_name} installation failed - package.json not found")
294+
return False
295+
235296
except Exception as e:
236-
logger.error(f"Fehler bei der Installation von {tl_install_name}: {e}")
297+
logger.error(f"Error installing {tl_install_name}: {e}")
237298
return False
238299

239300
def _get_tool_paths(self, tool_name: str) -> Dict[str, str]:
@@ -418,7 +479,7 @@ def _handle_existing_tool(
418479
return self.install_tool(tool_name, retry_count + 1)
419480

420481
def _configure_arduino_framework(self, frameworks: List[str]) -> None:
421-
"""Configure Arduino framework"""
482+
"""Configure Arduino framework dependencies."""
422483
if "arduino" not in frameworks:
423484
return
424485

@@ -500,17 +561,23 @@ def _configure_mcu_toolchains(
500561
self.install_tool("tool-openocd-esp32")
501562

502563
def _configure_installer(self) -> None:
503-
"""Configure the ESP-IDF tools installer."""
504-
564+
"""Configure the ESP-IDF tools installer with proper version checking."""
565+
566+
# Check version - installs only when needed
505567
if not self._check_tl_install_version():
506568
logger.error("Error during tool-esp_install version check / installation")
507569
return
508570

571+
# Check if idf_tools.py is available
509572
installer_path = os.path.join(
510573
self.packages_dir, tl_install_name, "tools", "idf_tools.py"
511574
)
575+
512576
if os.path.exists(installer_path):
577+
logger.debug(f"{tl_install_name} is available and ready")
513578
self.packages[tl_install_name]["optional"] = True
579+
else:
580+
logger.warning(f"idf_tools.py not found in {installer_path}")
514581

515582
def _install_esptool_package(self) -> None:
516583
"""Install esptool package required for all builds."""
@@ -545,7 +612,7 @@ def _ensure_mklittlefs_version(self) -> None:
545612
os.remove(piopm_path)
546613
logger.info(f"Incompatible mklittlefs version {version} removed (required: 3.x)")
547614
except (json.JSONDecodeError, KeyError) as e:
548-
logger.error(f"Error reading mklittlefs package data: {e}")
615+
logger.error(f"Error reading mklittlefs package {e}")
549616

550617
def _setup_mklittlefs_for_download(self) -> None:
551618
"""Setup mklittlefs for download functionality with version 4.x."""
@@ -797,3 +864,4 @@ def configure_debug_session(self, debug_config):
797864
f'{build_extra_data.get("application_offset", DEFAULT_APP_OFFSET)} verify'
798865
)
799866
debug_config.load_cmds = load_cmds
867+

0 commit comments

Comments
 (0)