From 022e79a5fea585a002d1cb2031e3325b3ba3a436 Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Wed, 9 Mar 2022 18:16:27 +0800 Subject: [PATCH 1/5] fix(shim): Manipulating shims with UTF8 encoding Signed-off-by: Chawye Hsu --- lib/core.ps1 | 43 +++++++++++++++++++++++------------------ libexec/scoop-alias.ps1 | 2 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index 83e7a28aad..0c2fb13c64 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -479,8 +479,8 @@ function Invoke-ExternalCommand { return $false } if ($LogPath -and ($FilePath -notmatch '(^|\W)msiexec($|\W)')) { - Out-File -FilePath $LogPath -Encoding Default -Append -InputObject $Process.StandardOutput.ReadToEnd() - Out-File -FilePath $LogPath -Encoding Default -Append -InputObject $Process.StandardError.ReadToEnd() + Out-UTF8File -FilePath $LogPath -Append -InputObject $Process.StandardOutput.ReadToEnd() + Out-UTF8File -FilePath $LogPath -Append -InputObject $Process.StandardError.ReadToEnd() } $Process.WaitForExit() if ($Process.ExitCode -ne 0) { @@ -625,9 +625,9 @@ function shim($path, $global, $name, $arg) { # for programs with no awareness of any shell warn_on_overwrite "$shim.shim" $path Copy-Item (get_shim_path) "$shim.exe" -Force - Write-Output "path = `"$resolved_path`"" | Out-File "$shim.shim" -Encoding ASCII + Write-Output "path = `"$resolved_path`"" | Out-UTF8File "$shim.shim" if ($arg) { - Write-Output "args = $arg" | Out-File "$shim.shim" -Encoding ASCII -Append + Write-Output "args = $arg" | Out-UTF8File "$shim.shim" -Append } } elseif ($path -match '\.(bat|cmd)$') { # shim .bat, .cmd so they can be used by programs with no awareness of PSH @@ -635,14 +635,14 @@ function shim($path, $global, $name, $arg) { @( "@rem $resolved_path", "@`"$resolved_path`" $arg %*" - ) -join "`r`n" | Out-File "$shim.cmd" -Encoding ASCII + ) -join "`r`n" | Out-UTF8File "$shim.cmd" warn_on_overwrite $shim $path @( "#!/bin/sh", "# $resolved_path", "MSYS2_ARG_CONV_EXCL=/C cmd.exe /C `"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-File $shim -Encoding ASCII -NoNewline + ) -join "`n" | Out-UTF8File $shim } elseif ($path -match '\.ps1$') { # if $path points to another drive resolve-path prepends .\ which could break shims warn_on_overwrite "$shim.ps1" $path @@ -661,7 +661,7 @@ function shim($path, $global, $name, $arg) { "exit `$LASTEXITCODE" ) } - $ps1text -join "`r`n" | Out-File "$shim.ps1" -Encoding ASCII + $ps1text -join "`r`n" | Out-UTF8File "$shim.ps1" # make ps1 accessible from cmd.exe warn_on_overwrite "$shim.cmd" $path @@ -682,7 +682,7 @@ function shim($path, $global, $name, $arg) { ") else (", " powershell -noprofile -ex unrestricted -file `"$resolved_path`" $arg %args%", ")" - ) -join "`r`n" | Out-File "$shim.cmd" -Encoding ASCII + ) -join "`r`n" | Out-UTF8File "$shim.cmd" warn_on_overwrite $shim $path @( @@ -693,33 +693,33 @@ function shim($path, $global, $name, $arg) { "else", " powershell.exe -noprofile -ex unrestricted -file `"$resolved_path`" $arg $@", "fi" - ) -join "`n" | Out-File $shim -Encoding ASCII -NoNewline + ) -join "`n" | Out-UTF8File $shim } elseif ($path -match '\.jar$') { warn_on_overwrite "$shim.cmd" $path @( "@rem $resolved_path", "@java -jar `"$resolved_path`" $arg %*" - ) -join "`r`n" | Out-File "$shim.cmd" -Encoding ASCII + ) -join "`r`n" | Out-UTF8File "$shim.cmd" warn_on_overwrite $shim $path @( "#!/bin/sh", "# $resolved_path", "java.exe -jar `"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-File $shim -Encoding ASCII -NoNewline + ) -join "`n" | Out-UTF8File $shim } elseif ($path -match '\.py$') { warn_on_overwrite "$shim.cmd" $path @( "@rem $resolved_path", "@python `"$resolved_path`" $arg %*" - ) -join "`r`n" | Out-File "$shim.cmd" -Encoding ASCII + ) -join "`r`n" | Out-UTF8File "$shim.cmd" warn_on_overwrite $shim $path @( "#!/bin/sh", "# $resolved_path", "python.exe `"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-File $shim -Encoding ASCII -NoNewline + ) -join "`n" | Out-UTF8File $shim } else { warn_on_overwrite "$shim.cmd" $path # find path to Git's bash so that batch scripts can run bash scripts @@ -730,14 +730,14 @@ function shim($path, $global, $name, $arg) { @( "@rem $resolved_path", "@`"$(Join-Path (Join-Path $gitdir.FullName 'bin') 'bash.exe')`" `"$resolved_path`" $arg %*" - ) -join "`r`n" | Out-File "$shim.cmd" -Encoding ASCII + ) -join "`r`n" | Out-UTF8File "$shim.cmd" warn_on_overwrite $shim $path @( "#!/bin/sh", "# $resolved_path", "`"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-File $shim -Encoding ASCII -NoNewline + ) -join "`n" | Out-UTF8File $shim } } @@ -1101,14 +1101,19 @@ function Out-UTF8File { [Parameter(Mandatory = $True, Position = 0)] [Alias("Path")] [String] $FilePath, + [Switch] $Append, [Parameter(ValueFromPipeline = $True)] [PSObject] $InputObject ) process { - # Ref: https://stackoverflow.com/questions/5596982 - # Performance Note: `WriteAllLines` throttles memory usage while - # `WriteAllText` needs to keep the complete string in memory. - [System.IO.File]::WriteAllLines($FilePath, $InputObject) + if ($Append) { + [System.IO.File]::AppendAllText($FilePath, $InputObject) + } else { + # Ref: https://stackoverflow.com/questions/5596982 + # Performance Note: `WriteAllLines` throttles memory usage while + # `WriteAllText` needs to keep the complete string in memory. + [System.IO.File]::WriteAllLines($FilePath, $InputObject) + } } } diff --git a/libexec/scoop-alias.ps1 b/libexec/scoop-alias.ps1 index c639790cf3..cc919c743c 100644 --- a/libexec/scoop-alias.ps1 +++ b/libexec/scoop-alias.ps1 @@ -58,7 +58,7 @@ function add_alias($name, $command) { # Summary: $description $command "@ - $script | Out-File "$shimdir\$alias_file.ps1" -Encoding ASCII + $script | Out-UTF8File "$shimdir\$alias_file.ps1" # add alias to config $aliases | Add-Member -MemberType NoteProperty -Name $name -Value $alias_file From 0e06d2ad89a21576aaf4d4821f3c70649ae1b3eb Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Wed, 9 Mar 2022 18:31:52 +0800 Subject: [PATCH 2/5] fix(tests): Tests fix Signed-off-by: Chawye Hsu --- test/Scoop-Alias.Tests.ps1 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/Scoop-Alias.Tests.ps1 b/test/Scoop-Alias.Tests.ps1 index 9d3f4078b6..c2ebb9db98 100644 --- a/test/Scoop-Alias.Tests.ps1 +++ b/test/Scoop-Alias.Tests.ps1 @@ -3,12 +3,11 @@ reset_aliases Describe 'add_alias' -Tag 'Scoop' { - Mock shimdir { 'TestDrive:\shim' } + Mock shimdir { "$env:TEMP\shims" } Mock set_config { } Mock get_config { @{} } $shimdir = shimdir - mkdir $shimdir Context "alias doesn't exist" { It 'creates a new alias' { @@ -23,7 +22,7 @@ Describe 'add_alias' -Tag 'Scoop' { Context 'alias exists' { It 'does not change existing alias' { $alias_file = "$shimdir\scoop-rm.ps1" - New-Item $alias_file -type file + New-Item $alias_file -Type File -Force $alias_file | Should -Exist add_alias 'rm' 'test' @@ -33,12 +32,11 @@ Describe 'add_alias' -Tag 'Scoop' { } Describe 'rm_alias' -Tag 'Scoop' { - Mock shimdir { 'TestDrive:\shim' } + Mock shimdir { "$env:TEMP\shims" } Mock set_config { } Mock get_config { @{} } $shimdir = shimdir - mkdir $shimdir Context 'alias exists' { It 'removes an existing alias' { From 0a0b9c05aac1368e06129221038ead59ec4e4582 Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Wed, 9 Mar 2022 18:44:16 +0800 Subject: [PATCH 3/5] fix(tests): Tests fix Signed-off-by: Chawye Hsu --- test/Scoop-Alias.Tests.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/Scoop-Alias.Tests.ps1 b/test/Scoop-Alias.Tests.ps1 index c2ebb9db98..be913af67d 100644 --- a/test/Scoop-Alias.Tests.ps1 +++ b/test/Scoop-Alias.Tests.ps1 @@ -8,6 +8,7 @@ Describe 'add_alias' -Tag 'Scoop' { Mock get_config { @{} } $shimdir = shimdir + New-Item -ItemType Directory -Path $shimdir -ErrorAction Ignore Context "alias doesn't exist" { It 'creates a new alias' { @@ -37,6 +38,7 @@ Describe 'rm_alias' -Tag 'Scoop' { Mock get_config { @{} } $shimdir = shimdir + New-Item -ItemType Directory -Path $shimdir -ErrorAction Ignore Context 'alias exists' { It 'removes an existing alias' { From cbbc6beddff4b2884a0e715dd80730c6bfa24a24 Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Thu, 10 Mar 2022 01:24:11 +0800 Subject: [PATCH 4/5] Add NoNewLine option Signed-off-by: Chawye Hsu --- lib/core.ps1 | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index 0c2fb13c64..eef33586ff 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -642,7 +642,7 @@ function shim($path, $global, $name, $arg) { "#!/bin/sh", "# $resolved_path", "MSYS2_ARG_CONV_EXCL=/C cmd.exe /C `"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-UTF8File $shim + ) -join "`n" | Out-UTF8File $shim -NoNewLine } elseif ($path -match '\.ps1$') { # if $path points to another drive resolve-path prepends .\ which could break shims warn_on_overwrite "$shim.ps1" $path @@ -693,7 +693,7 @@ function shim($path, $global, $name, $arg) { "else", " powershell.exe -noprofile -ex unrestricted -file `"$resolved_path`" $arg $@", "fi" - ) -join "`n" | Out-UTF8File $shim + ) -join "`n" | Out-UTF8File $shim -NoNewLine } elseif ($path -match '\.jar$') { warn_on_overwrite "$shim.cmd" $path @( @@ -706,7 +706,7 @@ function shim($path, $global, $name, $arg) { "#!/bin/sh", "# $resolved_path", "java.exe -jar `"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-UTF8File $shim + ) -join "`n" | Out-UTF8File $shim -NoNewLine } elseif ($path -match '\.py$') { warn_on_overwrite "$shim.cmd" $path @( @@ -719,7 +719,7 @@ function shim($path, $global, $name, $arg) { "#!/bin/sh", "# $resolved_path", "python.exe `"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-UTF8File $shim + ) -join "`n" | Out-UTF8File $shim -NoNewLine } else { warn_on_overwrite "$shim.cmd" $path # find path to Git's bash so that batch scripts can run bash scripts @@ -737,7 +737,7 @@ function shim($path, $global, $name, $arg) { "#!/bin/sh", "# $resolved_path", "`"$resolved_path`" $arg `"$@`"" - ) -join "`n" | Out-UTF8File $shim + ) -join "`n" | Out-UTF8File $shim -NoNewLine } } @@ -1102,6 +1102,7 @@ function Out-UTF8File { [Alias("Path")] [String] $FilePath, [Switch] $Append, + [Switch] $NoNewLine, [Parameter(ValueFromPipeline = $True)] [PSObject] $InputObject ) @@ -1109,10 +1110,15 @@ function Out-UTF8File { if ($Append) { [System.IO.File]::AppendAllText($FilePath, $InputObject) } else { - # Ref: https://stackoverflow.com/questions/5596982 - # Performance Note: `WriteAllLines` throttles memory usage while - # `WriteAllText` needs to keep the complete string in memory. - [System.IO.File]::WriteAllLines($FilePath, $InputObject) + if (!$NoNewLine) { + # Ref: https://stackoverflow.com/questions/5596982 + # Performance Note: `WriteAllLines` throttles memory usage while + # `WriteAllText` needs to keep the complete string in memory. + [System.IO.File]::WriteAllLines($FilePath, $InputObject) + } else { + # However `WriteAllText` does not add ending newline. + [System.IO.File]::WriteAllText($FilePath, $InputObject) + } } } } From 77f2f4c5c1346b7d718212ee56ae5a8493bd4e10 Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Thu, 10 Mar 2022 15:35:49 +0800 Subject: [PATCH 5/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66373a2dbe..fa044a0401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Bug Fixes +- **shim:** Manipulating shims with UTF8 encoding ([#4791](https://github.com/ScoopInstaller/Scoop/issues/4791)) - **installed:** If no `$global`, check both local and global installed ([#4798](https://github.com/ScoopInstaller/Scoop/issues/4798)) - **scoop-prefix:** Fix typo that breaks global installed apps ([#4795](https://github.com/ScoopInstaller/Scoop/issues/4795))