Skip to content

Commit 721330b

Browse files
authored
Merge branch 'main' into 06-26-fix_install_clean_up_the_temp_dir_when_a_package-manager_install_fails
2 parents 7de1520 + 49a79f1 commit 721330b

1 file changed

Lines changed: 110 additions & 8 deletions

File tree

packages/cli/install.ps1

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,87 @@ function Write-Warn {
4646
Write-Host $Message
4747
}
4848

49+
# Exit code when a Windows native binary cannot load required DLLs (STATUS_DLL_NOT_FOUND).
50+
$script:DllNotFoundExitCode = -1073741515
51+
52+
function Test-IsDllNotFoundExitCode {
53+
param([int]$ExitCode)
54+
if ($ExitCode -eq $script:DllNotFoundExitCode) {
55+
return $true
56+
}
57+
if ($ExitCode -eq 3221225781) {
58+
return $true
59+
}
60+
if ($ExitCode -lt 0) {
61+
$hex = '{0:X8}' -f ($ExitCode -band 0xFFFFFFFF)
62+
return $hex -eq 'C0000135'
63+
}
64+
return $false
65+
}
66+
67+
function Get-DllNotFoundInstallMessage {
68+
$arch = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "x64" }
69+
$vcUrl = if ($arch -eq "arm64") {
70+
"https://aka.ms/vs/17/release/vc_redist.arm64.exe"
71+
} else {
72+
"https://aka.ms/vs/17/release/vc_redist.x64.exe"
73+
}
74+
return @"
75+
vp.exe could not start (exit code 0xC0000135).
76+
This usually means Microsoft Visual C++ 2015-2022 Redistributable ($arch) is not installed.
77+
78+
Install: $vcUrl
79+
Then re-run: irm https://vite.plus/ps1 | iex
80+
"@
81+
}
82+
83+
# Internal stop signal: halts install without re-printing an error we already wrote.
84+
$script:InstallStopSignal = 'VP_INSTALL_STOP'
85+
86+
function Test-IsInstallStopException {
87+
param(
88+
[System.Management.Automation.ErrorRecord]$ErrorRecord
89+
)
90+
return $ErrorRecord.Exception.Message -eq $script:InstallStopSignal
91+
}
92+
93+
function Test-ShouldKeepShellOpenAfterFailure {
94+
# Only `irm ... | iex` typed in an already-open interactive shell should keep the
95+
# session alive. CI, script files, and `powershell -Command "..."` must exit non-zero.
96+
if ($env:CI -eq "true") {
97+
return $false
98+
}
99+
if ($PSCommandPath) {
100+
return $false
101+
}
102+
if (-not [Environment]::UserInteractive) {
103+
return $false
104+
}
105+
try {
106+
$commandLine = (Get-CimInstance Win32_Process -Filter "ProcessId=$PID").CommandLine
107+
if ($commandLine -match '(^|\s)-Command(\s|$)') {
108+
return $false
109+
}
110+
} catch {
111+
return $false
112+
}
113+
return $true
114+
}
115+
116+
function Exit-Installer {
117+
param([int]$Code = 1)
118+
$global:LASTEXITCODE = $Code
119+
if (-not (Test-ShouldKeepShellOpenAfterFailure)) {
120+
exit $Code
121+
}
122+
throw $script:InstallStopSignal
123+
}
124+
49125
function Write-Error-Exit {
50126
param([string]$Message)
51127
Write-Host "error: " -ForegroundColor Red -NoNewline
52128
Write-Host $Message
53-
exit 1
129+
Exit-Installer
54130
}
55131

56132
function Test-ReleaseAgeError {
@@ -114,11 +190,26 @@ function Write-ReleaseAgeOverride {
114190
}
115191

116192
function Write-InstallFailure {
117-
param([string]$LogPath)
193+
param(
194+
[string]$LogPath,
195+
[int]$ExitCode = 0
196+
)
197+
198+
if (Test-IsDllNotFoundExitCode $ExitCode) {
199+
$message = Get-DllNotFoundInstallMessage
200+
if ($env:CI -eq "true") {
201+
Write-Host "error: " -ForegroundColor Red -NoNewline
202+
Write-Host $message
203+
Exit-Installer
204+
}
205+
Write-Error-Exit $message
206+
}
207+
118208
if ($env:CI -eq "true") {
119209
Write-Host "error: " -ForegroundColor Red -NoNewline
120210
Write-Host "Failed to install dependencies. Log output:"
121211
Get-Content -Path $LogPath | ForEach-Object { Write-Host $_ }
212+
Exit-Installer
122213
} else {
123214
Write-Error-Exit "Failed to install dependencies. See log for details: $LogPath"
124215
}
@@ -157,6 +248,7 @@ function Get-PackageMetadata {
157248
try {
158249
$script:PackageMetadata = Invoke-RestMethod $metadataUrl
159250
} catch {
251+
if (Test-IsInstallStopException $_) { throw }
160252
# Try to extract npm error message from response
161253
$errorMsg = $_.ErrorDetails.Message
162254
if ($errorMsg) {
@@ -166,6 +258,7 @@ function Get-PackageMetadata {
166258
Write-Error-Exit "Failed to fetch version '${versionPath}': $($errorJson.error)`n URL: $metadataUrl"
167259
}
168260
} catch {
261+
if (Test-IsInstallStopException $_) { throw }
169262
# JSON parsing failed, fall through to generic error
170263
}
171264
}
@@ -179,6 +272,7 @@ function Get-PackageMetadata {
179272
try {
180273
$script:PackageMetadata = $script:PackageMetadata | ConvertFrom-Json
181274
} catch {
275+
if (Test-IsInstallStopException $_) { throw }
182276
# Not valid JSON - treat as plain string error
183277
Write-Error-Exit "Failed to fetch version '${versionPath}': $script:PackageMetadata`n URL: $metadataUrl"
184278
}
@@ -593,16 +687,14 @@ function Main {
593687
$retryExitCode = $LASTEXITCODE
594688
$retryOutput | Out-File $installLog
595689
if ($retryExitCode -ne 0) {
596-
Write-InstallFailure $installLog
597-
exit 1
690+
Write-InstallFailure -LogPath $installLog -ExitCode $retryExitCode
598691
}
599692
} else {
600693
Write-ReleaseAgeFailure $installLog
601-
exit 1
694+
Exit-Installer
602695
}
603696
} else {
604-
Write-InstallFailure $installLog
605-
exit 1
697+
Write-InstallFailure -LogPath $installLog -ExitCode $installExitCode
606698
}
607699
}
608700
} finally {
@@ -749,4 +841,14 @@ exec "`$VP_HOME/current/bin/vp.exe" "`$@"
749841
Write-Host ""
750842
}
751843

752-
Main
844+
try {
845+
Main
846+
} catch {
847+
if (Test-IsInstallStopException $_) {
848+
if (Test-ShouldKeepShellOpenAfterFailure) {
849+
return
850+
}
851+
exit $global:LASTEXITCODE
852+
}
853+
throw
854+
}

0 commit comments

Comments
 (0)