Keep an unowned default-mode sd.cpp checkout on uninstall

The custom-root sd.cpp removal requires the .unsloth-studio-owned marker (written by
install_sd_cpp_prebuilt) before deleting, so a user's own stable-diffusion.cpp checkout
beside a custom root is kept. The default-mode removal of ~/.unsloth/stable-diffusion.cpp
was unconditional, so a user who keeps their own checkout at that path (or points
UNSLOTH_SD_CPP_PATH there), or a pre-marker Studio build, would have it deleted on
uninstall. Guard the default-mode removal on the same owner marker in both uninstall.sh
and uninstall.ps1. Extends the sd.cpp uninstall shell test with owned (removed) and
unowned (kept) default-mode cases.
This commit is contained in:
Daniel Han 2026-07-07 10:22:40 +00:00
commit 6519fbfad5
3 changed files with 45 additions and 3 deletions

View file

@ -403,7 +403,15 @@ function Uninstall-UnslothStudio {
# Default-mode shared llama.cpp build + cache (siblings of studio under
# ~/.unsloth). No-op in env/custom mode and when absent.
if ($defaultLlamaCpp) { _RemovePath $defaultLlamaCpp }
if ($defaultSdCpp) { _RemovePath $defaultSdCpp }
# "stable-diffusion.cpp" is exactly what a git clone of leejet/stable-diffusion.cpp produces,
# so a user may keep their own checkout (or point UNSLOTH_SD_CPP_PATH) at this default path;
# require our owner marker (written by install_sd_cpp_prebuilt) before rm, mirroring the
# custom-root guard above, so a user's own checkout or a pre-marker Studio build is kept.
if ($defaultSdCpp -and (Test-Path -LiteralPath $defaultSdCpp) -and -not (Test-Path -LiteralPath (Join-Path $defaultSdCpp ".unsloth-studio-owned") -PathType Leaf)) {
_Substep "keeping sd.cpp without Studio owner marker: $defaultSdCpp" "Yellow"
} elseif ($defaultSdCpp) {
_RemovePath $defaultSdCpp
}
if ($defaultCache) { _RemovePath $defaultCache }
# Isolated Node.js runtime (sibling of studio under ~/.unsloth). No-op in env/
# custom mode (nested under the custom root, removed with it) and when absent.

View file

@ -234,8 +234,17 @@ _remove_path "$HOME/.unsloth/studio"
_remove_path "$HOME/.unsloth/llama.cpp"
# Default-mode native diffusion (stable-diffusion.cpp / sd-cli) build, a sibling of
# studio like llama.cpp (install_sd_cpp_prebuilt.default_install_dir()). No-op in
# env/custom mode and when absent. A user-set UNSLOTH_SD_CPP_PATH is kept.
_remove_path "$HOME/.unsloth/stable-diffusion.cpp"
# env/custom mode and when absent. "stable-diffusion.cpp" is exactly what a `git clone` of
# leejet/stable-diffusion.cpp produces, so a user may keep their own checkout (or point
# UNSLOTH_SD_CPP_PATH) at this default path; require our owner marker (written by
# install_sd_cpp_prebuilt) before rm, mirroring the custom-root guard above, so a user's own
# checkout or a pre-marker Studio build is kept rather than deleted.
_default_sd_cpp="$HOME/.unsloth/stable-diffusion.cpp"
if [ -e "$_default_sd_cpp" ] && [ ! -f "$_default_sd_cpp/.unsloth-studio-owned" ]; then
echo " keeping sd.cpp without Studio owner marker: $_default_sd_cpp" >&2
else
_remove_path "$_default_sd_cpp"
fi
_remove_path "$HOME/.unsloth/.cache"
# Isolated Node.js runtime (install_node_prebuilt.py), a sibling of studio in
# default mode. No-op in env/custom mode (nested under the custom root) and absent.

View file

@ -34,6 +34,9 @@ HELPERS_FILE=$(mktemp -p "$_TMP_ROOT")
} > "$HELPERS_FILE"
LOOP_FILE=$(mktemp -p "$_TMP_ROOT")
sed -n '/^_custom_studio_roots | while IFS= read -r _custom_root; do/,/^done/p' "$UNINSTALL_SH" > "$LOOP_FILE"
# The real default-mode ~/.unsloth/stable-diffusion.cpp removal block (marker-guarded).
DEFAULT_FILE=$(mktemp -p "$_TMP_ROOT")
sed -n '/^_default_sd_cpp="\$HOME\/\.unsloth\/stable-diffusion\.cpp"/,/^fi/p' "$UNINSTALL_SH" > "$DEFAULT_FILE"
# shellcheck disable=SC1090
. "$HELPERS_FILE"
@ -53,6 +56,10 @@ run_loop() {
# shellcheck disable=SC1090
. "$LOOP_FILE"
}
run_default_removal() {
# shellcheck disable=SC1090
. "$DEFAULT_FILE"
}
# 1. Single custom root -> root AND its sibling stable-diffusion.cpp both removed.
p1="$_TMP_ROOT/inst1"
@ -95,6 +102,24 @@ _custom_studio_roots() { printf '%s\n' "$p1/studioA"; } # a now-removed root ->
run_loop
assert_dir "default-mode sd.cpp untouched by custom loop" "$HOME/.unsloth/stable-diffusion.cpp"
# 5. Default-mode ~/.unsloth/stable-diffusion.cpp WITH the Studio owner marker (a real Studio
# default install) IS removed by the default-mode line.
rm -rf "$HOME/.unsloth/stable-diffusion.cpp"
mkdir -p "$HOME/.unsloth/stable-diffusion.cpp/build/bin"
: > "$HOME/.unsloth/stable-diffusion.cpp/build/bin/sd-cli"
: > "$HOME/.unsloth/stable-diffusion.cpp/.unsloth-studio-owned" # written by install_sd_cpp_prebuilt
run_default_removal
assert_nodir "default-mode owned sd.cpp removed" "$HOME/.unsloth/stable-diffusion.cpp"
# 6. Default-mode ~/.unsloth/stable-diffusion.cpp WITHOUT the marker -- a user's own checkout at
# the default path (or a pre-marker Studio build) -- is KEPT, mirroring the custom-root guard,
# so uninstall never deletes a user file.
rm -rf "$HOME/.unsloth/stable-diffusion.cpp"
mkdir -p "$HOME/.unsloth/stable-diffusion.cpp"
: > "$HOME/.unsloth/stable-diffusion.cpp/main.cpp" # user's own checkout, no owner marker
run_default_removal
assert_dir "default-mode unowned sd.cpp kept" "$HOME/.unsloth/stable-diffusion.cpp"
echo ""
echo "Results: $PASS passed, $FAIL failed"
[ "$FAIL" = 0 ]