Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 39 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -269,32 +269,36 @@ jobs:
RUST_MIN_STACK: 8388608

- name: Test global package install (powershell)
if: ${{ matrix.os == 'windows-latest' }}
if: ${{ matrix.os != 'namespace-profile-linux-x64-default' }}
shell: pwsh
run: |
echo "PATH: $env:Path"
where.exe node
where.exe npm
where.exe npx
where.exe vp
$vpHome = Join-Path $HOME ".vite-plus"
$vpBin = Join-Path $vpHome "bin"
. (Join-Path $vpHome 'env.ps1')

Write-Host "PATH: $env:Path"
Get-Command node
Get-Command npm
Get-Command npx
Get-Command vp
vp env doctor

# Test 1: Install a JS-based CLI (typescript)
vp install -g typescript
tsc --version
where.exe tsc
Get-Command tsc

# Test 2: Verify the package was installed correctly
Get-ChildItem "$env:USERPROFILE\.vite-plus\packages\typescript\"
Get-ChildItem "$env:USERPROFILE\.vite-plus\bin\"
Get-ChildItem (Join-Path $vpHome "packages/typescript")
Get-ChildItem $vpBin

# Test 3: Uninstall
vp uninstall -g typescript

# Test 4: Verify uninstall removed shim
Write-Host "Checking bin dir after uninstall:"
Get-ChildItem "$env:USERPROFILE\.vite-plus\bin\"
$shimPath = "$env:USERPROFILE\.vite-plus\bin\tsc.cmd"
Get-ChildItem $vpBin
$shimPath = if ($IsWindows) { Join-Path $vpBin "tsc.cmd" } else { Join-Path $vpBin "tsc" }
if (Test-Path $shimPath) {
Write-Error "tsc shim file still exists at $shimPath"
exit 1
Expand Down Expand Up @@ -444,14 +448,16 @@ jobs:
fi

- name: Test upgrade (powershell)
if: ${{ matrix.os == 'windows-latest' }}
if: ${{ matrix.os != 'namespace-profile-linux-x64-default' }}
shell: pwsh
run: |
Get-ChildItem "$env:USERPROFILE\.vite-plus\"
$vpHome = Join-Path $HOME ".vite-plus"
. (Join-Path $vpHome 'env.ps1')
Get-ChildItem $vpHome

# Helper to read the installed CLI version from package.json
function Get-CliVersion {
node -p "require(require('path').resolve(process.env.USERPROFILE, '.vite-plus', 'current', 'node_modules', 'vite-plus', 'package.json')).version"
node -p "require(require('path').resolve(process.env.USERPROFILE || process.env.HOME, '.vite-plus', 'current', 'node_modules', 'vite-plus', 'package.json')).version"
}

# Save initial (dev build) version
Expand All @@ -466,7 +472,7 @@ jobs:
vp --version
vp env doctor

Get-ChildItem "$env:USERPROFILE\.vite-plus\"
Get-ChildItem $vpHome

# Verify version changed after update
$updatedVersion = Get-CliVersion
Expand Down Expand Up @@ -552,20 +558,28 @@ jobs:
vp --version

- name: Test implode (powershell)
if: ${{ matrix.os == 'windows-latest' }}
if: ${{ matrix.os != 'namespace-profile-linux-x64-default' }}
shell: pwsh
run: |
# Retry — Windows file locks can cause transient "Access is denied" errors
foreach ($i in 1..3) {
vp implode --yes
if ($LASTEXITCODE -eq 0) { break }
Write-Host "Retry $i`: vp implode failed, waiting 5s..."
$vpHome = Join-Path $HOME ".vite-plus"
. (Join-Path $vpHome 'env.ps1')

if ($IsWindows) {
# Retry — Windows file locks can cause transient "Access is denied" errors
foreach ($i in 1..3) {
vp implode --yes
if ($LASTEXITCODE -eq 0) { break }
Write-Host "Retry $i`: vp implode failed, waiting 5s..."
Start-Sleep -Seconds 5
}
Start-Sleep -Seconds 5
} else {
vp implode --yes
}
Start-Sleep -Seconds 5
dir "$env:USERPROFILE\"
if (Test-Path "$env:USERPROFILE\.vite-plus") {
Write-Error "~/.vite-plus still exists after implode"

Get-ChildItem $HOME
if (Test-Path $vpHome) {
Write-Error "$vpHome still exists after implode"
exit 1
}
pnpm bootstrap-cli:ci
Expand Down
12 changes: 7 additions & 5 deletions crates/vite_global_cli/src/commands/env/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,28 +641,30 @@ if ($env:Path -split ';' -notcontains $__vp_bin) {
function vp {
if ($args.Count -ge 2 -and $args[0] -eq "env" -and $args[1] -eq "use") {
if ($args -contains "-h" -or $args -contains "--help") {
& (Join-Path $__vp_bin "vp.exe") @args; return
& (Join-Path $__vp_bin "vp") @args; return
}
$env:VP_ENV_USE_EVAL_ENABLE = "1"
$output = & (Join-Path $__vp_bin "vp.exe") @args 2>&1 | ForEach-Object {
$env:VP_SHELL_PWSH = "1"
$output = & (Join-Path $__vp_bin "vp") @args 2>&1 | ForEach-Object {
if ($_ -is [System.Management.Automation.ErrorRecord]) {
Write-Host $_.Exception.Message
} else {
$_
}
}
Remove-Item Env:VP_ENV_USE_EVAL_ENABLE -ErrorAction SilentlyContinue
Remove-Item Env:VP_SHELL_PWSH -ErrorAction SilentlyContinue
if ($LASTEXITCODE -eq 0 -and $output) {
Invoke-Expression ($output -join "`n")
}
} else {
& (Join-Path $__vp_bin "vp.exe") @args
& (Join-Path $__vp_bin "vp") @args
}
}

# Dynamic shell completion for PowerShell
$env:VP_COMPLETE = "powershell"
& (Join-Path $__vp_bin "vp.exe") | Out-String | Invoke-Expression
& (Join-Path $__vp_bin "vp") | Out-String | Invoke-Expression
Remove-Item Env:\VP_COMPLETE -ErrorAction SilentlyContinue

$__vpr_comp = {
Expand All @@ -674,7 +676,7 @@ $__vpr_comp = {
$args = $args -replace '^(vpr\.exe|vpr)\b', 'vp run'
if ($wordToComplete -eq "") { $args += " ''" }
$results = Invoke-Expression @"
& (Join-Path $__vp_bin 'vp.exe') -- $args
& (Join-Path $__vp_bin 'vp') -- $args
"@;
if ($prev) { $env:VP_COMPLETE = $prev } else { Remove-Item Env:\VP_COMPLETE }
$results | ForEach-Object {
Expand Down
9 changes: 3 additions & 6 deletions crates/vite_global_cli/src/commands/env/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn detect_shell() -> Shell {
Shell::Fish
} else if config.vp_shell_nu {
Shell::NuShell
} else if cfg!(windows) && config.ps_module_path.is_some() {
} else if config.vp_shell_pwsh {
Shell::PowerShell
} else if cfg!(windows) {
Shell::Cmd
Expand Down Expand Up @@ -178,15 +178,12 @@ mod tests {
use super::*;

#[test]
fn test_detect_shell_posix_even_with_psmodulepath() {
fn test_detect_shell_pwsh() {
let _guard = vite_shared::EnvConfig::test_guard(vite_shared::EnvConfig {
ps_module_path: Some("/some/path".into()),
vp_shell_pwsh: true,
..vite_shared::EnvConfig::for_test()
});
let shell = detect_shell();
#[cfg(not(windows))]
assert!(matches!(shell, Shell::Posix));
#[cfg(windows)]
assert!(matches!(shell, Shell::PowerShell));
}

Expand Down
7 changes: 7 additions & 0 deletions crates/vite_shared/src/env_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ pub struct EnvConfig {
///
/// Env: `VP_SHELL_NU`
pub vp_shell_nu: bool,

/// Explicit PowerShell eval signal set by the `env.ps1` wrapper.
///
/// Env: `VP_SHELL_PWSH`
pub vp_shell_pwsh: bool,
}

impl EnvConfig {
Expand Down Expand Up @@ -166,6 +171,7 @@ impl EnvConfig {
ps_module_path: std::env::var("PSModulePath").ok(),
nu_version: std::env::var("NU_VERSION").ok(),
vp_shell_nu: std::env::var(env_vars::VP_SHELL_NU).is_ok(),
vp_shell_pwsh: std::env::var(env_vars::VP_SHELL_PWSH).is_ok(),
}
}

Expand Down Expand Up @@ -250,6 +256,7 @@ impl EnvConfig {
ps_module_path: None,
nu_version: None,
vp_shell_nu: false,
vp_shell_pwsh: false,
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/vite_shared/src/env_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ pub const VP_ENV_USE_EVAL_ENABLE: &str = "VP_ENV_USE_EVAL_ENABLE";
/// bash/zsh is launched from a Nushell session.
pub const VP_SHELL_NU: &str = "VP_SHELL_NU";

/// Explicit signal set by the PowerShell wrapper to indicate PowerShell eval context.
pub const VP_SHELL_PWSH: &str = "VP_SHELL_PWSH";

/// Filter for update task types.
pub const VITE_UPDATE_TASK_TYPES: &str = "VITE_UPDATE_TASK_TYPES";

Expand Down
Loading