Skip to content

fix: use _rmtree for Windows-safe directory cleanup in downloader#299

Merged
danielmeppiel merged 1 commit intomainfrom
fix/windows-rmtree-readonly
Mar 14, 2026
Merged

fix: use _rmtree for Windows-safe directory cleanup in downloader#299
danielmeppiel merged 1 commit intomainfrom
fix/windows-rmtree-readonly

Conversation

@danielmeppiel
Copy link
Collaborator

Replace bare shutil.rmtree() with existing _rmtree() helper that handles read-only git pack files and Windows file locks. Two code paths in download_package and download_subdirectory_package were using the raw call instead of the helper that was already defined for this exact purpose.

Fixes PermissionError: [WinError 5] Access is denied on .git/objects/pack/*.idx files during dependency update on Windows.

Replace bare shutil.rmtree() calls with the existing _rmtree() helper
that handles read-only git pack files and Windows file locks. The helper
was already defined but not used in two code paths (download_package
and download_subdirectory_package).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 14, 2026 12:24
@danielmeppiel danielmeppiel merged commit 3ffa7df into main Mar 14, 2026
15 checks passed
@danielmeppiel danielmeppiel deleted the fix/windows-rmtree-readonly branch March 14, 2026 12:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the GitHub dependency downloader to use the existing Windows-safe _rmtree() helper instead of shutil.rmtree() when clearing non-empty target directories prior to downloading packages, addressing Windows PermissionError issues on read-only/locked .git pack files.

Changes:

  • Replace shutil.rmtree(target_path) with _rmtree(target_path) in download_subdirectory_package().
  • Replace shutil.rmtree(target_path) with _rmtree(target_path) in download_package().
Comments suppressed due to low confidence (1)

src/apm_cli/deps/github_downloader.py:1413

  • _rmtree() can swallow PermissionError and may leave the directory partially intact (Windows fallback uses ignore_errors=True). Proceeding to mkdir() and then cloning into target_path risks mixing old and new contents without surfacing an error. Suggest making the cleanup strict here (post-check that target_path is removed/empty, or have _rmtree raise on failure after retries) so installs don't silently succeed with stale files.
        if target_path.exists() and any(target_path.iterdir()):
            _rmtree(target_path)
            target_path.mkdir(parents=True, exist_ok=True)

# If target exists and has content, remove it
if target_path.exists() and any(target_path.iterdir()):
shutil.rmtree(target_path)
_rmtree(target_path)
# If directory already exists and has content, remove it
if target_path.exists() and any(target_path.iterdir()):
shutil.rmtree(target_path)
_rmtree(target_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants