perf(cli): drop legacy single-file compat from install/self-update

This commit is contained in:
Ahmed Allam 2026-07-27 23:12:58 +00:00
parent e3be6253f5
commit 084169ad1b
2 changed files with 17 additions and 77 deletions

View file

@ -159,28 +159,16 @@ download_and_install() {
fi
echo -e "${MUTED}Extracting...${NC}"
# Archive contains an app bundle dir: strix-{version}-{target}/ (strix + _internal/).
local extracted="strix-${specific_version}-${target}"
if [ "$os" = "windows" ]; then
unzip -q "$filename"
if [ -d "$extracted" ]; then
# Onedir app bundle (strix.exe + _internal/).
rm -rf "$INSTALL_DIR/_internal" "$INSTALL_DIR/strix.exe"
cp -R "$extracted/." "$INSTALL_DIR/"
else
# Legacy single-file binary.
mv "${extracted}.exe" "$INSTALL_DIR/strix.exe"
fi
rm -rf "$INSTALL_DIR/_internal" "$INSTALL_DIR/strix.exe"
cp -R "$extracted/." "$INSTALL_DIR/"
else
tar -xzf "$filename"
if [ -d "$extracted" ]; then
# Onedir app bundle (strix + _internal/).
rm -rf "$INSTALL_DIR/_internal" "$INSTALL_DIR/strix"
cp -R "$extracted/." "$INSTALL_DIR/"
else
# Legacy single-file binary.
rm -rf "$INSTALL_DIR/strix"
mv "$extracted" "$INSTALL_DIR/strix"
fi
rm -rf "$INSTALL_DIR/_internal" "$INSTALL_DIR/strix"
cp -R "$extracted/." "$INSTALL_DIR/"
chmod 755 "$INSTALL_DIR/strix"
fi

View file

@ -286,7 +286,6 @@ def _download_and_replace(version: str, target: str, console: Console) -> bool:
archive_ext = ".zip" if is_windows else ".tar.gz"
filename = f"strix-{version}-{target}{archive_ext}"
url = f"https://github.com/{GITHUB_REPO}/releases/download/v{version}/{filename}"
binary_name = f"strix-{version}-{target}" + (".exe" if is_windows else "")
current_exe = Path(sys.executable).resolve()
with tempfile.TemporaryDirectory() as tmp:
@ -322,41 +321,10 @@ def _download_and_replace(version: str, target: str, console: Console) -> bool:
tf.extractall(tmp_dir, filter="data") # nosec B202
bundle_dir = tmp_dir / f"strix-{version}-{target}"
if bundle_dir.is_dir():
_swap_app_bundle(bundle_dir, current_exe, is_windows=is_windows)
return True
new_binary = tmp_dir / binary_name
if not new_binary.is_file():
raise RuntimeError(f"unexpected archive layout in {filename}")
_swap_single_binary(new_binary, current_exe, is_windows=is_windows)
_swap_app_bundle(bundle_dir, current_exe, is_windows=is_windows)
return True
def _swap_single_binary(new_binary: Path, current_exe: Path, *, is_windows: bool) -> None:
"""Replace a legacy single-file binary in place."""
new_binary.chmod(new_binary.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
staged = current_exe.with_name(current_exe.name + ".new")
try:
shutil.copy2(new_binary, staged)
if is_windows:
# Windows can't replace a running executable in place; move it aside first.
old = current_exe.with_name(current_exe.name + ".old")
old.unlink(missing_ok=True)
current_exe.rename(old)
try:
staged.replace(current_exe)
except Exception:
old.rename(current_exe)
raise
else:
staged.replace(current_exe)
except Exception:
staged.unlink(missing_ok=True)
raise
def _swap_app_bundle(bundle_dir: Path, current_exe: Path, *, is_windows: bool) -> None:
"""Swap an onedir app bundle (exe + ``_internal/``) into place."""
exe_name = "strix.exe" if is_windows else "strix"
@ -369,39 +337,23 @@ def _swap_app_bundle(bundle_dir: Path, current_exe: Path, *, is_windows: bool) -
app_dir = current_exe.parent
internal = app_dir / "_internal"
old_internal = app_dir / "_internal.old"
staged_internal = app_dir / "_internal.new"
staged_exe = current_exe.with_name(current_exe.name + ".new")
old_exe = current_exe.with_name(current_exe.name + ".old")
shutil.rmtree(staged_internal, ignore_errors=True)
shutil.rmtree(old_internal, ignore_errors=True)
staged_exe.unlink(missing_ok=True)
old_exe.unlink(missing_ok=True)
shutil.copytree(new_internal, staged_internal)
shutil.copy2(new_exe, staged_exe)
internal_moved = False
try:
if internal.is_dir():
internal.rename(old_internal)
internal_moved = True
staged_internal.rename(internal)
if is_windows:
# Windows can't replace a running executable in place; move it aside first.
current_exe.rename(old_exe)
try:
staged_exe.replace(current_exe)
except Exception:
old_exe.rename(current_exe)
raise
else:
staged_exe.replace(current_exe)
except Exception:
if internal_moved and not internal.exists() and old_internal.exists():
old_internal.rename(internal)
shutil.rmtree(staged_internal, ignore_errors=True)
staged_exe.unlink(missing_ok=True)
raise
shutil.copytree(new_internal, internal)
if is_windows:
# Windows can't replace a running executable in place; move it aside first.
current_exe.rename(old_exe)
shutil.copy2(new_exe, current_exe)
else:
staged_exe = current_exe.with_name(current_exe.name + ".new")
shutil.copy2(new_exe, staged_exe)
staged_exe.replace(current_exe)
# Best effort: on Windows loaded DLLs/exe may resist deletion until restart.
shutil.rmtree(old_internal, ignore_errors=True)