install + setup: canonicalize legacy-equality comparison sites

Cycle 24 made \$STUDIO_HOME canonical via 'CDPATH= cd -P -- ... && pwd -P',
but the legacy-equality comparison sites still used the bare logical
"\$HOME/.unsloth/studio" string. With a symlinked \$HOME (e.g.
/home/alice -> /u/alice), the comparison fails even when both sides
point at the same dir, and llama.cpp ends up under a custom-root path
the Python backend's legacy comparison cannot find.

Reviewer cycle 25 inst 2 reproduced this with HOME=/tmp/link -> /tmp/real
and UNSLOTH_STUDIO_HOME=\$HOME/.unsloth/studio: setup.sh resolves
UNSLOTH_HOME to /tmp/real/.unsloth/studio while the backend search
resolves both physically equal and looks at /tmp/link/.unsloth/llama.cpp.

Canonicalize the legacy side at all four sites:
- install.sh:695 (create_studio_shortcuts llama.cpp path)
- studio/setup.sh:577 (UNSLOTH_HOME selection)
- install.ps1:462 (launcher UNSLOTH_LLAMA_CPP_PATH path)
- studio/setup.ps1:1829 (UnslothHome selection)

Apply CDPATH= cd -P -- ... && pwd -P (Unix) or Resolve-Path -LiteralPath
(Windows) when the legacy dir exists. unsloth_cli/commands/studio.py
already does this via Path.resolve().
This commit is contained in:
Daniel Han 2026-04-26 22:58:42 +00:00
commit a4d12c4d7e
4 changed files with 25 additions and 0 deletions

View file

@ -460,6 +460,12 @@ function Install-UnslothStudio {
# legacy default, llama.cpp still lives at ~/.unsloth/llama.cpp.
# Keep the persisted UNSLOTH_LLAMA_CPP_PATH consistent with that.
$_legacyStudio = Join-Path $env:USERPROFILE ".unsloth\studio"
# Canonicalize the legacy side (when it exists) to match the
# resolved $StudioHome from the env-override path. This keeps
# the legacy-equality check stable across path normalization.
if (Test-Path -LiteralPath $_legacyStudio -PathType Container) {
$_legacyStudio = (Resolve-Path -LiteralPath $_legacyStudio).Path
}
$_llamaPath = if ($StudioHome -eq $_legacyStudio) {
Join-Path $env:USERPROFILE ".unsloth\llama.cpp"
} else {

View file

@ -692,7 +692,15 @@ LAUNCHER_EOF
# happens to point at the legacy default, llama.cpp still lives
# at ~/.unsloth/llama.cpp (one shared build across legacy
# installs) -- keep UNSLOTH_LLAMA_CPP_PATH consistent with that.
# $STUDIO_HOME is canonicalized (cycle 24) but $HOME/.unsloth/studio
# is still logical. Canonicalize the legacy side too so a symlinked
# $HOME doesn't make the comparison fail when both point at the
# same dir.
_css_legacy_studio="$HOME/.unsloth/studio"
if [ -d "$_css_legacy_studio" ]; then
_css_legacy_studio=$(CDPATH= cd -P -- "$_css_legacy_studio" 2>/dev/null && pwd -P) \
|| _css_legacy_studio="$HOME/.unsloth/studio"
fi
if [ "$STUDIO_HOME" = "$_css_legacy_studio" ]; then
_css_llama_path="$HOME/.unsloth/llama.cpp"
else

View file

@ -1827,6 +1827,10 @@ step "transformers" "5.5.0 pre-installed"
# stale UNSLOTH_STUDIO_HOME pointing at the legacy default does not
# accidentally relocate llama.cpp.
$LegacyStudioHome = Join-Path $env:USERPROFILE ".unsloth\studio"
# Canonicalize the legacy side to match $StudioHome's normalized form.
if (Test-Path -LiteralPath $LegacyStudioHome -PathType Container) {
$LegacyStudioHome = (Resolve-Path -LiteralPath $LegacyStudioHome).Path
}
if ($StudioHome -eq $LegacyStudioHome) {
$UnslothHome = Join-Path $env:USERPROFILE ".unsloth"
} else {

View file

@ -575,6 +575,13 @@ fi
# of env-var presence avoids regressing default installs that incidentally
# inherit UNSLOTH_STUDIO_HOME from a parent process or the CLI.
_LEGACY_STUDIO_HOME="$HOME/.unsloth/studio"
# Canonicalize the legacy side so a symlinked $HOME doesn't make the
# comparison fail when STUDIO_HOME (already canonicalized) and the
# legacy path point at the same directory.
if [ -d "$_LEGACY_STUDIO_HOME" ]; then
_LEGACY_STUDIO_HOME=$(CDPATH= cd -P -- "$_LEGACY_STUDIO_HOME" 2>/dev/null && pwd -P) \
|| _LEGACY_STUDIO_HOME="$HOME/.unsloth/studio"
fi
if [ "$STUDIO_HOME" = "$_LEGACY_STUDIO_HOME" ]; then
UNSLOTH_HOME="$HOME/.unsloth"
else