install.ps1: env-override resolution uses .NET API for literal paths

Gemini code-review (review 4177641398, commit 2ea2c91) caught two
remaining New-Item -Path sites in the env-override resolution block
that the cycle 18 sweep missed:

- Line 123: New-Item -ItemType Directory -Path \$envOverride
- Line 132: New-Item -ItemType File -Path \$probe (writability test)

Both use -Path which interprets square brackets as wildcards. For a
user with UNSLOTH_STUDIO_HOME=C:\\workspaces\\studio[abc], both calls
would fail before the install starts. New-Item also has no
-LiteralPath in PowerShell 5.1.

Replace both with the .NET API:
- [System.IO.Directory]::CreateDirectory(\$envOverride)
- [System.IO.File]::WriteAllText(\$probe, "") -- closes the file
  handle before the Remove-Item below.

End-to-end verified with /tmp/test-envoverride-[abc]-* path:
CreateDirectory + WriteAllText + Test-Path -LiteralPath all work.
This commit is contained in:
Daniel Han 2026-04-26 23:55:10 +00:00
commit fe309d2192

View file

@ -120,7 +120,10 @@ function Install-UnslothStudio {
$envOverride = (Join-Path $env:USERPROFILE $envOverride.Substring(1).TrimStart('/','\'))
}
try {
New-Item -ItemType Directory -Path $envOverride -Force -ErrorAction Stop | Out-Null
# New-Item has no -LiteralPath in PowerShell 5.1 and -Path treats
# square brackets as wildcards. Use the .NET API so a custom root
# like C:\workspaces\studio[abc] is handled literally.
[System.IO.Directory]::CreateDirectory($envOverride) | Out-Null
$StudioHome = (Resolve-Path -LiteralPath $envOverride).Path
} catch {
Write-Host "ERROR: STUDIO_HOME=$envOverride cannot be created or accessed." -ForegroundColor Red
@ -129,7 +132,10 @@ function Install-UnslothStudio {
# Default ToString() form already produces a unique GUID string.
$probe = Join-Path $StudioHome (".unsloth-write-probe-" + [guid]::NewGuid())
try {
New-Item -ItemType File -Path $probe -ErrorAction Stop | Out-Null
# WriteAllText is literal-path safe and closes the file handle
# before the Remove-Item below; New-Item -Path would fail on
# bracketed roots (wildcard expansion) just like the dir case.
[System.IO.File]::WriteAllText($probe, "")
Remove-Item -LiteralPath $probe -Force -ErrorAction SilentlyContinue
} catch {
Write-Host "ERROR: STUDIO_HOME=$StudioHome is not writable." -ForegroundColor Red