From 6772e61b3d595bee401b50f030567c78c598bdc5 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 27 Mar 2024 17:32:39 +0800 Subject: [PATCH 1/8] refactor(core): Rewrite and separate path-related functions to `system.ps1` (#5836) --- CHANGELOG.md | 1 + bin/uninstall.ps1 | 4 +- lib/core.ps1 | 126 +++------------------------- lib/install.ps1 | 16 ++-- lib/psmodules.ps1 | 5 +- lib/system.ps1 | 158 +++++++++++++++++++++++++++++++++++ libexec/scoop-install.ps1 | 1 + libexec/scoop-reset.ps1 | 1 + libexec/scoop-uninstall.ps1 | 1 + libexec/scoop-update.ps1 | 1 + test/Scoop-Core.Tests.ps1 | 37 +------- test/Scoop-Install.Tests.ps1 | 13 +-- 12 files changed, 197 insertions(+), 167 deletions(-) create mode 100644 lib/system.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 70904eb80c..51322fd91f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ - **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122), [#5375](https://github.com/ScoopInstaller/Scoop/issues/5375)) - **scoop-download:** Output more detailed manifest information ([#5277](https://github.com/ScoopInstaller/Scoop/issues/5277)) - **core:** Cleanup some old codes, e.g., msi section and config migration ([#5715](https://github.com/ScoopInstaller/Scoop/issues/5715), [#5824](https://github.com/ScoopInstaller/Scoop/issues/5824)) +- **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836)) ### Builds diff --git a/bin/uninstall.ps1 b/bin/uninstall.ps1 index 3baf30ba42..9e89481959 100644 --- a/bin/uninstall.ps1 +++ b/bin/uninstall.ps1 @@ -12,6 +12,7 @@ param( ) . "$PSScriptRoot\..\lib\core.ps1" +. "$PSScriptRoot\..\lib\system.ps1" . "$PSScriptRoot\..\lib\install.ps1" . "$PSScriptRoot\..\lib\shortcuts.ps1" . "$PSScriptRoot\..\lib\versions.ps1" @@ -98,7 +99,6 @@ if ($purge) { if ($global) { keep_onlypersist $globaldir } } -remove_from_path (shimdir $false) -if ($global) { remove_from_path (shimdir $true) } +Remove-Path -Path (shimdir $global) -Global:$global success 'Scoop has been uninstalled.' diff --git a/lib/core.ps1 b/lib/core.ps1 index 525a4951e4..af62b8156e 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -581,12 +581,18 @@ function fullpath($path) { $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path) } function friendly_path($path) { - $h = (Get-PsProvider 'FileSystem').home; if(!$h.endswith('\')) { $h += '\' } - if($h -eq '\') { return $path } - return "$path" -replace ([regex]::escape($h)), "~\" + $h = (Get-PSProvider 'FileSystem').Home + if (!$h.EndsWith('\')) { + $h += '\' + } + if ($h -eq '\') { + return $path + } else { + return $path -replace ([Regex]::Escape($h)), '~\' + } } function is_local($path) { - ($path -notmatch '^https?://') -and (test-path $path) + ($path -notmatch '^https?://') -and (Test-Path $path) } # operations @@ -715,57 +721,6 @@ function Invoke-ExternalCommand { return $true } -function Publish-Env { - if (-not ("Win32.NativeMethods" -as [Type])) { - Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @" -[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] -public static extern IntPtr SendMessageTimeout( - IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, - uint fuFlags, uint uTimeout, out UIntPtr lpdwResult); -"@ - } - - $HWND_BROADCAST = [IntPtr] 0xffff; - $WM_SETTINGCHANGE = 0x1a; - $result = [UIntPtr]::Zero - - [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST, - $WM_SETTINGCHANGE, - [UIntPtr]::Zero, - "Environment", - 2, - 5000, - [ref] $result - ) | Out-Null -} - -function env($name, $global, $val = '__get') { - $RegisterKey = if ($global) { - Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' - } else { - Get-Item -Path 'HKCU:' - } - $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment', $val -ne '__get') - - if ($val -eq '__get') { - $RegistryValueOption = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames - $EnvRegisterKey.GetValue($name, $null, $RegistryValueOption) - } elseif ($val -eq $null) { - try { $EnvRegisterKey.DeleteValue($name) } catch { } - Publish-Env - } else { - $RegistryValueKind = if ($val.Contains('%')) { - [Microsoft.Win32.RegistryValueKind]::ExpandString - } elseif ($EnvRegisterKey.GetValue($name)) { - $EnvRegisterKey.GetValueKind($name) - } else { - [Microsoft.Win32.RegistryValueKind]::String - } - $EnvRegisterKey.SetValue($name, $val, $RegistryValueKind) - Publish-Env - } -} - function isFileLocked([string]$path) { $file = New-Object System.IO.FileInfo $path @@ -873,7 +828,7 @@ function warn_on_overwrite($shim, $path) { function shim($path, $global, $name, $arg) { if (!(Test-Path $path)) { abort "Can't shim '$(fname $path)': couldn't find '$path'." } $abs_shimdir = ensure (shimdir $global) - ensure_in_path $abs_shimdir $global + Add-Path -Path $abs_shimdir -Global:$global if (!$name) { $name = strip_ext (fname $path) } $shim = "$abs_shimdir\$($name.tolower())" @@ -1010,26 +965,6 @@ function get_shim_path() { return $shim_path } -function search_in_path($target) { - $path = (env 'PATH' $false) + ";" + (env 'PATH' $true) - foreach($dir in $path.split(';')) { - if(test-path "$dir\$target" -pathType leaf) { - return "$dir\$target" - } - } -} - -function ensure_in_path($dir, $global) { - $path = env 'PATH' $global - $dir = fullpath $dir - if($path -notmatch [regex]::escape($dir)) { - write-output "Adding $(friendly_path $dir) to $(if($global){'global'}else{'your'}) path." - - env 'PATH' $global "$dir;$path" # for future sessions... - $env:PATH = "$dir;$env:PATH" # for this session - } -} - function Get-DefaultArchitecture { $arch = get_config DEFAULT_ARCHITECTURE $system = if (${env:ProgramFiles(Arm)}) { @@ -1104,45 +1039,6 @@ function Confirm-InstallationStatus { return , $Installed } -function strip_path($orig_path, $dir) { - if($null -eq $orig_path) { $orig_path = '' } - $stripped = [string]::join(';', @( $orig_path.split(';') | Where-Object { $_ -and $_ -ne $dir } )) - return ($stripped -ne $orig_path), $stripped -} - -function add_first_in_path($dir, $global) { - $dir = fullpath $dir - - # future sessions - $null, $currpath = strip_path (env 'path' $global) $dir - env 'path' $global "$dir;$currpath" - - # this session - $null, $env:PATH = strip_path $env:PATH $dir - $env:PATH = "$dir;$env:PATH" -} - -function remove_from_path($dir, $global) { - $dir = fullpath $dir - - # future sessions - $was_in_path, $newpath = strip_path (env 'path' $global) $dir - if($was_in_path) { - Write-Output "Removing $(friendly_path $dir) from your path." - env 'path' $global $newpath - } - - # current session - $was_in_path, $newpath = strip_path $env:PATH $dir - if($was_in_path) { $env:PATH = $newpath } -} - -function ensure_robocopy_in_path { - if(!(Test-CommandAvailable robocopy)) { - shim "C:\Windows\System32\Robocopy.exe" $false - } -} - function wraptext($text, $width) { if(!$width) { $width = $host.ui.rawui.buffersize.width }; $width -= 1 # be conservative: doesn't seem to print the last char diff --git a/lib/install.ps1 b/lib/install.ps1 index 0ed13707e8..2a244b44c2 100644 --- a/lib/install.ps1 +++ b/lib/install.ps1 @@ -783,7 +783,7 @@ function create_shims($manifest, $dir, $global, $arch) { } elseif (Test-Path $target -PathType leaf) { $bin = $target } else { - $bin = search_in_path $target + $bin = (Get-Command $target).Source } if (!$bin) { abort "Can't shim '$target': File doesn't exist." } @@ -876,16 +876,16 @@ function unlink_current($versiondir) { # to undo after installers add to path so that scoop manifest can keep track of this instead function ensure_install_dir_not_in_path($dir, $global) { - $path = (env 'path' $global) + $path = (Get-EnvVar -Name 'PATH' -Global:$global) $fixed, $removed = find_dir_or_subdir $path "$dir" if ($removed) { $removed | ForEach-Object { "Installer added '$(friendly_path $_)' to path. Removing." } - env 'path' $global $fixed + Set-EnvVar -Name 'PATH' -Value $fixed -Global:$global } if (!$global) { - $fixed, $removed = find_dir_or_subdir (env 'path' $true) "$dir" + $fixed, $removed = find_dir_or_subdir (Get-EnvVar -Name 'PATH' -Global) "$dir" if ($removed) { $removed | ForEach-Object { warn "Installer added '$_' to system path. You might want to remove this manually (requires admin permission)." } } @@ -920,7 +920,7 @@ function env_add_path($manifest, $dir, $global, $arch) { if (!(is_in_dir $dir $path_dir)) { abort "Error in manifest: env_add_path '$_' is outside the app directory." } - add_first_in_path $path_dir $global + Add-Path -Path $path_dir -Global:$global -Force } } } @@ -935,7 +935,7 @@ function env_rm_path($manifest, $dir, $global, $arch) { } else { $path_dir = Join-Path $dir $_ } - remove_from_path $path_dir $global + Remove-Path -Path $path_dir -Global:$global } } } @@ -946,7 +946,7 @@ function env_set($manifest, $dir, $global, $arch) { $env_set | Get-Member -Member NoteProperty | ForEach-Object { $name = $_.name $val = format $env_set.$($_.name) @{ 'dir' = $dir } - env $name $global $val + Set-EnvVar -Name $name -Value $val -Global:$global Set-Content env:\$name $val } } @@ -956,7 +956,7 @@ function env_rm($manifest, $global, $arch) { if ($env_set) { $env_set | Get-Member -Member NoteProperty | ForEach-Object { $name = $_.name - env $name $global $null + Set-EnvVar -Name $name -Value $null -Global:$global if (Test-Path env:\$name) { Remove-Item env:\$name } } } diff --git a/lib/psmodules.ps1 b/lib/psmodules.ps1 index c65fd65c7b..3ba2f6624a 100644 --- a/lib/psmodules.ps1 +++ b/lib/psmodules.ps1 @@ -42,7 +42,7 @@ function uninstall_psmodule($manifest, $dir, $global) { } function ensure_in_psmodulepath($dir, $global) { - $path = env 'psmodulepath' $global + $path = Get-EnvVar -Name 'PSModulePath' -Global:$global if (!$global -and $null -eq $path) { $path = "$env:USERPROFILE\Documents\WindowsPowerShell\Modules" } @@ -50,7 +50,6 @@ function ensure_in_psmodulepath($dir, $global) { if ($path -notmatch [Regex]::Escape($dir)) { Write-Output "Adding $(friendly_path $dir) to $(if($global){'global'}else{'your'}) PowerShell module path." - env 'psmodulepath' $global "$dir;$path" # for future sessions... - $env:psmodulepath = "$dir;$env:psmodulepath" # for this session + Set-EnvVar -Name 'PSModulePath' -Value "$dir;$path" -Global:$global } } diff --git a/lib/system.ps1 b/lib/system.ps1 new file mode 100644 index 0000000000..aa26cf2af0 --- /dev/null +++ b/lib/system.ps1 @@ -0,0 +1,158 @@ +# System-related functions + +## Environment Variables + +function Publish-EnvVar { + if (-not ('Win32.NativeMethods' -as [Type])) { + Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @' +[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] +public static extern IntPtr SendMessageTimeout( + IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, + uint fuFlags, uint uTimeout, out UIntPtr lpdwResult +); +'@ + } + + $HWND_BROADCAST = [IntPtr] 0xffff + $WM_SETTINGCHANGE = 0x1a + $result = [UIntPtr]::Zero + + [Win32.NativeMethods]::SendMessageTimeout($HWND_BROADCAST, + $WM_SETTINGCHANGE, + [UIntPtr]::Zero, + 'Environment', + 2, + 5000, + [ref] $result + ) | Out-Null +} + +function Get-EnvVar { + param( + [string]$Name, + [switch]$Global + ) + + $registerKey = if ($Global) { + Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' + } else { + Get-Item -Path 'HKCU:' + } + $envRegisterKey = $registerKey.OpenSubKey('Environment') + $registryValueOption = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames + $envRegisterKey.GetValue($Name, $null, $registryValueOption) +} + +function Set-EnvVar { + param( + [string]$Name, + [string]$Value, + [switch]$Global + ) + + $registerKey = if ($Global) { + Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' + } else { + Get-Item -Path 'HKCU:' + } + $envRegisterKey = $registerKey.OpenSubKey('Environment', $true) + if ($null -eq $Value -or $Value -eq '') { + $envRegisterKey.DeleteValue($Name) + } else { + $registryValueKind = if ($Value.Contains('%')) { + [Microsoft.Win32.RegistryValueKind]::ExpandString + } elseif ($envRegisterKey.GetValue($Name)) { + $envRegisterKey.GetValueKind($Name) + } else { + [Microsoft.Win32.RegistryValueKind]::String + } + $envRegisterKey.SetValue($Name, $Value, $registryValueKind) + } + Publish-EnvVar +} + +function Test-PathLikeEnvVar { + param( + [string]$Name, + [string]$Path + ) + + if ($null -eq $Path -and $Path -eq '') { + return $false, $null + } else { + $strippedPath = $Path.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries).Where({ $_ -ne $Name }) -join ';' + return ($strippedPath -ne $Path), $strippedPath + } +} + +function Add-Path { + param( + [string]$Path, + [switch]$Global, + [switch]$Force + ) + + if (!$Path.Contains('%')) { + $Path = fullpath $Path + } + # future sessions + $inPath, $strippedPath = Test-PathLikeEnvVar $Path (Get-EnvVar -Name 'PATH' -Global:$Global) + if (!$inPath -or $Force) { + Write-Output "Adding $(friendly_path $Path) to $(if ($Global) {'global'} else {'your'}) path." + Set-EnvVar -Name 'PATH' -Value (@($Path, $strippedPath) -join ';') -Global:$Global + } + # current session + $inPath, $strippedPath = Test-PathLikeEnvVar $Path $env:PATH + if (!$inPath -or $Force) { + $env:PATH = @($Path, $strippedPath) -join ';' + } +} + +function Remove-Path { + param( + [string]$Path, + [switch]$Global + ) + + if (!$Path.Contains('%')) { + $Path = fullpath $Path + } + # future sessions + $inPath, $strippedPath = Test-PathLikeEnvVar $Path (Get-EnvVar -Name 'PATH' -Global:$Global) + if ($inPath) { + Write-Output "Removing $(friendly_path $Path) from $(if ($Global) {'global'} else {'your'}) path." + Set-EnvVar -Name 'PATH' -Value $strippedPath -Global:$Global + } + # current session + $inPath, $strippedPath = Test-PathLikeEnvVar $Path $env:PATH + if ($inPath) { + $env:PATH = $strippedPath + } +} + +## Deprecated functions + +function env($name, $global, $val) { + if ($PSBoundParameters.ContainsKey('val')) { + Show-DeprecatedWarning $MyInvocation 'Set-EnvVar' + Set-EnvVar -Name $name -Value $val -Global:$global + } else { + Show-DeprecatedWarning $MyInvocation 'Get-EnvVar' + Get-EnvVar -Name $name -Global:$global + } +} + +function strip_path($orig_path, $dir) { + Show-DeprecatedWarning $MyInvocation 'Test-PathLikeEnvVar' + Test-PathLikeEnvVar -Name $dir -Path $orig_path +} + +function add_first_in_path($dir, $global) { + Show-DeprecatedWarning $MyInvocation 'Add-Path' + Add-Path -Path $dir -Global:$global -Force +} + +function remove_from_path($dir, $global) { + Show-DeprecatedWarning $MyInvocation 'Remove-Path' + Remove-Path -Path $dir -Global:$global +} diff --git a/libexec/scoop-install.ps1 b/libexec/scoop-install.ps1 index 61cad28883..fac03d71f4 100644 --- a/libexec/scoop-install.ps1 +++ b/libexec/scoop-install.ps1 @@ -25,6 +25,7 @@ . "$PSScriptRoot\..\lib\json.ps1" # 'autoupdate.ps1' 'manifest.ps1' (indirectly) . "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly) . "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest' 'Select-CurrentVersion' (indirectly) +. "$PSScriptRoot\..\lib\system.ps1" . "$PSScriptRoot\..\lib\install.ps1" . "$PSScriptRoot\..\lib\decompress.ps1" . "$PSScriptRoot\..\lib\shortcuts.ps1" diff --git a/libexec/scoop-reset.ps1 b/libexec/scoop-reset.ps1 index c30eeb6e1b..e073cd4dfb 100644 --- a/libexec/scoop-reset.ps1 +++ b/libexec/scoop-reset.ps1 @@ -8,6 +8,7 @@ . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\manifest.ps1" # 'Select-CurrentVersion' (indirectly) +. "$PSScriptRoot\..\lib\system.ps1" # 'env_add_path' (indirectly) . "$PSScriptRoot\..\lib\install.ps1" . "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion' . "$PSScriptRoot\..\lib\shortcuts.ps1" diff --git a/libexec/scoop-uninstall.ps1 b/libexec/scoop-uninstall.ps1 index 44f5561db5..7931158eec 100644 --- a/libexec/scoop-uninstall.ps1 +++ b/libexec/scoop-uninstall.ps1 @@ -8,6 +8,7 @@ . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest' 'Select-CurrentVersion' (indirectly) +. "$PSScriptRoot\..\lib\system.ps1" . "$PSScriptRoot\..\lib\install.ps1" . "$PSScriptRoot\..\lib\shortcuts.ps1" . "$PSScriptRoot\..\lib\psmodules.ps1" diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index e632be72fb..517aeeed1e 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -16,6 +16,7 @@ . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\json.ps1" # 'save_install_info' in 'manifest.ps1' (indirectly) +. "$PSScriptRoot\..\lib\system.ps1" . "$PSScriptRoot\..\lib\shortcuts.ps1" . "$PSScriptRoot\..\lib\psmodules.ps1" . "$PSScriptRoot\..\lib\decompress.ps1" diff --git a/test/Scoop-Core.Tests.ps1 b/test/Scoop-Core.Tests.ps1 index 4c95067e23..3fb7fbd663 100644 --- a/test/Scoop-Core.Tests.ps1 +++ b/test/Scoop-Core.Tests.ps1 @@ -1,6 +1,7 @@ BeforeAll { . "$PSScriptRoot\Scoop-TestLib.ps1" . "$PSScriptRoot\..\lib\core.ps1" + . "$PSScriptRoot\..\lib\system.ps1" . "$PSScriptRoot\..\lib\install.ps1" } @@ -167,7 +168,7 @@ Describe 'shim' -Tag 'Scoop', 'Windows' { BeforeAll { $working_dir = setup_working 'shim' $shimdir = shimdir - $(ensure_in_path $shimdir) | Out-Null + Add-Path $shimdir } It "links a file onto the user's path" { @@ -201,7 +202,7 @@ Describe 'rm_shim' -Tag 'Scoop', 'Windows' { BeforeAll { $working_dir = setup_working 'shim' $shimdir = shimdir - $(ensure_in_path $shimdir) | Out-Null + Add-Path $shimdir } It 'removes shim from path' { @@ -220,7 +221,7 @@ Describe 'get_app_name_from_shim' -Tag 'Scoop', 'Windows' { BeforeAll { $working_dir = setup_working 'shim' $shimdir = shimdir - $(ensure_in_path $shimdir) | Out-Null + Add-Path $shimdir Mock appsdir { $working_dir } } @@ -258,36 +259,6 @@ Describe 'get_app_name_from_shim' -Tag 'Scoop', 'Windows' { } } -Describe 'ensure_robocopy_in_path' -Tag 'Scoop', 'Windows' { - BeforeAll { - $shimdir = shimdir $false - Mock versiondir { "$PSScriptRoot\.." } - } - - It 'shims robocopy when not on path' { - Mock Test-CommandAvailable { $false } - Test-CommandAvailable robocopy | Should -Be $false - - ensure_robocopy_in_path - - # "$shimdir/robocopy.ps1" | should -exist - "$shimdir/robocopy.exe" | Should -Exist - - # clean up - rm_shim robocopy $(shimdir $false) | Out-Null - } - - It 'does not shim robocopy when it is in path' { - Mock Test-CommandAvailable { $true } - Test-CommandAvailable robocopy | Should -Be $true - - ensure_robocopy_in_path - - # "$shimdir/robocopy.ps1" | should -not -exist - "$shimdir/robocopy.exe" | Should -Not -Exist - } -} - Describe 'sanitary_path' -Tag 'Scoop' { It 'removes invalid path characters from a string' { $path = 'test?.json' diff --git a/test/Scoop-Install.Tests.ps1 b/test/Scoop-Install.Tests.ps1 index bafdfbe847..140327d11f 100644 --- a/test/Scoop-Install.Tests.ps1 +++ b/test/Scoop-Install.Tests.ps1 @@ -1,6 +1,7 @@ BeforeAll { . "$PSScriptRoot\Scoop-TestLib.ps1" . "$PSScriptRoot\..\lib\core.ps1" + . "$PSScriptRoot\..\lib\system.ps1" . "$PSScriptRoot\..\lib\manifest.ps1" . "$PSScriptRoot\..\lib\install.ps1" } @@ -57,17 +58,17 @@ Describe 'env add and remove path' -Tag 'Scoop', 'Windows' { } It 'should concat the correct path' { - Mock add_first_in_path {} - Mock remove_from_path {} + Mock Add-Path {} + Mock Remove-Path {} # adding env_add_path $manifest $testdir $global - Assert-MockCalled add_first_in_path -Times 1 -ParameterFilter { $dir -like "$testdir\foo" } - Assert-MockCalled add_first_in_path -Times 1 -ParameterFilter { $dir -like "$testdir\bar" } + Assert-MockCalled Add-Path -Times 1 -ParameterFilter { $Path -like "$testdir\foo" } + Assert-MockCalled Add-Path -Times 1 -ParameterFilter { $Path -like "$testdir\bar" } env_rm_path $manifest $testdir $global - Assert-MockCalled remove_from_path -Times 1 -ParameterFilter { $dir -like "$testdir\foo" } - Assert-MockCalled remove_from_path -Times 1 -ParameterFilter { $dir -like "$testdir\bar" } + Assert-MockCalled Remove-Path -Times 1 -ParameterFilter { $Path -like "$testdir\foo" } + Assert-MockCalled Remove-Path -Times 1 -ParameterFilter { $Path -like "$testdir\bar" } } } From dfbeace06607494c07cc49408df9ad66fb3778bb Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Mon, 1 Apr 2024 18:02:32 +0800 Subject: [PATCH 2/8] fix(system): Remove EnvVar only if existed (#5858) --- CHANGELOG.md | 2 +- lib/system.ps1 | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51322fd91f..e14e1d7697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,7 @@ - **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122), [#5375](https://github.com/ScoopInstaller/Scoop/issues/5375)) - **scoop-download:** Output more detailed manifest information ([#5277](https://github.com/ScoopInstaller/Scoop/issues/5277)) - **core:** Cleanup some old codes, e.g., msi section and config migration ([#5715](https://github.com/ScoopInstaller/Scoop/issues/5715), [#5824](https://github.com/ScoopInstaller/Scoop/issues/5824)) -- **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836)) +- **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836), [#5858](https://github.com/ScoopInstaller/Scoop/issues/5858)) ### Builds diff --git a/lib/system.ps1 b/lib/system.ps1 index aa26cf2af0..388cbfb783 100644 --- a/lib/system.ps1 +++ b/lib/system.ps1 @@ -57,7 +57,9 @@ function Set-EnvVar { } $envRegisterKey = $registerKey.OpenSubKey('Environment', $true) if ($null -eq $Value -or $Value -eq '') { - $envRegisterKey.DeleteValue($Name) + if ($envRegisterKey.GetValue($Name)) { + $envRegisterKey.DeleteValue($Name) + } } else { $registryValueKind = if ($Value.Contains('%')) { [Microsoft.Win32.RegistryValueKind]::ExpandString From 9ef03c24fb67e394b414ca36f2c9194d5cf48bfb Mon Sep 17 00:00:00 2001 From: David Watson Date: Mon, 1 Apr 2024 06:31:01 -0400 Subject: [PATCH 3/8] perf(scoop-update): Check for running process before wasting time on download (#5799) --- CHANGELOG.md | 1 + libexec/scoop-update.ps1 | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e14e1d7697..6693705877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ - **decompress:** Disable progress bar to improve `Expand-Archive` performance ([#5410](https://github.com/ScoopInstaller/Scoop/issues/5410)) - **scoop-search:** Improve performance for local search ([#5324](https://github.com/ScoopInstaller/Scoop/issues/5324)) +- **scoop-update:** Check for running process before wasting time on download ([#5799](https://github.com/ScoopInstaller/Scoop/issues/5799)) - **shim:** Update kiennq-shim to v3.1.1 ([#5841](https://github.com/ScoopInstaller/Scoop/issues/5841), ([#5847](https://github.com/ScoopInstaller/Scoop/issues/5847))) ### Code Refactoring diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 517aeeed1e..60c50ad4b2 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -241,6 +241,13 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c Write-Host "Updating '$app' ($old_version -> $version)" + #region Workaround for #2952 + if (test_running_process $app $global) { + Write-Host 'Running process detected, skip updating.' + return + } + #endregion Workaround for #2952 + # region Workaround # Workaround for https://github.com/ScoopInstaller/Scoop/issues/2220 until install is refactored # Remove and replace whole region after proper fix @@ -281,12 +288,6 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c Invoke-HookScript -HookType 'pre_uninstall' -Manifest $old_manifest -Arch $architecture - #region Workaround for #2952 - if (test_running_process $app $global) { - return - } - #endregion Workaround for #2952 - Write-Host "Uninstalling '$app' ($old_version)" run_uninstaller $old_manifest $architecture $dir rm_shims $app $old_manifest $global $architecture From 0b135052ce1b9936deda9cabed25ec55b2ac68a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Svraka?= Date: Thu, 4 Apr 2024 15:39:51 +0200 Subject: [PATCH 4/8] fix(scoop-shim): Import system.ps1 (#5864) --- CHANGELOG.md | 2 +- libexec/scoop-shim.ps1 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6693705877..49348cf15f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,7 +59,7 @@ - **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122), [#5375](https://github.com/ScoopInstaller/Scoop/issues/5375)) - **scoop-download:** Output more detailed manifest information ([#5277](https://github.com/ScoopInstaller/Scoop/issues/5277)) - **core:** Cleanup some old codes, e.g., msi section and config migration ([#5715](https://github.com/ScoopInstaller/Scoop/issues/5715), [#5824](https://github.com/ScoopInstaller/Scoop/issues/5824)) -- **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836), [#5858](https://github.com/ScoopInstaller/Scoop/issues/5858)) +- **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836), [#5858](https://github.com/ScoopInstaller/Scoop/issues/5858), [#5864](https://github.com/ScoopInstaller/Scoop/issues/5864)) ### Builds diff --git a/libexec/scoop-shim.ps1 b/libexec/scoop-shim.ps1 index cf775b1d6b..877b65b2e9 100644 --- a/libexec/scoop-shim.ps1 +++ b/libexec/scoop-shim.ps1 @@ -35,6 +35,7 @@ param($SubCommand) . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\install.ps1" # for rm_shim +. "$PSScriptRoot\..\lib\system.ps1" # 'Add-Path' (indirectly) if ($SubCommand -notin @('add', 'rm', 'list', 'info', 'alter')) { if (!$SubCommand) { From 5a06eacd9ca0e04c4a5f2624809adb71347112c0 Mon Sep 17 00:00:00 2001 From: HUMORCE Date: Mon, 8 Apr 2024 15:23:57 +0000 Subject: [PATCH 5/8] refactor(helper): Remove 7zip's fallback '7zip-zstd' (#5548) --- CHANGELOG.md | 1 + lib/core.ps1 | 7 +------ libexec/scoop-checkup.ps1 | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49348cf15f..d11f225165 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ - **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122), [#5375](https://github.com/ScoopInstaller/Scoop/issues/5375)) - **scoop-download:** Output more detailed manifest information ([#5277](https://github.com/ScoopInstaller/Scoop/issues/5277)) +- **helper:** Remove 7zip's fallback '7zip-zstd' ([#5548](https://github.com/ScoopInstaller/Scoop/issues/5548)) - **core:** Cleanup some old codes, e.g., msi section and config migration ([#5715](https://github.com/ScoopInstaller/Scoop/issues/5715), [#5824](https://github.com/ScoopInstaller/Scoop/issues/5824)) - **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836), [#5858](https://github.com/ScoopInstaller/Scoop/issues/5858), [#5864](https://github.com/ScoopInstaller/Scoop/issues/5864)) diff --git a/lib/core.ps1 b/lib/core.ps1 index af62b8156e..5e60cb3c0f 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -423,12 +423,7 @@ function Get-HelperPath { $HelperPath = (Get-Command git -ErrorAction Ignore).Source } } - '7zip' { - $HelperPath = Get-AppFilePath '7zip' '7z.exe' - if ([String]::IsNullOrEmpty($HelperPath)) { - $HelperPath = Get-AppFilePath '7zip-zstd' '7z.exe' - } - } + '7zip' { $HelperPath = Get-AppFilePath '7zip' '7z.exe' } 'Lessmsi' { $HelperPath = Get-AppFilePath 'lessmsi' 'lessmsi.exe' } 'Innounp' { $HelperPath = Get-AppFilePath 'innounp' 'innounp.exe' } 'Dark' { diff --git a/libexec/scoop-checkup.ps1 b/libexec/scoop-checkup.ps1 index 02def4eaa5..32b0ef4a5a 100644 --- a/libexec/scoop-checkup.ps1 +++ b/libexec/scoop-checkup.ps1 @@ -20,7 +20,7 @@ $issues += !(check_long_paths) $issues += !(Get-WindowsDeveloperModeStatus) if (!(Test-HelperInstalled -Helper 7zip) -and !(get_config USE_EXTERNAL_7ZIP)) { - warn "'7-Zip' is not installed! It's required for unpacking most programs. Please Run 'scoop install 7zip' or 'scoop install 7zip-zstd'." + warn "'7-Zip' is not installed! It's required for unpacking most programs. Please Run 'scoop install 7zip'." $issues++ } From b008fe5b117c050d42506518dc38356200ad1812 Mon Sep 17 00:00:00 2001 From: Xuesong Date: Mon, 8 Apr 2024 23:24:18 +0800 Subject: [PATCH 6/8] fix(scoop-virustotal): escape character not available in PowerShell 5.1 (#5870) --- CHANGELOG.md | 1 + libexec/scoop-virustotal.ps1 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d11f225165..79612b524f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ - **update/uninstall:** Remove items from PATH correctly ([#5833](https://github.com/ScoopInstaller/Scoop/issues/5833)) - **shim:** Allow GUI applications to attach to the shell's console when launched using the GUI shim ([#5721](https://github.com/ScoopInstaller/Scoop/issues/5721)) - **core:** Fix arguments parsing method of `Invoke-ExternalCommand()` ([#5839](https://github.com/ScoopInstaller/Scoop/issues/5839)) +- **scoop-virustotal:** Fix the issue that escape character not available in PowerShell 5.1 ([#5870](https://github.com/ScoopInstaller/Scoop/issues/5870)) ### Performance Improvements diff --git a/libexec/scoop-virustotal.ps1 b/libexec/scoop-virustotal.ps1 index 93b60f232d..e1e7b9f75c 100644 --- a/libexec/scoop-virustotal.ps1 +++ b/libexec/scoop-virustotal.ps1 @@ -136,7 +136,7 @@ Function Get-VirusTotalResultByHash ($hash, $url, $app) { warn "$app`: $unsafe/$total, see $report_url" } Default { - warn "`e[31m$app`: $unsafe/$total, see $report_url`e[0m" + warn "$([char]0x1b)[31m$app`: $unsafe/$total, see $report_url$([char]0x1b)[0m" } } $maliciousResults = $vendorResults | From 81e7dec78ccacaf65311b71c88676422d26a4ef5 Mon Sep 17 00:00:00 2001 From: HUMORCE Date: Mon, 8 Apr 2024 15:26:38 +0000 Subject: [PATCH 7/8] fix(scoop-alias): Prevent overwrite existing file when adding alias (#5577) Co-authored-by: Hsiao-nan Cheung --- CHANGELOG.md | 1 + libexec/scoop-alias.ps1 | 11 +++++++---- test/Scoop-Alias.Tests.ps1 | 13 +++++++------ test/Scoop-Versions.Tests.ps1 | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79612b524f..7912cc5d07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ - **update/uninstall:** Remove items from PATH correctly ([#5833](https://github.com/ScoopInstaller/Scoop/issues/5833)) - **shim:** Allow GUI applications to attach to the shell's console when launched using the GUI shim ([#5721](https://github.com/ScoopInstaller/Scoop/issues/5721)) - **core:** Fix arguments parsing method of `Invoke-ExternalCommand()` ([#5839](https://github.com/ScoopInstaller/Scoop/issues/5839)) +- **scoop-alias:** Prevent overwrite existing file when adding alias ([#5577](https://github.com/ScoopInstaller/Scoop/issues/5577)) - **scoop-virustotal:** Fix the issue that escape character not available in PowerShell 5.1 ([#5870](https://github.com/ScoopInstaller/Scoop/issues/5870)) ### Performance Improvements diff --git a/libexec/scoop-alias.ps1 b/libexec/scoop-alias.ps1 index d60884c351..48a956fd64 100644 --- a/libexec/scoop-alias.ps1 +++ b/libexec/scoop-alias.ps1 @@ -44,13 +44,16 @@ function add_alias($name, $command) { # get current aliases from config $aliases = init_alias_config if ($aliases.$name) { - abort "Alias $name already exists." + abort "Alias '$name' already exists." } $alias_file = "scoop-$name" # generate script $shimdir = shimdir $false + if (Test-Path "$shimdir\$alias_file.ps1") { + abort "File '$alias_file.ps1' already exists in shims directory." + } $script = @( "# Summary: $description", @@ -67,18 +70,18 @@ function add_alias($name, $command) { function rm_alias($name) { $aliases = init_alias_config if (!$name) { - abort 'Which alias should be removed?' + abort 'Alias to be removed has not been specified!' } if ($aliases.$name) { - "Removing alias $name..." + info "Removing alias '$name'..." rm_shim $aliases.$name (shimdir $false) $aliases.PSObject.Properties.Remove($name) set_config $script:config_alias $aliases | Out-Null } else { - abort "Alias $name doesn't exist." + abort "Alias '$name' doesn't exist." } } diff --git a/test/Scoop-Alias.Tests.ps1 b/test/Scoop-Alias.Tests.ps1 index bd365718a8..e6fd33e7eb 100644 --- a/test/Scoop-Alias.Tests.ps1 +++ b/test/Scoop-Alias.Tests.ps1 @@ -8,7 +8,7 @@ BeforeAll { Describe 'Manipulate Alias' -Tag 'Scoop' { BeforeAll { Mock shimdir { "$TestDrive\shims" } - Mock set_config { } + Mock set_config {} Mock get_config { @{} } $shimdir = shimdir @@ -23,23 +23,24 @@ Describe 'Manipulate Alias' -Tag 'Scoop' { & $alias_file | Should -Be 'hello, world!' } - It 'Does not change existing alias if alias exists' { + It 'Does not change existing file if its filename same as alias name' { $alias_file = "$shimdir\scoop-rm.ps1" + Mock abort {} New-Item $alias_file -Type File -Force $alias_file | Should -Exist - add_alias 'rm' 'test' - & $alias_file | Should -Not -Be 'test' + add_alias 'rm' '"test"' + Should -Invoke -CommandName abort -Times 1 -ParameterFilter { $msg -eq "File 'scoop-rm.ps1' already exists in shims directory." } } It 'Removes an existing alias' { $alias_file = "$shimdir\scoop-rm.ps1" - add_alias 'rm' '"hello, world!"' - $alias_file | Should -Exist Mock get_config { @(@{'rm' = 'scoop-rm' }) } + Mock info {} rm_alias 'rm' $alias_file | Should -Not -Exist + Should -Invoke -CommandName info -Times 1 -ParameterFilter { $msg -eq "Removing alias 'rm'..." } } } diff --git a/test/Scoop-Versions.Tests.ps1 b/test/Scoop-Versions.Tests.ps1 index 536f9cc7c3..7043ee07cf 100644 --- a/test/Scoop-Versions.Tests.ps1 +++ b/test/Scoop-Versions.Tests.ps1 @@ -99,7 +99,7 @@ Describe 'versions comparison' -Tag 'Scoop' { Compare-Version 'nightly-20190801' 'nightly-20200801' | Should -Be 0 } - It 'handles nightly versions with `update_nightly`' { + It "handles nightly versions with 'update_nightly'" { function get_config { $true } Mock Get-Date { '20200801' } Compare-Version 'nightly-20200801' 'nightly' | Should -Be 0 From 92b71c6057a1a594beeab416cc4d002da17867b1 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 10 Apr 2024 14:55:20 +0800 Subject: [PATCH 8/8] refactor(core): Get rid of 'fullpath' (#3533) --- CHANGELOG.md | 1 + bin/checkhashes.ps1 | 4 ++-- lib/autoupdate.ps1 | 2 +- lib/core.ps1 | 40 ++++++++++++++++++++++++++++-------- lib/install.ps1 | 13 +++++------- lib/psmodules.ps1 | 1 - lib/system.ps1 | 4 ++-- libexec/scoop-info.ps1 | 2 +- libexec/scoop-status.ps1 | 2 +- libexec/scoop-update.ps1 | 4 ++-- test/Scoop-Install.Tests.ps1 | 2 -- 11 files changed, 47 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7912cc5d07..235f360f0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ - **helper:** Remove 7zip's fallback '7zip-zstd' ([#5548](https://github.com/ScoopInstaller/Scoop/issues/5548)) - **core:** Cleanup some old codes, e.g., msi section and config migration ([#5715](https://github.com/ScoopInstaller/Scoop/issues/5715), [#5824](https://github.com/ScoopInstaller/Scoop/issues/5824)) - **core:** Rewrite and separate path-related functions to `system.ps1` ([#5836](https://github.com/ScoopInstaller/Scoop/issues/5836), [#5858](https://github.com/ScoopInstaller/Scoop/issues/5858), [#5864](https://github.com/ScoopInstaller/Scoop/issues/5864)) +- **core:** Get rid of 'fullpath' ([#3533](https://github.com/ScoopInstaller/Scoop/issues/3533)) ### Builds diff --git a/bin/checkhashes.ps1 b/bin/checkhashes.ps1 index 0420ee1fa8..cbfb0af40f 100644 --- a/bin/checkhashes.ps1 +++ b/bin/checkhashes.ps1 @@ -121,7 +121,7 @@ foreach ($current in $MANIFESTS) { Invoke-CachedDownload $current.app $version $_ $null $null -use_cache:$UseCache - $to_check = fullpath (cache_path $current.app $version $_) + $to_check = cache_path $current.app $version $_ $actual_hash = (Get-FileHash -Path $to_check -Algorithm $algorithm).Hash.ToLower() # Append type of algorithm to both expected and actual if it's not sha256 @@ -146,7 +146,7 @@ foreach ($current in $MANIFESTS) { Write-Host "$($current.app): " -NoNewline Write-Host 'Mismatch found ' -ForegroundColor Red $mismatched | ForEach-Object { - $file = fullpath (cache_path $current.app $version $current.urls[$_]) + $file = cache_path $current.app $version $current.urls[$_] Write-Host "`tURL:`t`t$($current.urls[$_])" if (Test-Path $file) { Write-Host "`tFirst bytes:`t$((get_magic_bytes_pretty $file ' ').ToUpper())" diff --git a/lib/autoupdate.ps1 b/lib/autoupdate.ps1 index 803e994b6c..c07fe6ba8a 100644 --- a/lib/autoupdate.ps1 +++ b/lib/autoupdate.ps1 @@ -278,7 +278,7 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u Write-Host "URL $url is not valid" -ForegroundColor DarkRed return $null } - $file = fullpath (cache_path $app $version $url) + $file = cache_path $app $version $url $hash = (Get-FileHash -Path $file -Algorithm SHA256).Hash.ToLower() Write-Host 'Computed hash: ' -ForegroundColor DarkYellow -NoNewline Write-Host $hash -ForegroundColor Green diff --git a/lib/core.ps1 b/lib/core.ps1 index 5e60cb3c0f..830ee7aae7 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -450,8 +450,8 @@ function Get-CommandPath { ) begin { - $userShims = Convert-Path (shimdir $false) - $globalShims = fullpath (shimdir $true) # don't resolve: may not exist + $userShims = shimdir $false + $globalShims = shimdir $true } process { @@ -571,9 +571,33 @@ function ensure($dir) { } Convert-Path -Path $dir } +function Get-AbsolutePath { + <# + .SYNOPSIS + Get absolute path + .DESCRIPTION + Get absolute path, even if not existed + .PARAMETER Path + Path to manipulate + .OUTPUTS + System.String + Absolute path, may or maynot existed + #> + [CmdletBinding()] + [OutputType([string])] + param ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] + $Path + ) + process { + return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) + } +} + function fullpath($path) { - # should be ~ rooted - $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path) + Show-DeprecatedWarning $MyInvocation 'Get-AbsolutePath' + return Get-AbsolutePath -Path $path } function friendly_path($path) { $h = (Get-PSProvider 'FileSystem').Home @@ -1300,7 +1324,7 @@ if ($pathExpected) { # ├─shims # ├─config.json # ``` - $configPortablePath = fullpath "$coreRoot\..\..\..\config.json" + $configPortablePath = Get-AbsolutePath "$coreRoot\..\..\..\config.json" if (Test-Path $configPortablePath) { $configFile = $configPortablePath } @@ -1308,17 +1332,17 @@ if ($pathExpected) { $scoopConfig = load_cfg $configFile # Scoop root directory -$scoopdir = $env:SCOOP, (get_config ROOT_PATH), (Resolve-Path "$PSScriptRoot\..\..\..\.."), "$([System.Environment]::GetFolderPath('UserProfile'))\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +$scoopdir = $env:SCOOP, (get_config ROOT_PATH), "$PSScriptRoot\..\..\..\..", "$([System.Environment]::GetFolderPath('UserProfile'))\scoop" | Where-Object { $_ } | Select-Object -First 1 | Get-AbsolutePath # Scoop global apps directory -$globaldir = $env:SCOOP_GLOBAL, (get_config GLOBAL_PATH), "$([System.Environment]::GetFolderPath('CommonApplicationData'))\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +$globaldir = $env:SCOOP_GLOBAL, (get_config GLOBAL_PATH), "$([System.Environment]::GetFolderPath('CommonApplicationData'))\scoop" | Where-Object { $_ } | Select-Object -First 1 | Get-AbsolutePath # Scoop cache directory # Note: Setting the SCOOP_CACHE environment variable to use a shared directory # is experimental and untested. There may be concurrency issues when # multiple users write and access cached files at the same time. # Use at your own risk. -$cachedir = $env:SCOOP_CACHE, (get_config CACHE_PATH), "$scoopdir\cache" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +$cachedir = $env:SCOOP_CACHE, (get_config CACHE_PATH), "$scoopdir\cache" | Where-Object { $_ } | Select-Object -First 1 | Get-AbsolutePath # OS information $WindowsBuild = [System.Environment]::OSVersion.Version.Build diff --git a/lib/install.ps1 b/lib/install.ps1 index 2a244b44c2..19f8d9b3f6 100644 --- a/lib/install.ps1 +++ b/lib/install.ps1 @@ -81,7 +81,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru } function Invoke-CachedDownload ($app, $version, $url, $to, $cookies = $null, $use_cache = $true) { - $cached = fullpath (cache_path $app $version $url) + $cached = cache_path $app $version $url if (!(Test-Path $cached) -or !$use_cache) { ensure $cachedir | Out-Null @@ -239,7 +239,7 @@ function Invoke-CachedAria2Download ($app, $version, $manifest, $architecture, $ $data.$url = @{ 'target' = "$dir\$(url_filename $url)" 'cachename' = fname (cache_path $app $version $url) - 'source' = fullpath (cache_path $app $version $url) + 'source' = cache_path $app $version $url } if ((Test-Path $data.$url.source) -and -not((Test-Path "$($data.$url.source).aria2") -or (Test-Path $urlstxt)) -and $use_cache) { @@ -638,9 +638,7 @@ function cookie_header($cookies) { } function is_in_dir($dir, $check) { - $check = "$(fullpath $check)" - $dir = "$(fullpath $dir)" - $check -match "^$([regex]::Escape("$dir"))([/\\]|`$)" + $check -match "^$([regex]::Escape("$dir"))([/\\]|$)" } function ftp_file_size($url) { @@ -665,7 +663,6 @@ function hash_for_url($manifest, $url, $arch) { # returns (ok, err) function check_hash($file, $hash, $app_name) { - $file = fullpath $file if (!$hash) { warn "Warning: No hash in manifest. SHA256 for '$(fname $file)' is:`n $((Get-FileHash -Path $file -Algorithm SHA256).Hash.ToLower())" return $true, $null @@ -1088,8 +1085,8 @@ function persist_data($manifest, $original_dir, $persist_dir) { $source = $source.TrimEnd('/').TrimEnd('\\') - $source = fullpath "$dir\$source" - $target = fullpath "$persist_dir\$target" + $source = "$dir\$source" + $target = "$persist_dir\$target" # if we have had persist data in the store, just create link and go if (Test-Path $target) { diff --git a/lib/psmodules.ps1 b/lib/psmodules.ps1 index 3ba2f6624a..9d0cb7ce8a 100644 --- a/lib/psmodules.ps1 +++ b/lib/psmodules.ps1 @@ -46,7 +46,6 @@ function ensure_in_psmodulepath($dir, $global) { if (!$global -and $null -eq $path) { $path = "$env:USERPROFILE\Documents\WindowsPowerShell\Modules" } - $dir = fullpath $dir if ($path -notmatch [Regex]::Escape($dir)) { Write-Output "Adding $(friendly_path $dir) to $(if($global){'global'}else{'your'}) PowerShell module path." diff --git a/lib/system.ps1 b/lib/system.ps1 index 388cbfb783..2a572a9fde 100644 --- a/lib/system.ps1 +++ b/lib/system.ps1 @@ -95,7 +95,7 @@ function Add-Path { ) if (!$Path.Contains('%')) { - $Path = fullpath $Path + $Path = Get-AbsolutePath $Path } # future sessions $inPath, $strippedPath = Test-PathLikeEnvVar $Path (Get-EnvVar -Name 'PATH' -Global:$Global) @@ -117,7 +117,7 @@ function Remove-Path { ) if (!$Path.Contains('%')) { - $Path = fullpath $Path + $Path = Get-AbsolutePath $Path } # future sessions $inPath, $strippedPath = Test-PathLikeEnvVar $Path (Get-EnvVar -Name 'PATH' -Global:$Global) diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1 index 3cf58e4118..853de647f9 100644 --- a/libexec/scoop-info.ps1 +++ b/libexec/scoop-info.ps1 @@ -160,7 +160,7 @@ if ($status.installed) { $totalPackage = 0 foreach ($url in @(url $manifest (Get-DefaultArchitecture))) { try { - if (Test-Path (fullpath (cache_path $app $manifest.version $url))) { + if (Test-Path (cache_path $app $manifest.version $url)) { $cached = " (latest version is cached)" } else { $cached = $null diff --git a/libexec/scoop-status.ps1 b/libexec/scoop-status.ps1 index c72f75bcbc..a62cad2dd1 100644 --- a/libexec/scoop-status.ps1 +++ b/libexec/scoop-status.ps1 @@ -8,7 +8,7 @@ . "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion' # check if scoop needs updating -$currentdir = fullpath $(versiondir 'scoop' 'current') +$currentdir = versiondir 'scoop' 'current' $needs_update = $false $bucket_needs_update = $false $script:network_failure = $false diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 60c50ad4b2..354fb2e839 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -71,7 +71,7 @@ function Sync-Scoop { if (!(Test-GitAvailable)) { abort "Scoop uses Git to update itself. Run 'scoop install git' and try again." } Write-Host "Updating Scoop..." - $currentdir = fullpath $(versiondir 'scoop' 'current') + $currentdir = versiondir 'scoop' 'current' if (!(Test-Path "$currentdir\.git")) { $newdir = "$currentdir\..\new" $olddir = "$currentdir\..\old" @@ -262,7 +262,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c if ($check_hash) { $manifest_hash = hash_for_url $manifest $url $architecture - $source = fullpath (cache_path $app $version $url) + $source = cache_path $app $version $url $ok, $err = check_hash $source $manifest_hash $(show_app $app $bucket) if (!$ok) { diff --git a/test/Scoop-Install.Tests.ps1 b/test/Scoop-Install.Tests.ps1 index 140327d11f..130d6a7517 100644 --- a/test/Scoop-Install.Tests.ps1 +++ b/test/Scoop-Install.Tests.ps1 @@ -38,8 +38,6 @@ Describe 'is_in_dir' -Tag 'Scoop', 'Windows' { It 'should work correctly' { is_in_dir 'C:\test' 'C:\foo' | Should -BeFalse is_in_dir 'C:\test' 'C:\test\foo\baz.zip' | Should -BeTrue - - is_in_dir 'test' "$PSScriptRoot" | Should -BeTrue is_in_dir "$PSScriptRoot\..\" "$PSScriptRoot" | Should -BeFalse } }