@@ -273,7 +273,7 @@ def _extract_version_from_url(self, version_string: str) -> str:
273
273
def _install_tl_install (self , version : str ) -> bool :
274
274
"""
275
275
Install tool-esp_install ONLY when necessary
276
- and handles backwards compability for tl-install.
276
+ and handles backwards compatibility for tl-install.
277
277
278
278
Args:
279
279
version: Version string or URL to install
@@ -298,15 +298,15 @@ def _install_tl_install(self, version: str) -> bool:
298
298
self .packages [tl_install_name ]["optional" ] = False
299
299
self .packages [tl_install_name ]["version" ] = version
300
300
pm .install (version )
301
- # Ensure backward compability by removing pio install status indicator
301
+ # Ensure backward compatibility by removing pio install status indicator
302
302
tl_piopm_path = os .path .join (tl_install_path , ".piopm" )
303
303
safe_remove_file (tl_piopm_path )
304
304
305
305
if os .path .exists (os .path .join (tl_install_path , "package.json" )):
306
306
logger .info (f"{ tl_install_name } successfully installed and verified" )
307
307
self .packages [tl_install_name ]["optional" ] = True
308
308
309
- # Handle old tl-install to keep backwards compability
309
+ # Handle old tl-install to keep backwards compatibility
310
310
if old_tl_install_exists :
311
311
# Copy tool-esp_install content to tl-install location
312
312
if safe_copy_directory (tl_install_path , old_tl_install_path ):
@@ -322,23 +322,39 @@ def _install_tl_install(self, version: str) -> bool:
322
322
logger .error (f"Error installing { tl_install_name } : { e } " )
323
323
return False
324
324
325
+ def _cleanup_versioned_tool_directories (self , tool_name : str ) -> None :
326
+ """
327
+ Clean up versioned tool directories containing '@' or version suffixes.
328
+ This function should be called during every tool version check.
329
+
330
+ Args:
331
+ tool_name: Name of the tool to clean up
332
+ """
333
+ if not os .path .exists (self .packages_dir ) or not os .path .isdir (self .packages_dir ):
334
+ return
335
+
336
+ try :
337
+ # Remove directories with '@' in their name (e.g., tool-name@version, tool-name@src)
338
+ safe_remove_directory_pattern (self .packages_dir , f"{ tool_name } @*" )
339
+
340
+ # Remove directories with version suffixes (e.g., tool-name.12345)
341
+ safe_remove_directory_pattern (self .packages_dir , f"{ tool_name } .*" )
342
+
343
+ # Also check for any directory that starts with tool_name and contains '@'
344
+ for item in os .listdir (self .packages_dir ):
345
+ if item .startswith (tool_name ) and '@' in item :
346
+ item_path = os .path .join (self .packages_dir , item )
347
+ if os .path .isdir (item_path ):
348
+ safe_remove_directory (item_path )
349
+ logger .debug (f"Removed versioned directory: { item_path } " )
350
+
351
+ except OSError as e :
352
+ logger .error (f"Error cleaning up versioned directories for { tool_name } : { e } " )
325
353
326
354
def _get_tool_paths (self , tool_name : str ) -> Dict [str , str ]:
327
355
"""Get centralized path calculation for tools with caching."""
328
356
if tool_name not in self ._tools_cache :
329
357
tool_path = os .path .join (self .packages_dir , tool_name )
330
- # Remove all directories containing '@' in their name
331
- try :
332
- if os .path .exists (self .packages_dir ) and os .path .isdir (self .packages_dir ):
333
- for item in os .listdir (self .packages_dir ):
334
- if '@' in item and item .startswith (tool_name ):
335
- item_path = os .path .join (self .packages_dir , item )
336
- if os .path .isdir (item_path ):
337
- safe_remove_directory (item_path )
338
- logger .debug (f"Removed directory with '@' in name: { item_path } " )
339
-
340
- except OSError as e :
341
- logger .error (f"Error scanning packages directory for '@' directories: { e } " )
342
358
343
359
self ._tools_cache [tool_name ] = {
344
360
'tool_path' : tool_path ,
@@ -398,6 +414,9 @@ def _run_idf_tools_install(self, tools_json_path: str, idf_tools_path: str) -> b
398
414
399
415
def _check_tool_version (self , tool_name : str ) -> bool :
400
416
"""Check if the installed tool version matches the required version."""
417
+ # Clean up versioned directories FIRST, before any version checks
418
+ self ._cleanup_versioned_tool_directories (tool_name )
419
+
401
420
paths = self ._get_tool_paths (tool_name )
402
421
403
422
try :
@@ -489,17 +508,10 @@ def _handle_existing_tool(
489
508
logger .debug (f"Tool { tool_name } found with correct version" )
490
509
return True
491
510
492
- # Wrong version, reinstall - remove similar paths too
511
+ # Wrong version, reinstall - cleanup is already done in _check_tool_version
493
512
logger .info (f"Reinstalling { tool_name } due to version mismatch" )
494
-
495
- tool_base_name = os .path .basename (paths ['tool_path' ])
496
- packages_dir = os .path .dirname (paths ['tool_path' ])
497
-
498
- # Remove similar directories with version suffixes FIRST (e.g., xtensa@src, xtensa.12232)
499
- safe_remove_directory_pattern (packages_dir , f"{ tool_base_name } @*" )
500
- safe_remove_directory_pattern (packages_dir , f"{ tool_base_name } .*" )
501
-
502
- # Then remove the main tool directory (if it still exists)
513
+
514
+ # Remove the main tool directory (if it still exists after cleanup)
503
515
safe_remove_directory (paths ['tool_path' ])
504
516
505
517
return self .install_tool (tool_name , retry_count + 1 )
0 commit comments