Clean up existing install before extracting .mpk (#55)

install_mpk() would fail with EEXIST if the destination folder already
existed from a previous (possibly partial) install, or if a dangling
symlink occupied the path (e.g. a dev symlink whose target was removed).

Before extracting, now remove the destination if it is:
- A real directory (via shutil.rmtree)
- A regular file (via os.remove)
- A symlink, including broken ones (via os.remove as a fallback)

This enables clean reinstalls, updates, and recovery from failed
installs.

Co-authored-by: Richard Taylor <RT@MacBookPro.lan>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-02-21 06:42:04 +00:00
committed by GitHub
parent ef30c80e49
commit a1478080b1
@@ -157,6 +157,25 @@ class AppManager:
@staticmethod
def install_mpk(temp_zip_path, dest_folder):
try:
# Step 1: Remove any existing (possibly partial) install or symlink
try:
st = os.stat(dest_folder)
if st[0] & 0x4000: # It's a real directory
import shutil
shutil.rmtree(dest_folder)
print("Removed existing folder:", dest_folder)
else:
os.remove(dest_folder)
print("Removed existing file:", dest_folder)
except OSError:
pass # Doesn't exist, that's fine
# Also remove if it's a symlink (broken or otherwise)
try:
os.remove(dest_folder)
print("Removed symlink:", dest_folder)
except OSError:
pass # Not a symlink or already removed
# Step 2: Unzip the file
print("Unzipping it to:", dest_folder)
with zipfile.ZipFile(temp_zip_path, "r") as zip_ref: