Skip to content

clean up packages dir with every tool version check #238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 31, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 37 additions & 25 deletions platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def _extract_version_from_url(self, version_string: str) -> str:
def _install_tl_install(self, version: str) -> bool:
"""
Install tool-esp_install ONLY when necessary
and handles backwards compability for tl-install.
and handles backwards compatibility for tl-install.

Args:
version: Version string or URL to install
Expand All @@ -298,15 +298,15 @@ def _install_tl_install(self, version: str) -> bool:
self.packages[tl_install_name]["optional"] = False
self.packages[tl_install_name]["version"] = version
pm.install(version)
# Ensure backward compability by removing pio install status indicator
# Ensure backward compatibility by removing pio install status indicator
tl_piopm_path = os.path.join(tl_install_path, ".piopm")
safe_remove_file(tl_piopm_path)

if os.path.exists(os.path.join(tl_install_path, "package.json")):
logger.info(f"{tl_install_name} successfully installed and verified")
self.packages[tl_install_name]["optional"] = True

# Handle old tl-install to keep backwards compability
# Handle old tl-install to keep backwards compatibility
if old_tl_install_exists:
# Copy tool-esp_install content to tl-install location
if safe_copy_directory(tl_install_path, old_tl_install_path):
Expand All @@ -322,23 +322,39 @@ def _install_tl_install(self, version: str) -> bool:
logger.error(f"Error installing {tl_install_name}: {e}")
return False

def _cleanup_versioned_tool_directories(self, tool_name: str) -> None:
"""
Clean up versioned tool directories containing '@' or version suffixes.
This function should be called during every tool version check.

Args:
tool_name: Name of the tool to clean up
"""
if not os.path.exists(self.packages_dir) or not os.path.isdir(self.packages_dir):
return

try:
# Remove directories with '@' in their name (e.g., tool-name@version, tool-name@src)
safe_remove_directory_pattern(self.packages_dir, f"{tool_name}@*")

# Remove directories with version suffixes (e.g., tool-name.12345)
safe_remove_directory_pattern(self.packages_dir, f"{tool_name}.*")

# Also check for any directory that starts with tool_name and contains '@'
for item in os.listdir(self.packages_dir):
if item.startswith(tool_name) and '@' in item:
item_path = os.path.join(self.packages_dir, item)
if os.path.isdir(item_path):
safe_remove_directory(item_path)
logger.debug(f"Removed versioned directory: {item_path}")

except OSError as e:
logger.error(f"Error cleaning up versioned directories for {tool_name}: {e}")

def _get_tool_paths(self, tool_name: str) -> Dict[str, str]:
"""Get centralized path calculation for tools with caching."""
if tool_name not in self._tools_cache:
tool_path = os.path.join(self.packages_dir, tool_name)
# Remove all directories containing '@' in their name
try:
if os.path.exists(self.packages_dir) and os.path.isdir(self.packages_dir):
for item in os.listdir(self.packages_dir):
if '@' in item and item.startswith(tool_name):
item_path = os.path.join(self.packages_dir, item)
if os.path.isdir(item_path):
safe_remove_directory(item_path)
logger.debug(f"Removed directory with '@' in name: {item_path}")

except OSError as e:
logger.error(f"Error scanning packages directory for '@' directories: {e}")

self._tools_cache[tool_name] = {
'tool_path': tool_path,
Expand Down Expand Up @@ -398,6 +414,9 @@ def _run_idf_tools_install(self, tools_json_path: str, idf_tools_path: str) -> b

def _check_tool_version(self, tool_name: str) -> bool:
"""Check if the installed tool version matches the required version."""
# Clean up versioned directories FIRST, before any version checks
self._cleanup_versioned_tool_directories(tool_name)

paths = self._get_tool_paths(tool_name)

try:
Expand Down Expand Up @@ -489,17 +508,10 @@ def _handle_existing_tool(
logger.debug(f"Tool {tool_name} found with correct version")
return True

# Wrong version, reinstall - remove similar paths too
# Wrong version, reinstall - cleanup is already done in _check_tool_version
logger.info(f"Reinstalling {tool_name} due to version mismatch")

tool_base_name = os.path.basename(paths['tool_path'])
packages_dir = os.path.dirname(paths['tool_path'])

# Remove similar directories with version suffixes FIRST (e.g., xtensa@src, xtensa.12232)
safe_remove_directory_pattern(packages_dir, f"{tool_base_name}@*")
safe_remove_directory_pattern(packages_dir, f"{tool_base_name}.*")

# Then remove the main tool directory (if it still exists)

# Remove the main tool directory (if it still exists after cleanup)
safe_remove_directory(paths['tool_path'])

return self.install_tool(tool_name, retry_count + 1)
Expand Down