@@ -162,78 +162,139 @@ def packages_dir(self) -> str:
162
162
163
163
def _check_tl_install_version (self ) -> bool :
164
164
"""
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
167
170
"""
168
-
169
- # Hole die erforderliche Version aus platform.json
171
+
172
+ # Get required version from platform.json
170
173
required_version = self .packages .get (tl_install_name , {}).get ("version" )
171
174
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 } " )
173
176
return True
174
-
175
- # Prüfe ob das Tool bereits installiert ist
177
+
178
+ # Check if tool is already installed
176
179
tl_install_path = os .path .join (self .packages_dir , tl_install_name )
177
180
package_json_path = os .path .join (tl_install_path , "package.json" )
178
-
181
+
179
182
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 } " )
181
184
return self ._install_tl_install (required_version )
182
-
183
- # Lese die installierte Version
185
+
186
+ # Read installed version
184
187
try :
185
188
with open (package_json_path , 'r' , encoding = 'utf-8' ) as f :
186
189
package_data = json .load (f )
187
-
190
+
188
191
installed_version = package_data .get ("version" )
189
192
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 } " )
191
194
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 :
195
203
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 "
198
206
)
199
207
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
+
204
209
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 } " )
206
211
return self ._install_tl_install (required_version )
207
212
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
+
208
255
def _install_tl_install (self , version : str ) -> bool :
209
256
"""
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
211
264
"""
212
265
tl_install_path = os .path .join (self .packages_dir , tl_install_name )
213
-
266
+
214
267
try :
215
- # Entferne alte Installation
268
+ # Remove old installation completely
216
269
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 " )
218
271
safe_remove_directory (tl_install_path )
219
-
220
- # Entferne auch versionierte Verzeichnisse
272
+
273
+ # Remove versioned directories as well
221
274
safe_remove_directory_pattern (self .packages_dir , f"{ tl_install_name } @*" )
222
275
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
226
281
self .packages [tl_install_name ]["optional" ] = False
227
282
self .packages [tl_install_name ]["version" ] = version
228
-
229
- # Verwende den Package Manager für die Installation
283
+
284
+ # Install via package manager
230
285
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
+
235
296
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 } " )
237
298
return False
238
299
239
300
def _get_tool_paths (self , tool_name : str ) -> Dict [str , str ]:
@@ -418,7 +479,7 @@ def _handle_existing_tool(
418
479
return self .install_tool (tool_name , retry_count + 1 )
419
480
420
481
def _configure_arduino_framework (self , frameworks : List [str ]) -> None :
421
- """Configure Arduino framework"""
482
+ """Configure Arduino framework dependencies. """
422
483
if "arduino" not in frameworks :
423
484
return
424
485
@@ -500,17 +561,23 @@ def _configure_mcu_toolchains(
500
561
self .install_tool ("tool-openocd-esp32" )
501
562
502
563
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
505
567
if not self ._check_tl_install_version ():
506
568
logger .error ("Error during tool-esp_install version check / installation" )
507
569
return
508
570
571
+ # Check if idf_tools.py is available
509
572
installer_path = os .path .join (
510
573
self .packages_dir , tl_install_name , "tools" , "idf_tools.py"
511
574
)
575
+
512
576
if os .path .exists (installer_path ):
577
+ logger .debug (f"{ tl_install_name } is available and ready" )
513
578
self .packages [tl_install_name ]["optional" ] = True
579
+ else :
580
+ logger .warning (f"idf_tools.py not found in { installer_path } " )
514
581
515
582
def _install_esptool_package (self ) -> None :
516
583
"""Install esptool package required for all builds."""
@@ -545,7 +612,7 @@ def _ensure_mklittlefs_version(self) -> None:
545
612
os .remove (piopm_path )
546
613
logger .info (f"Incompatible mklittlefs version { version } removed (required: 3.x)" )
547
614
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 } " )
549
616
550
617
def _setup_mklittlefs_for_download (self ) -> None :
551
618
"""Setup mklittlefs for download functionality with version 4.x."""
@@ -797,3 +864,4 @@ def configure_debug_session(self, debug_config):
797
864
f'{ build_extra_data .get ("application_offset" , DEFAULT_APP_OFFSET )} verify'
798
865
)
799
866
debug_config .load_cmds = load_cmds
867
+
0 commit comments