Skip to content

[Repo Assist] fix(uninstall): clean up empty wsl\ parent dir after VHD removal#472

Draft
github-actions[bot] wants to merge 1 commit into
masterfrom
repo-assist/fix-uninstall-empty-dirs-467-d90059e340ce92f0
Draft

[Repo Assist] fix(uninstall): clean up empty wsl\ parent dir after VHD removal#472
github-actions[bot] wants to merge 1 commit into
masterfrom
repo-assist/fix-uninstall-empty-dirs-467-d90059e340ce92f0

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

After the WSL uninstall flow removes the distro-specific VHD directory (%LOCALAPPDATA%\OpenClawTray\wsl\OpenClawGateway\), the parent wsl\ directory was left as an empty orphan. This prevented the MSIX uninstaller from removing %LOCALAPPDATA%\OpenClawTray\ cleanly.

Closes #467

Root Cause

Step 5a in LocalGatewayUninstall.cs calls Directory.Delete(vhdDir, recursive: true) on the distro-specific subdirectory but does not clean up the wsl\ parent. After all 13 steps complete, the empty wsl\ directory holds %LOCALAPPDATA%\OpenClawTray\ open, so it survives MSIX uninstall.

Fix

  • Step 5b added to LocalGatewayUninstall.cs: after VHD parent dir cleanup, delete the wsl\ parent directory if it is empty. Non-empty wsl\ dirs (e.g. other distros still present) are preserved safely.
  • WslParentDirAbsent postcondition added; included in AllRequiredPostconditionsMet and AppendPostconditionErrors.
  • validate-wsl-gateway-uninstall.ps1 updated: added $wslParentDirPath, wsl_parent_dir_absent to postconditions and required-checks list, and wsl_parent_dir_exists in pre-state snapshot.
  • 3 unit tests added covering empty→deleted, non-empty→skipped, and already-absent→skipped.

Trade-offs

  • The wsl\ cleanup is guarded with EnumerateFileSystemEntries(...).Any() — it will not delete the directory if any other files or subdirectories remain, so this is safe for machines that have other WSL distros under %LOCALAPPDATA%\OpenClawTray\wsl\.
  • The %LOCALAPPDATA%\OpenClawTray\ root directory itself is left for the MSIX uninstaller to clean up once empty, which is consistent with the existing pattern.

Test Status

dotnet build tests/OpenClaw.Tray.Tests/ — Build succeeded, 0 warnings
dotnet test tests/OpenClaw.Tray.Tests/ -- no-restore
  Failed: 9 (all pre-existing Linux-environment failures)
  Passed: 1065
  Skipped: 51 (includes 3 new WslParentDirCleanup_* tests, skipped on Linux per [WindowsFact])

dotnet test tests/OpenClaw.Shared.Tests/ -- no-restore
  Failed: 7 (all pre-existing)
  Passed: 1796

All failures are pre-existing. No regressions introduced.

Generated by 🤖 Repo Assist.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

After Step 5a removes the distro-specific VHD directory
(e.g. %LOCALAPPDATA%\OpenClawTray\wsl\OpenClawGateway\), the
parent wsl\ directory was left as an empty orphan, which also
prevented the %LOCALAPPDATA%\OpenClawTray\ directory from being
removed by the MSIX uninstaller.

Changes:
- Add Step 5b in LocalGatewayUninstall.cs: after VHD parent dir
  cleanup, delete the wsl\ parent directory if it is empty.
  Non-empty wsl\ dirs (e.g. other distros still present) are
  preserved safely.
- Add WslParentDirAbsent postcondition; include it in
  AllRequiredPostconditionsMet and AppendPostconditionErrors.
- Update validate-wsl-gateway-uninstall.ps1: add wsl_parent_dir
  path constant, include wsl_parent_dir_absent in postconditions
  and required-checks list, and capture it in the pre-state
  snapshot.
- Add 3 unit tests (WslParentDirCleanup_*) covering empty→deleted,
  non-empty→skipped, and already-absent→skipped scenarios.

Closes #467

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Uninstall leaves behind empty directories in %LOCALAPPDATA%

0 participants