From afd93ff627b777d911b4db6fc7e7e4856f4a85c4 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Mon, 1 Apr 2024 18:09:14 +0800 Subject: [PATCH] Add switch function --- lib/core.ps1 | 52 +++++++++++++++++++++++++++++++++++++++ lib/install.ps1 | 25 +++---------------- lib/system.ps1 | 65 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 98 insertions(+), 44 deletions(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index af62b8156e..fac9b2d619 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -142,11 +142,63 @@ function set_config { $scoopConfig.PSObject.Properties.Remove($name) } + # Initialize config's change + Complete-ConfigChange -Name $name -Value $value + # Save config with UTF8NoBOM encoding ConvertTo-Json $scoopConfig | Out-UTF8File -FilePath $configFile return $scoopConfig } +function Complete-ConfigChange { + [CmdletBinding()] + param ( + [Parameter(Mandatory, Position = 0)] + [string] + $Name, + [Parameter(Mandatory, Position = 1)] + [AllowEmptyString()] + [string] + $Value + ) + + if ($Name -eq 'use_isolated_path') { + . "$PSScriptRoot\..\lib\system.ps1" + + if ($Value -eq $true) { + info 'Switching to isolated path... This may take a while, please wait.' + $movedPath = Remove-Path -Path "$scoopdir\apps\*" -Quiet -PassThru + if ($movedPath) { + Add-Path -Path $movedPath -TargetEnvVar 'SCOOP_PATH' -Quiet + Add-Path -Path '%SCOOP_PATH%' -Quiet + } + if (is_admin) { + $movedPath = Remove-Path -Path "$globaldir\apps\*" -Global -Quiet -PassThru + if ($movedPath) { + Add-Path -Path $movedPath -TargetEnvVar 'SCOOP_PATH' -Global -Quiet + Add-Path -Path '%SCOOP_PATH%' -Global -Quiet + } + } + } else { + info 'Switching to shared path... This may take a while, please wait.' + $movedPath = Get-EnvVar -Name 'SCOOP_PATH' + if ($movedPath) { + Add-Path -Path $movedPath -Quiet + Remove-Path -Path '%SCOOP_PATH%' -Quiet + Set-EnvVar -Name 'SCOOP_PATH' -Quiet + } + if (is_admin) { + $movedPath = Get-EnvVar -Name 'SCOOP_PATH' -Global + if ($movedPath) { + Add-Path -Path $movedPath -Global -Quiet + Remove-Path -Path '%SCOOP_PATH%' -Global -Quiet + Set-EnvVar -Name 'SCOOP_PATH' -Global -Quiet + } + } + } + } +} + function setup_proxy() { # note: '@' and ':' in password must be escaped, e.g. 'p@ssword' -> p\@ssword' $proxy = get_config PROXY diff --git a/lib/install.ps1 b/lib/install.ps1 index badbc401e4..52ab5fb21f 100644 --- a/lib/install.ps1 +++ b/lib/install.ps1 @@ -915,19 +915,7 @@ function env_add_path($manifest, $dir, $global, $arch) { } else { $target_path = 'PATH' } - # GH-3785: Add path in ascending order. - [Array]::Reverse($env_add_path) - $env_add_path | Where-Object { $_ } | ForEach-Object { - if ($_ -eq '.') { - $path_dir = $dir - } else { - $path_dir = Join-Path $dir $_ - } - if (!(is_in_dir $dir $path_dir)) { - abort "Error in manifest: env_add_path '$_' is outside the app directory." - } - Add-Path -Path $path_dir -TargetEnvVar $target_path -Global:$global -Force - } + Add-Path -Path ($env_add_path.Where({ $_ -and !$_.Contains(':') }).ForEach({ Join-Path $dir $_ })) -TargetEnvVar $target_path -Global:$global -Force } } @@ -935,21 +923,14 @@ function env_rm_path($manifest, $dir, $global, $arch) { $env_add_path = arch_specific 'env_add_path' $manifest $arch $dir = $dir.TrimEnd('\') if ($env_add_path) { - if (get_config USE_ISOLATED_PATH) { - $target_path = 'SCOOP_PATH' - } else { - $target_path = 'PATH' - } $env_add_path | Where-Object { $_ } | ForEach-Object { if ($_ -eq '.') { $path_dir = $dir } else { $path_dir = Join-Path $dir $_ } - Remove-Path -Path $path_dir -TargetEnvVar $target_path -Global:$global - if ($target_path -eq 'SCOOP_PATH') { - Remove-Path -Path $path_dir -Global:$global - } + Remove-Path -Path $path_dir -Global:$global + Remove-Path -Path $path_dir -TargetEnvVar 'SCOOP_PATH' -Global:$global } } } diff --git a/lib/system.ps1 b/lib/system.ps1 index b47b7394e3..9369ea5034 100644 --- a/lib/system.ps1 +++ b/lib/system.ps1 @@ -73,41 +73,55 @@ function Set-EnvVar { Publish-EnvVar } -function Test-PathLikeEnvVar { +function Split-PathLikeEnvVar { param( - [string]$Name, + [string[]]$Pattern, [string]$Path ) if ($null -eq $Path -and $Path -eq '') { - return $false, $null + return $null, $null } else { - $strippedPath = $Path.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries).Where({ $_ -ne $Name }) -join ';' - return ($strippedPath -ne $Path), $strippedPath + $splitPattern = $Pattern.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries) + $splitPath = $Path.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries) + $inPath = @() + foreach ($p in $splitPattern) { + $inPath += $splitPath.Where({ $_ -like $p }) + $splitPath = $splitPath.Where({ $_ -notlike $p }) + } + return ($inPath -join ';'), ($splitPath -join ';') } } function Add-Path { param( - [string]$Path, + [string[]]$Path, [string]$TargetEnvVar = 'PATH', [switch]$Global, - [switch]$Force + [switch]$Force, + [switch]$Quiet ) - - if (!$Path.Contains('%')) { - $Path = fullpath $Path + $Path = $Path | ForEach-Object { + if (!$_.Contains('%')) { + fullpath $_ + } else { + $_ + } } # future sessions - $inPath, $strippedPath = Test-PathLikeEnvVar $Path (Get-EnvVar -Name $TargetEnvVar -Global:$Global) + $inPath, $strippedPath = Split-PathLikeEnvVar $Path (Get-EnvVar -Name $TargetEnvVar -Global:$Global) if (!$inPath -or $Force) { - Write-Output "Adding $(friendly_path $Path) to $(if ($Global) {'global'} else {'your'}) path." - Set-EnvVar -Name $TargetEnvVar -Value (@($Path, $strippedPath) -join ';') -Global:$Global + if (!$Quiet) { + $Path | ForEach-Object { + Write-Host "Adding $(friendly_path $_) to $(if ($Global) {'global'} else {'your'}) path." + } + } + Set-EnvVar -Name $TargetEnvVar -Value ((@($Path) + $strippedPath) -join ';') -Global:$Global } # current session - $inPath, $strippedPath = Test-PathLikeEnvVar $Path $env:PATH + $inPath, $strippedPath = Split-PathLikeEnvVar $Path $env:PATH if (!$inPath -or $Force) { - $env:PATH = @($Path, $strippedPath) -join ';' + $env:PATH = (@($Path) + $strippedPath) -join ';' } } @@ -115,23 +129,30 @@ function Remove-Path { param( [string]$Path, [string]$TargetEnvVar = 'PATH', - [switch]$Global + [switch]$Global, + [switch]$Quiet, + [switch]$PassThru ) if (!$Path.Contains('%')) { $Path = fullpath $Path } # future sessions - $inPath, $strippedPath = Test-PathLikeEnvVar $Path (Get-EnvVar -Name $TargetEnvVar -Global:$Global) + $inPath, $strippedPath = Split-PathLikeEnvVar $Path (Get-EnvVar -Name $TargetEnvVar -Global:$Global) if ($inPath) { - Write-Output "Removing $(friendly_path $Path) from $(if ($Global) {'global'} else {'your'}) path." + if (!$Quiet) { + Write-Host "Removing $(friendly_path $Path) from $(if ($Global) {'global'} else {'your'}) path." + } Set-EnvVar -Name $TargetEnvVar -Value $strippedPath -Global:$Global } # current session - $inPath, $strippedPath = Test-PathLikeEnvVar $Path $env:PATH - if ($inPath) { + $inSessionPath, $strippedPath = Split-PathLikeEnvVar $Path $env:PATH + if ($inSessionPath) { $env:PATH = $strippedPath } + if ($PassThru) { + return $inPath + } } ## Deprecated functions @@ -147,8 +168,8 @@ function env($name, $global, $val) { } function strip_path($orig_path, $dir) { - Show-DeprecatedWarning $MyInvocation 'Test-PathLikeEnvVar' - Test-PathLikeEnvVar -Name $dir -Path $orig_path + Show-DeprecatedWarning $MyInvocation 'Split-PathLikeEnvVar' + Split-PathLikeEnvVar -Name $dir -Path $orig_path } function add_first_in_path($dir, $global) {