Skip to content

Commit

Permalink
refactor(core): Rewrite and separate path-related functions to `syste…
Browse files Browse the repository at this point in the history
…m.ps1` (#5836)
  • Loading branch information
niheaven committed Mar 27, 2024
1 parent 77b66cc commit 6772e61
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 167 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions bin/uninstall.ps1
Expand Up @@ -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"
Expand Down Expand Up @@ -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.'
126 changes: 11 additions & 115 deletions lib/core.ps1
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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())"
Expand Down Expand Up @@ -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)}) {
Expand Down Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions lib/install.ps1
Expand Up @@ -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." }

Expand Down Expand Up @@ -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)." }
}
Expand Down Expand Up @@ -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
}
}
}
Expand All @@ -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
}
}
}
Expand All @@ -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
}
}
Expand All @@ -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 }
}
}
Expand Down
5 changes: 2 additions & 3 deletions lib/psmodules.ps1
Expand Up @@ -42,15 +42,14 @@ 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"
}
$dir = fullpath $dir
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
}
}

0 comments on commit 6772e61

Please sign in to comment.