From 360daa706a583ff63a91d9ed61cd833d271b1c0f Mon Sep 17 00:00:00 2001
From: Richard Kuhnt
Date: Wed, 23 Nov 2022 06:58:51 +0100
Subject: [PATCH 01/75] feat(chore): Improve git.exe execution and add parallel
bucket updates (#5122)
---
CHANGELOG.md | 8 +++
bin/scoop.ps1 | 8 +--
lib/buckets.ps1 | 14 ++---
lib/core.ps1 | 89 +++++++++++++++++++++++++--
libexec/scoop-info.ps1 | 2 +-
libexec/scoop-status.ps1 | 6 +-
libexec/scoop-update.ps1 | 126 +++++++++++++++++++++++----------------
7 files changed, 179 insertions(+), 74 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ae5f38000..4b9b155d5b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## [Unreleased](https://github.com/ScoopInstaller/Scoop/compare/master...develop)
+
+### Features
+- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/pull/5122))
+
+### Code Refactoring
+- **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/pull/5122))
+
## [v0.3.1](https://github.com/ScoopInstaller/Scoop/compare/v0.3.0...v0.3.1) - 2022-11-15
### Features
diff --git a/bin/scoop.ps1 b/bin/scoop.ps1
index 6d96c68b2f..fd2fd41fa7 100644
--- a/bin/scoop.ps1
+++ b/bin/scoop.ps1
@@ -20,8 +20,8 @@ switch ($subCommand) {
}
({ $subCommand -in @('-v', '--version') }) {
Write-Host 'Current Scoop version:'
- if ((Test-CommandAvailable git) -and (Test-Path "$PSScriptRoot\..\.git") -and (get_config SCOOP_BRANCH 'master') -ne 'master') {
- git -C "$PSScriptRoot\.." --no-pager log --oneline HEAD -n 1
+ if (Test-GitAvailable -and (Test-Path "$PSScriptRoot\..\.git") -and (get_config SCOOP_BRANCH 'master') -ne 'master') {
+ Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('log', 'HEAD', '-1', '--oneline')
} else {
$version = Select-String -Pattern '^## \[(v[\d.]+)\].*?([\d-]+)$' -Path "$PSScriptRoot\..\CHANGELOG.md"
Write-Host $version.Matches.Groups[1].Value -ForegroundColor Cyan -NoNewline
@@ -31,9 +31,9 @@ switch ($subCommand) {
Get-LocalBucket | ForEach-Object {
$bucketLoc = Find-BucketDirectory $_ -Root
- if ((Test-Path "$bucketLoc\.git") -and (Test-CommandAvailable git)) {
+ if (Test-GitAvailable -and (Test-Path "$bucketLoc\.git")) {
Write-Host "'$_' bucket:"
- git -C "$bucketLoc" --no-pager log --oneline HEAD -n 1
+ Invoke-Git -Path $bucketLoc -ArgumentList @('log', 'HEAD', '-1', '--oneline')
Write-Host ''
}
}
diff --git a/lib/buckets.ps1 b/lib/buckets.ps1
index 2a03561210..704d51a82b 100644
--- a/lib/buckets.ps1
+++ b/lib/buckets.ps1
@@ -99,8 +99,8 @@ function list_buckets {
$bucket = [Ordered]@{ Name = $_ }
$path = Find-BucketDirectory $_ -Root
if ((Test-Path (Join-Path $path '.git')) -and (Get-Command git -ErrorAction SilentlyContinue)) {
- $bucket.Source = git -C $path config remote.origin.url
- $bucket.Updated = git -C $path log --format='%aD' -n 1 | Get-Date
+ $bucket.Source = Invoke-Git -Path $path -ArgumentList @('config', 'remote.origin.url')
+ $bucket.Updated = Invoke-Git -Path $path -ArgumentList @('log', "--format='%aD'", '-n', '1')
} else {
$bucket.Source = friendly_path $path
$bucket.Updated = (Get-Item "$path\bucket").LastWriteTime
@@ -113,7 +113,7 @@ function list_buckets {
}
function add_bucket($name, $repo) {
- if (!(Test-CommandAvailable git)) {
+ if (!(Test-GitAvailable)) {
error "Git is required for buckets. Run 'scoop install git' and try again."
return 1
}
@@ -130,7 +130,7 @@ function add_bucket($name, $repo) {
}
foreach ($bucket in Get-LocalBucket) {
if (Test-Path -Path "$bucketsdir\$bucket\.git") {
- $remote = git -C "$bucketsdir\$bucket" config --get remote.origin.url
+ $remote = Invoke-Git -Path "$bucketsdir\$bucket" -ArgumentList @('config', '--get', 'remote.origin.url')
if ((Convert-RepositoryUri -Uri $remote) -eq $uni_repo) {
warn "Bucket $bucket already exists for $repo"
return 2
@@ -139,14 +139,14 @@ function add_bucket($name, $repo) {
}
Write-Host 'Checking repo... ' -NoNewline
- $out = git_cmd ls-remote $repo 2>&1
+ $out = Invoke-Git -ArgumentList @('ls-remote', $repo) 2>&1
if ($LASTEXITCODE -ne 0) {
error "'$repo' doesn't look like a valid git repository`n`nError given:`n$out"
return 1
}
ensure $bucketsdir | Out-Null
$dir = ensure $dir
- git_cmd clone "$repo" "`"$dir`"" -q
+ Invoke-Git -ArgumentList @('clone', $repo, $dir, '-q')
Write-Host 'OK'
success "The $name bucket was added successfully."
return 0
@@ -169,7 +169,7 @@ function new_issue_msg($app, $bucket, $title, $body) {
$bucket_path = "$bucketsdir\$bucket"
if (Test-Path $bucket_path) {
- $remote = git -C "$bucket_path" config --get remote.origin.url
+ $remote = Invoke-Git -Path $bucket_path -ArgumentList @('config', '--get', 'remote.origin.url')
# Support ssh and http syntax
# git@PROVIDER:USER/REPO.git
# https://PROVIDER/USER/REPO.git
diff --git a/lib/core.ps1 b/lib/core.ps1
index bc0365eb03..3d10baf22d 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -128,13 +128,78 @@ function setup_proxy() {
}
}
-function git_cmd {
+function Invoke-Git {
+ [CmdletBinding()]
+ [OutputType([String])]
+ param(
+ [Parameter(Mandatory = $false, Position = 0)]
+ [Alias('PSPath', 'Path')]
+ [ValidateNotNullOrEmpty()]
+ [String]
+ $WorkingDirectory,
+ [Parameter(Mandatory = $true, Position = 1)]
+ [Alias('Args')]
+ [String[]]
+ $ArgumentList
+ )
+
$proxy = get_config PROXY
- $cmd = "git $($args | ForEach-Object { "$_ " })"
- if ($proxy -and $proxy -ne 'none') {
- $cmd = "SET HTTPS_PROXY=$proxy&&SET HTTP_PROXY=$proxy&&$cmd"
+ $git = Get-HelperPath -Helper Git
+ $arguments = $ArgumentList -join ' '
+ $cmd = "`"$git`" $arguments"
+
+ if ($WorkingDirectory) {
+ $cmd = "`"$git`" -C `"$WorkingDirectory`" $arguments"
+ }
+ $sb = [scriptblock]::Create("& $cmd")
+
+ if([String]::IsNullOrEmpty($proxy) -or $proxy -eq 'none') {
+ return Invoke-Command $sb
+ }
+
+ if($arguments -Match '\b(clone|checkout|pull|fetch|ls-remote)\b') {
+ $old_https = $env:HTTPS_PROXY
+ $old_http = $env:HTTP_PROXY
+ try {
+ # convert proxy setting for git
+ if ($proxy.StartsWith('currentuser@')) {
+ $proxy = $proxy.Replace('currentuser@', ':@')
+ }
+ $env:HTTPS_PROXY = $proxy
+ $env:HTTP_PROXY = $proxy
+ return Invoke-Command $sb
+ }
+ catch {
+ error $_
+ return
+ }
+ finally {
+ $env:HTTPS_PROXY = $old_https
+ $env:HTTP_PROXY = $old_http
+ }
+ }
+
+ return Invoke-Command $sb
+}
+
+function Invoke-GitLog {
+ [CmdletBinding()]
+ Param (
+ [Parameter(Mandatory, ValueFromPipeline)]
+ [String]$Path,
+ [Parameter(Mandatory, ValueFromPipeline)]
+ [String]$CommitHash,
+ [String]$Name = ''
+ )
+ Process {
+ if ($Name) {
+ if ($Name.Length -gt 12) {
+ $Name = "$($Name.Substring(0, 10)).."
+ }
+ $Name = "%Cgreen$($Name.PadRight(12, ' ').Substring(0, 12))%Creset "
+ }
+ Invoke-Git -Path $Path -ArgumentList @('--no-pager', 'log', '--color', '--no-decorate', "--grep='^(chore)'", '--invert-grep', '--abbrev=12', "--format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s $Name%C(cyan)%cr%Creset'", "$CommitHash..HEAD")
}
- cmd.exe /d /c $cmd
}
# helper functions
@@ -293,12 +358,16 @@ Function Test-CommandAvailable {
Return [Boolean](Get-Command $Name -ErrorAction Ignore)
}
+Function Test-GitAvailable {
+ Return [Boolean](Test-Path (Get-HelperPath -Helper Git) -ErrorAction Ignore)
+}
+
function Get-HelperPath {
[CmdletBinding()]
[OutputType([String])]
param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
- [ValidateSet('7zip', 'Lessmsi', 'Innounp', 'Dark', 'Aria2', 'Zstd')]
+ [ValidateSet('Git', '7zip', 'Lessmsi', 'Innounp', 'Dark', 'Aria2', 'Zstd')]
[String]
$Helper
)
@@ -307,6 +376,14 @@ function Get-HelperPath {
}
process {
switch ($Helper) {
+ 'Git' {
+ $internalgit = "$(versiondir 'git' 'current')\mingw64\bin\git.exe"
+ if (Test-Path $internalgit) {
+ $HelperPath = $internalgit
+ } else {
+ $HelperPath = (Get-Command git -ErrorAction Ignore).Source
+ }
+ }
'7zip' {
$HelperPath = Get-AppFilePath '7zip' '7z.exe'
if ([String]::IsNullOrEmpty($HelperPath)) {
diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1
index f4346a6025..74e2530c36 100644
--- a/libexec/scoop-info.ps1
+++ b/libexec/scoop-info.ps1
@@ -84,7 +84,7 @@ if ($manifest.depends) {
if (Test-Path $manifest_file) {
if (Get-Command git -ErrorAction Ignore) {
- $gitinfo = (git -C (Split-Path $manifest_file) log -1 -s --format='%aD#%an' $manifest_file 2> $null) -Split '#'
+ $gitinfo = (Invoke-Git -Path (Split-Path $manifest_file) -ArgumentList @('log', '-1', '-s', "--format='%aD#%an'", $manifest_file) 2> $null) -Split '#'
}
if ($gitinfo) {
$item.'Updated at' = $gitinfo[0] | Get-Date
diff --git a/libexec/scoop-status.ps1 b/libexec/scoop-status.ps1
index 28596ce8e3..c72f75bcbc 100644
--- a/libexec/scoop-status.ps1
+++ b/libexec/scoop-status.ps1
@@ -21,10 +21,10 @@ if (!(Get-FormatData ScoopStatus)) {
function Test-UpdateStatus($repopath) {
if (Test-Path "$repopath\.git") {
- git_cmd -C "`"$repopath`"" fetch -q origin
+ Invoke-Git -Path $repopath -ArgumentList @('fetch', '-q', 'origin')
$script:network_failure = 128 -eq $LASTEXITCODE
- $branch = git -C $repopath branch --show-current
- $commits = git -C $repopath log "HEAD..origin/$branch" --oneline
+ $branch = Invoke-Git -Path $repopath -ArgumentList @('branch', '--show-current')
+ $commits = Invoke-Git -Path $repopath -ArgumentList @('log', "HEAD..origin/$branch", '--oneline')
if ($commits) { return $true }
else { return $false }
} else {
diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1
index ad670f86c0..3bcdcb7500 100644
--- a/libexec/scoop-update.ps1
+++ b/libexec/scoop-update.ps1
@@ -56,14 +56,18 @@ if(($PSVersionTable.PSVersion.Major) -lt 5) {
}
$show_update_log = get_config SHOW_UPDATE_LOG $true
-function update_scoop($show_update_log) {
+function Sync-Scoop {
+ [CmdletBinding()]
+ Param (
+ [Switch]$Log
+ )
# Test if Scoop Core is hold
if(Test-ScoopCoreOnHold) {
return
}
# check for git
- if (!(Test-CommandAvailable git)) { abort "Scoop uses Git to update itself. Run 'scoop install git' and try again." }
+ 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')
@@ -72,7 +76,7 @@ function update_scoop($show_update_log) {
$olddir = "$currentdir\..\old"
# get git scoop
- git_cmd clone -q $configRepo --branch $configBranch --single-branch "`"$newdir`""
+ Invoke-Git -ArgumentList @('clone', '-q', $configRepo, '--branch', $configBranch, '--single-branch', $newdir)
# check if scoop was successful downloaded
if (!(Test-Path "$newdir\bin\scoop.ps1")) {
@@ -93,18 +97,18 @@ function update_scoop($show_update_log) {
Remove-Item "$currentdir\..\old" -Recurse -Force -ErrorAction SilentlyContinue
}
- $previousCommit = git -C "$currentdir" rev-parse HEAD
- $currentRepo = git -C "$currentdir" config remote.origin.url
- $currentBranch = git -C "$currentdir" branch
+ $previousCommit = Invoke-Git -Path $currentdir -ArgumentList @('rev-parse', 'HEAD')
+ $currentRepo = Invoke-Git -Path $currentdir -ArgumentList @('config', 'remote.origin.url')
+ $currentBranch = Invoke-Git -Path $currentdir -ArgumentList @('branch')
$isRepoChanged = !($currentRepo -match $configRepo)
$isBranchChanged = !($currentBranch -match "\*\s+$configBranch")
# Stash uncommitted changes
- if (git -C "$currentdir" diff HEAD --name-only) {
+ if (Invoke-Git -Path $currentdir -ArgumentList @('diff', 'HEAD', '--name-only')) {
if (get_config AUTOSTASH_ON_CONFLICT) {
warn "Uncommitted changes detected. Stashing..."
- git -C "$currentdir" stash push -m "WIP at $([System.DateTime]::Now.ToString('o'))" -u -q
+ Invoke-Git -Path $currentdir -ArgumentList @('stash', 'push', '-m', "WIP at $([System.DateTime]::Now.ToString('o'))", '-u', '-q')
} else {
warn "Uncommitted changes detected. Update aborted."
return
@@ -113,26 +117,26 @@ function update_scoop($show_update_log) {
# Change remote url if the repo is changed
if ($isRepoChanged) {
- git -C "$currentdir" config remote.origin.url "$configRepo"
+ Invoke-Git -Path $currentdir -ArgumentList @('config', 'remote.origin.url', $configRepo)
}
# Fetch and reset local repo if the repo or the branch is changed
if ($isRepoChanged -or $isBranchChanged) {
# Reset git fetch refs, so that it can fetch all branches (GH-3368)
- git -C "$currentdir" config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
+ Invoke-Git -Path $currentdir -ArgumentList @('config', 'remote.origin.fetch', '+refs/heads/*:refs/remotes/origin/*')
# fetch remote branch
- git_cmd -C "`"$currentdir`"" fetch --force origin "refs/heads/`"$configBranch`":refs/remotes/origin/$configBranch" -q
+ Invoke-Git -Path $currentdir -ArgumentList @('fetch', '--force', 'origin', "refs/heads/$configBranch`:refs/remotes/origin/$configBranch", '-q')
# checkout and track the branch
- git_cmd -C "`"$currentdir`"" checkout -B $configBranch -t origin/$configBranch -q
+ Invoke-Git -Path $currentdir -ArgumentList @('checkout', '-B', $configBranch, '-t', "origin/$configBranch", '-q')
# reset branch HEAD
- git -C "$currentdir" reset --hard origin/$configBranch -q
+ Invoke-Git -Path $currentdir -ArgumentList @('reset', '--hard', "origin/$configBranch", '-q')
} else {
- git_cmd -C "`"$currentdir`"" pull -q
+ Invoke-Git -Path $currentdir -ArgumentList @('pull', '-q')
}
$res = $lastexitcode
- if ($show_update_log) {
- git -C "$currentdir" --no-pager log --no-decorate --grep='^(chore)' --invert-grep --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' "$previousCommit..HEAD"
+ if ($Log) {
+ Invoke-GitLog -Path $currentdir -CommitHash $previousCommit
}
if ($res -ne 0) {
@@ -140,47 +144,63 @@ function update_scoop($show_update_log) {
}
}
- # This should have been deprecated after 2019-05-12
- # if ((Get-LocalBucket) -notcontains 'main') {
- # info "The main bucket of Scoop has been separated to 'https://github.com/ScoopInstaller/Main'"
- # info "Adding main bucket..."
- # add_bucket 'main'
- # }
-
shim "$currentdir\bin\scoop.ps1" $false
}
-function update_bucket($show_update_log) {
- # check for git
- if (!(Test-CommandAvailable git)) { abort "Scoop uses Git to update main bucket and others. Run 'scoop install git' and try again." }
+function Sync-Bucket {
+ Param (
+ [Switch]$Log
+ )
+ Write-Host "Updating Buckets..."
+
+ if (!(Test-Path (Join-Path (Find-BucketDirectory 'main' -Root) '.git'))) {
+ info "Converting 'main' bucket to git repo..."
+ $status = rm_bucket 'main'
+ if ($status -ne 0) {
+ abort "Failed to remove local 'main' bucket."
+ }
+ $status = add_bucket 'main' (known_bucket_repo 'main')
+ if ($status -ne 0) {
+ abort "Failed to add remote 'main' bucket."
+ }
+ }
- foreach ($bucket in Get-LocalBucket) {
- Write-Host "Updating '$bucket' bucket..."
- $bucketLoc = Find-BucketDirectory $bucket -Root
+ $buckets = Get-LocalBucket | ForEach-Object {
+ $path = Find-BucketDirectory $_ -Root
+ return @{
+ name = $_
+ valid = Test-Path (Join-Path $path '.git')
+ path = $path
+ }
+ }
- if (!(Test-Path (Join-Path $bucketLoc '.git'))) {
- if ($bucket -eq 'main') {
- # Make sure main bucket, which was downloaded as zip, will be properly "converted" into git
- Write-Host " Converting 'main' bucket to git repo..."
- $status = rm_bucket 'main'
- if ($status -ne 0) {
- abort "Failed to remove local 'main' bucket."
- }
- $status = add_bucket 'main' (known_bucket_repo 'main')
- if ($status -ne 0) {
- abort "Failed to add remote 'main' bucket."
- }
- } else {
- Write-Host "'$bucket' is not a git repository. Skipped."
+ $buckets | Where-Object { !$_.valid } | ForEach-Object { Write-Host "'$($_.name)' is not a git repository. Skipped." }
+
+ if ($PSVersionTable.PSVersion.Major -ge 7) {
+ # Parallel parameter is available since PowerShell 7
+ $buckets | Where-Object { $_.valid } | ForEach-Object -ThrottleLimit 5 -Parallel {
+ . "$using:PSScriptRoot\..\lib\core.ps1"
+
+ $bucketLoc = $_.path
+ $name = $_.name
+
+ $previousCommit = Invoke-Git -Path $bucketLoc -ArgumentList @('rev-parse', 'HEAD')
+ Invoke-Git -Path $bucketLoc -ArgumentList @('pull', '-q')
+ if ($using:Log) {
+ Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit
}
- continue
}
-
- $previousCommit = git -C "$bucketLoc" rev-parse HEAD
- git_cmd -C "`"$bucketLoc`"" pull -q
- if ($show_update_log) {
- git -C "$bucketLoc" --no-pager log --no-decorate --grep='^(chore)' --invert-grep --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' "$previousCommit..HEAD"
+ } else {
+ $buckets | Where-Object { $_.valid } | ForEach-Object {
+ $bucketLoc = $_.path
+ $name = $_.name
+
+ $previousCommit = Invoke-Git -Path $bucketLoc -ArgumentList @('rev-parse', 'HEAD')
+ Invoke-Git -Path $bucketLoc -ArgumentList @('pull', '-q')
+ if ($Log) {
+ Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit
+ }
}
}
}
@@ -321,8 +341,8 @@ if (-not ($apps -or $all)) {
error 'scoop update: --no-cache is invalid when is not specified.'
exit 1
}
- update_scoop $show_update_log
- update_bucket $show_update_log
+ Sync-Scoop -Log:$show_update_log
+ Sync-Bucket -Log:$show_update_log
set_config LAST_UPDATE ([System.DateTime]::Now.ToString('o')) | Out-Null
success 'Scoop was updated successfully!'
} else {
@@ -336,8 +356,8 @@ if (-not ($apps -or $all)) {
$apps_param = $apps
if ($updateScoop) {
- update_scoop $show_update_log
- update_bucket $show_update_log
+ Sync-Scoop -Log:$show_update_log
+ Sync-Bucket -Log:$show_update_log
set_config LAST_UPDATE ([System.DateTime]::Now.ToString('o')) | Out-Null
success 'Scoop was updated successfully!'
}
From af5ffcddab21d9c8a93a5b4e04fff152abeb8f68 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Wed, 30 Nov 2022 13:32:35 +0800
Subject: [PATCH 02/75] test(bucket): Skip manifest validation if no manifest
changes (#5270)
---
CHANGELOG.md | 10 ++++++++--
test/Import-Bucket-Tests.ps1 | 8 +++-----
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b9b155d5b..d18455b733 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,16 @@
## [Unreleased](https://github.com/ScoopInstaller/Scoop/compare/master...develop)
### Features
-- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/pull/5122))
+
+- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
### Code Refactoring
-- **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/pull/5122))
+
+- **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
+
+### Tests
+
+- **bucket:** Skip manifest validation if no manifest changes ([#5270](https://github.com/ScoopInstaller/Scoop/issues/5270))
## [v0.3.1](https://github.com/ScoopInstaller/Scoop/compare/v0.3.0...v0.3.1) - 2022-11-15
diff --git a/test/Import-Bucket-Tests.ps1 b/test/Import-Bucket-Tests.ps1
index 789a4b24f7..96890a0a74 100644
--- a/test/Import-Bucket-Tests.ps1
+++ b/test/Import-Bucket-Tests.ps1
@@ -16,11 +16,9 @@ Describe 'Manifest validates against the schema' {
}
if ($env:CI -eq $true) {
Set-BuildEnvironment -Force
- $changedManifests = @(Get-GitChangedFile -Path $bucketDir -Include '*.json' -Commit $env:BHCommitHash)
- }
- $manifestFiles = (Get-ChildItem $bucketDir -Filter '*.json' -Recurse).FullName
- if ($changedManifests) {
- $manifestFiles = $manifestFiles | Where-Object { $_ -in $changedManifests }
+ $manifestFiles = @(Get-GitChangedFile -Path $bucketDir -Include '*.json' -Commit $env:BHCommitHash)
+ } else {
+ $manifestFiles = (Get-ChildItem $bucketDir -Filter '*.json' -Recurse).FullName
}
}
BeforeAll {
From 6369ba60baeb78b48ec58df290767c21f51c4763 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Sat, 10 Dec 2022 15:38:30 +0000
Subject: [PATCH 03/75] refactor(scoop-download): Output more detailed manifest
information (#5277)
---
CHANGELOG.md | 1 +
libexec/scoop-download.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d18455b733..09eb4eea50 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
### Code Refactoring
- **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
+- **scoop-download:** Output more detailed manifest information ([#5277](https://github.com/ScoopInstaller/Scoop/issues/5277))
### Tests
diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1
index 34de7ea19f..d339e7907f 100644
--- a/libexec/scoop-download.ps1
+++ b/libexec/scoop-download.ps1
@@ -57,7 +57,7 @@ foreach ($curr_app in $apps) {
$app, $bucket, $version = parse_app $curr_app
$app, $manifest, $bucket, $url = Get-Manifest "$bucket/$app"
- info "Starting download for $app..."
+ info "Downloading '$app'$(if ($version) { " ($version)" }) [$architecture]$(if ($bucket) { " from $bucket bucket" })"
# Generate manifest if there is different version in manifest
if (($null -ne $version) -and ($manifest.version -ne $version)) {
From 52f9ce3a817146f5c501bc4e70c4af26187283af Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Sun, 18 Dec 2022 23:15:03 +0800
Subject: [PATCH 04/75] fix(autoupdate): Fix file hash extraction (#5295)
---
CHANGELOG.md | 4 ++
lib/autoupdate.ps1 | 139 +++++++++++++++++++++++----------------------
2 files changed, 76 insertions(+), 67 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 09eb4eea50..9deb3ec1ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@
- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
+### Bug Fixes
+
+- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
+
### Code Refactoring
- **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
diff --git a/lib/autoupdate.ps1 b/lib/autoupdate.ps1
index 6edc8791ff..803e994b6c 100644
--- a/lib/autoupdate.ps1
+++ b/lib/autoupdate.ps1
@@ -8,9 +8,9 @@ function find_hash_in_rdf([String] $url, [String] $basename) {
$wc.Headers.Add('User-Agent', (Get-UserAgent))
$data = $wc.DownloadData($url)
[xml]$xml = (Get-Encoding($wc)).GetString($data)
- } catch [system.net.webexception] {
- write-host -f darkred $_
- write-host -f darkred "URL $url is not valid"
+ } catch [System.Net.WebException] {
+ Write-Host $_ -ForegroundColor DarkRed
+ Write-Host "URL $url is not valid" -ForegroundColor DarkRed
return $null
}
@@ -24,12 +24,12 @@ function find_hash_in_textfile([String] $url, [Hashtable] $substitutions, [Strin
$hashfile = $null
$templates = @{
- '$md5' = '([a-fA-F0-9]{32})';
- '$sha1' = '([a-fA-F0-9]{40})';
- '$sha256' = '([a-fA-F0-9]{64})';
- '$sha512' = '([a-fA-F0-9]{128})';
- '$checksum' = '([a-fA-F0-9]{32,128})';
- '$base64' = '([a-zA-Z0-9+\/=]{24,88})';
+ '$md5' = '([a-fA-F0-9]{32})'
+ '$sha1' = '([a-fA-F0-9]{40})'
+ '$sha256' = '([a-fA-F0-9]{64})'
+ '$sha512' = '([a-fA-F0-9]{128})'
+ '$checksum' = '([a-fA-F0-9]{32,128})'
+ '$base64' = '([a-zA-Z0-9+\/=]{24,88})'
}
try {
@@ -39,8 +39,8 @@ function find_hash_in_textfile([String] $url, [Hashtable] $substitutions, [Strin
$data = $wc.DownloadData($url)
$hashfile = (Get-Encoding($wc)).GetString($data)
} catch [system.net.webexception] {
- write-host -f darkred $_
- write-host -f darkred "URL $url is not valid"
+ Write-Host $_ -ForegroundColor DarkRed
+ Write-Host "URL $url is not valid" -ForegroundColor DarkRed
return
}
@@ -50,15 +50,15 @@ function find_hash_in_textfile([String] $url, [Hashtable] $substitutions, [Strin
$regex = substitute $regex $templates $false
$regex = substitute $regex $substitutions $true
- debug $regex
if ($hashfile -match $regex) {
- $hash = $matches[1] -replace '\s',''
+ debug $regex
+ $hash = $matches[1] -replace '\s', ''
}
# convert base64 encoded hash values
if ($hash -match '^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$') {
$base64 = $matches[0]
- if(!($hash -match '^[a-fA-F0-9]+$') -and $hash.length -notin @(32, 40, 64, 128)) {
+ if (!($hash -match '^[a-fA-F0-9]+$') -and $hash.Length -notin @(32, 40, 64, 128)) {
try {
$hash = ([System.Convert]::FromBase64String($base64) | ForEach-Object { $_.ToString('x2') }) -join ''
} catch {
@@ -69,13 +69,15 @@ function find_hash_in_textfile([String] $url, [Hashtable] $substitutions, [Strin
# find hash with filename in $hashfile
if ($hash.Length -eq 0) {
- $filenameRegex = "([a-fA-F0-9]{32,128})[\x20\t]+.*`$basename(?:[\x20\t]+\d+)?"
+ $filenameRegex = "([a-fA-F0-9]{32,128})[\x20\t]+.*`$basename(?:\s|$)|`$basename[\x20\t]+.*?([a-fA-F0-9]{32,128})"
$filenameRegex = substitute $filenameRegex $substitutions $true
if ($hashfile -match $filenameRegex) {
+ debug $filenameRegex
$hash = $matches[1]
}
- $metalinkRegex = "]+>([a-fA-F0-9]{64})"
+ $metalinkRegex = ']+>([a-fA-F0-9]{64})'
if ($hashfile -match $metalinkRegex) {
+ debug $metalinkRegex
$hash = $matches[1]
}
}
@@ -92,13 +94,14 @@ function find_hash_in_json([String] $url, [Hashtable] $substitutions, [String] $
$wc.Headers.Add('User-Agent', (Get-UserAgent))
$data = $wc.DownloadData($url)
$json = (Get-Encoding($wc)).GetString($data)
- } catch [system.net.webexception] {
- write-host -f darkred $_
- write-host -f darkred "URL $url is not valid"
+ } catch [System.Net.WebException] {
+ Write-Host $_ -ForegroundColor DarkRed
+ Write-Host "URL $url is not valid" -ForegroundColor DarkRed
return
}
+ debug $jsonpath
$hash = json_path $json $jsonpath $substitutions
- if(!$hash) {
+ if (!$hash) {
$hash = json_path_legacy $json $jsonpath $substitutions
}
return format_hash $hash
@@ -114,8 +117,8 @@ function find_hash_in_xml([String] $url, [Hashtable] $substitutions, [String] $x
$data = $wc.DownloadData($url)
$xml = [xml]((Get-Encoding($wc)).GetString($data))
} catch [system.net.webexception] {
- write-host -f darkred $_
- write-host -f darkred "URL $url is not valid"
+ Write-Host $_ -ForegroundColor DarkRed
+ Write-Host "URL $url is not valid" -ForegroundColor DarkRed
return
}
@@ -125,13 +128,15 @@ function find_hash_in_xml([String] $url, [Hashtable] $substitutions, [String] $x
}
# Find all `significant namespace declarations` from the XML file
- $nsList = $xml.SelectNodes("//namespace::*[not(. = ../../namespace::*)]")
+ $nsList = $xml.SelectNodes('//namespace::*[not(. = ../../namespace::*)]')
# Then add them into the NamespaceManager
$nsmgr = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$nsList | ForEach-Object {
$nsmgr.AddNamespace($_.LocalName, $_.Value)
}
+ debug $xpath
+ debug $nsmgr
# Getting hash from XML, using XPath
$hash = $xml.SelectSingleNode($xpath, $nsmgr).'#text'
return format_hash $hash
@@ -148,16 +153,16 @@ function find_hash_in_headers([String] $url) {
$req.Timeout = 2000
$req.Method = 'HEAD'
$res = $req.GetResponse()
- if(([int]$res.StatusCode -ge 300) -and ([int]$res.StatusCode -lt 400)) {
- if($res.Headers['Digest'] -match 'SHA-256=([^,]+)' -or $res.Headers['Digest'] -match 'SHA=([^,]+)' -or $res.Headers['Digest'] -match 'MD5=([^,]+)') {
+ if (([int]$res.StatusCode -ge 300) -and ([int]$res.StatusCode -lt 400)) {
+ if ($res.Headers['Digest'] -match 'SHA-256=([^,]+)' -or $res.Headers['Digest'] -match 'SHA=([^,]+)' -or $res.Headers['Digest'] -match 'MD5=([^,]+)') {
$hash = ([System.Convert]::FromBase64String($matches[1]) | ForEach-Object { $_.ToString('x2') }) -join ''
debug $hash
}
}
$res.Close()
- } catch [system.net.webexception] {
- write-host -f darkred $_
- write-host -f darkred "URL $url is not valid"
+ } catch [System.Net.WebException] {
+ Write-Host $_ -ForegroundColor DarkRed
+ Write-Host "URL $url is not valid" -ForegroundColor DarkRed
return
}
@@ -182,10 +187,10 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
$hashfile_url = substitute $config.url $substitutions
debug $hashfile_url
if ($hashfile_url) {
- write-host -f DarkYellow 'Searching hash for ' -NoNewline
- write-host -f Green $basename -NoNewline
- write-host -f DarkYellow ' in ' -NoNewline
- write-host -f Green $hashfile_url
+ Write-Host 'Searching hash for ' -ForegroundColor DarkYellow -NoNewline
+ Write-Host $basename -ForegroundColor Green -NoNewline
+ Write-Host ' in ' -ForegroundColor DarkYellow -NoNewline
+ Write-Host $hashfile_url -ForegroundColor Green
}
if ($hashmode.Length -eq 0 -and $config.url.Length -ne 0) {
@@ -215,11 +220,11 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
$hashmode = 'xpath'
}
- if (!$hashfile_url -and $url -match "^(?:.*fosshub.com\/).*(?:\/|\?dwl=)(?.*)$") {
+ if (!$hashfile_url -and $url -match '^(?:.*fosshub.com\/).*(?:\/|\?dwl=)(?.*)$') {
$hashmode = 'fosshub'
}
- if (!$hashfile_url -and $url -match "(?:downloads\.)?sourceforge.net\/projects?\/(?[^\/]+)\/(?:files\/)?(?.*)") {
+ if (!$hashfile_url -and $url -match '(?:downloads\.)?sourceforge.net\/projects?\/(?[^\/]+)\/(?:files\/)?(?.*)') {
$hashmode = 'sourceforge'
}
@@ -243,7 +248,7 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
}
}
'fosshub' {
- $hash = find_hash_in_textfile $url $substitutions ($Matches.filename+'.*?"sha256":"([a-fA-F0-9]{64})"')
+ $hash = find_hash_in_textfile $url $substitutions ($matches.filename + '.*?"sha256":"([a-fA-F0-9]{64})"')
}
'sourceforge' {
# change the URL because downloads.sourceforge.net doesn't have checksums
@@ -254,29 +259,29 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
if ($hash) {
# got one!
- write-host -f DarkYellow 'Found: ' -NoNewline
- write-host -f Green $hash -NoNewline
- write-host -f DarkYellow ' using ' -NoNewline
- write-host -f Green "$((Get-Culture).TextInfo.ToTitleCase($hashmode)) Mode"
+ Write-Host 'Found: ' -ForegroundColor DarkYellow -NoNewline
+ Write-Host $hash -ForegroundColor Green -NoNewline
+ Write-Host ' using ' -ForegroundColor DarkYellow -NoNewline
+ Write-Host "$((Get-Culture).TextInfo.ToTitleCase($hashmode)) Mode" -ForegroundColor Green
return $hash
} elseif ($hashfile_url) {
- write-host -f DarkYellow "Could not find hash in $hashfile_url"
+ Write-Host -f DarkYellow "Could not find hash in $hashfile_url"
}
- write-host -f DarkYellow 'Downloading ' -NoNewline
- write-host -f Green $basename -NoNewline
- write-host -f DarkYellow ' to compute hashes!'
+ Write-Host 'Downloading ' -ForegroundColor DarkYellow -NoNewline
+ Write-Host $basename -ForegroundColor Green -NoNewline
+ Write-Host ' to compute hashes!' -ForegroundColor DarkYellow
try {
Invoke-CachedDownload $app $version $url $null $null $true
} catch [system.net.webexception] {
- write-host -f darkred $_
- write-host -f darkred "URL $url is not valid"
+ Write-Host $_ -ForegroundColor DarkRed
+ Write-Host "URL $url is not valid" -ForegroundColor DarkRed
return $null
}
$file = fullpath (cache_path $app $version $url)
$hash = (Get-FileHash -Path $file -Algorithm SHA256).Hash.ToLower()
- write-host -f DarkYellow 'Computed hash: ' -NoNewline
- write-host -f Green $hash
+ Write-Host 'Computed hash: ' -ForegroundColor DarkYellow -NoNewline
+ Write-Host $hash -ForegroundColor Green
return $hash
}
@@ -346,7 +351,7 @@ function Update-ManifestProperty {
$newValue = substitute $autoupdateProperty $Substitutions
if (($autoupdateProperty.GetType().Name -eq 'Object[]') -and ($autoupdateProperty.Length -eq 1)) {
# Make sure it's an array
- $newValue = ,$newValue
+ $newValue = , $newValue
}
$Manifest.$currentProperty, $hasPropertyChanged = PropertyHelper -Property $Manifest.$currentProperty -Value $newValue
$hasManifestChanged = $hasManifestChanged -or $hasPropertyChanged
@@ -359,7 +364,7 @@ function Update-ManifestProperty {
$newValue = substitute $autoupdateProperty $Substitutions
if (($autoupdateProperty.GetType().Name -eq 'Object[]') -and ($autoupdateProperty.Length -eq 1)) {
# Make sure it's an array
- $newValue = ,$newValue
+ $newValue = , $newValue
}
$Manifest.architecture.$arch.$currentProperty, $hasPropertyChanged = PropertyHelper -Property $Manifest.architecture.$arch.$currentProperty -Value $newValue
$hasManifestChanged = $hasManifestChanged -or $hasPropertyChanged
@@ -388,25 +393,25 @@ function Get-VersionSubstitution {
$firstPart = $Version.Split('-') | Select-Object -First 1
$lastPart = $Version.Split('-') | Select-Object -Last 1
$versionVariables = @{
- '$version' = $Version;
- '$dotVersion' = ($Version -replace '[._-]', '.');
- '$underscoreVersion' = ($Version -replace '[._-]', '_');
- '$dashVersion' = ($Version -replace '[._-]', '-');
- '$cleanVersion' = ($Version -replace '[._-]', '');
- '$majorVersion' = $firstPart.Split('.') | Select-Object -First 1;
- '$minorVersion' = $firstPart.Split('.') | Select-Object -Skip 1 -First 1;
- '$patchVersion' = $firstPart.Split('.') | Select-Object -Skip 2 -First 1;
- '$buildVersion' = $firstPart.Split('.') | Select-Object -Skip 3 -First 1;
- '$preReleaseVersion' = $lastPart;
- }
- if($Version -match "(?\d+\.\d+(?:\.\d+)?)(?.*)") {
- $versionVariables.Set_Item('$matchHead', $Matches['head'])
- $versionVariables.Set_Item('$matchTail', $Matches['tail'])
- }
- if($CustomMatches) {
+ '$version' = $Version
+ '$dotVersion' = ($Version -replace '[._-]', '.')
+ '$underscoreVersion' = ($Version -replace '[._-]', '_')
+ '$dashVersion' = ($Version -replace '[._-]', '-')
+ '$cleanVersion' = ($Version -replace '[._-]', '')
+ '$majorVersion' = $firstPart.Split('.') | Select-Object -First 1
+ '$minorVersion' = $firstPart.Split('.') | Select-Object -Skip 1 -First 1
+ '$patchVersion' = $firstPart.Split('.') | Select-Object -Skip 2 -First 1
+ '$buildVersion' = $firstPart.Split('.') | Select-Object -Skip 3 -First 1
+ '$preReleaseVersion' = $lastPart
+ }
+ if ($Version -match '(?\d+\.\d+(?:\.\d+)?)(?.*)') {
+ $versionVariables.Add('$matchHead', $Matches['head'])
+ $versionVariables.Add('$matchTail', $Matches['tail'])
+ }
+ if ($CustomMatches) {
$CustomMatches.GetEnumerator() | ForEach-Object {
- if($_.Name -ne "0") {
- $versionVariables.Set_Item('$match' + (Get-Culture).TextInfo.ToTitleCase($_.Name), $_.Value)
+ if ($_.Name -ne '0') {
+ $versionVariables.Add('$match' + (Get-Culture).TextInfo.ToTitleCase($_.Name), $_.Value)
}
}
}
From 257304bbc7bb6d4fee4400cb148167a6cde4fc9e Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Sun, 18 Dec 2022 23:22:41 +0800
Subject: [PATCH 05/75] fix(decompress): Exclude '*.nsis' that may cause error
(#5294)
---
CHANGELOG.md | 1 +
lib/decompress.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9deb3ec1ff..de87c84ec5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
### Bug Fixes
+- **decompress:** Exclude '*.nsis' that may cause error ([#5294](https://github.com/ScoopInstaller/Scoop/issues/5294))
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
### Code Refactoring
diff --git a/lib/decompress.ps1 b/lib/decompress.ps1
index 91226706d1..785421c1a5 100644
--- a/lib/decompress.ps1
+++ b/lib/decompress.ps1
@@ -29,7 +29,7 @@ function Expand-7zipArchive {
}
$LogPath = "$(Split-Path $Path)\7zip.log"
$DestinationPath = $DestinationPath.TrimEnd('\')
- $ArgList = @('x', $Path, "-o$DestinationPath", '-y')
+ $ArgList = @('x', $Path, "-o$DestinationPath", '-xr!*.nsis', '-y')
$IsTar = ((strip_ext $Path) -match '\.tar$') -or ($Path -match '\.t[abgpx]z2?$')
if (!$IsTar -and $ExtractDir) {
$ArgList += "-ir!$ExtractDir\*"
From 68760de1e8c0ca30dd93297d7d3366f285db394a Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Mon, 9 Jan 2023 03:01:40 +0000
Subject: [PATCH 06/75] fix(shortcuts): Output correctly formatted path (#5333)
---
CHANGELOG.md | 1 +
lib/shortcuts.ps1 | 24 ++++++++++++------------
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de87c84ec5..138e330708 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
- **decompress:** Exclude '*.nsis' that may cause error ([#5294](https://github.com/ScoopInstaller/Scoop/issues/5294))
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
+- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
### Code Refactoring
diff --git a/lib/shortcuts.ps1 b/lib/shortcuts.ps1
index e8ddec26bb..edb6357480 100644
--- a/lib/shortcuts.ps1
+++ b/lib/shortcuts.ps1
@@ -5,16 +5,16 @@ function create_startmenu_shortcuts($manifest, $dir, $global, $arch) {
$target = [System.IO.Path]::Combine($dir, $_.item(0))
$target = New-Object System.IO.FileInfo($target)
$name = $_.item(1)
- $arguments = ""
+ $arguments = ''
$icon = $null
- if($_.length -ge 3) {
+ if ($_.length -ge 3) {
$arguments = $_.item(2)
}
- if($_.length -ge 4) {
+ if ($_.length -ge 4) {
$icon = [System.IO.Path]::Combine($dir, $_.item(3))
$icon = New-Object System.IO.FileInfo($icon)
}
- $arguments = (substitute $arguments @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir})
+ $arguments = (substitute $arguments @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir })
startmenu_shortcut $target $name $arguments $icon $global
}
}
@@ -29,11 +29,11 @@ function shortcut_folder($global) {
}
function startmenu_shortcut([System.IO.FileInfo] $target, $shortcutName, $arguments, [System.IO.FileInfo]$icon, $global) {
- if(!$target.Exists) {
+ if (!$target.Exists) {
Write-Host -f DarkRed "Creating shortcut for $shortcutName ($(fname $target)) failed: Couldn't find $target"
return
}
- if($icon -and !$icon.Exists) {
+ if ($icon -and !$icon.Exists) {
Write-Host -f DarkRed "Creating shortcut for $shortcutName ($(fname $target)) failed: Couldn't find icon $icon"
return
}
@@ -51,11 +51,11 @@ function startmenu_shortcut([System.IO.FileInfo] $target, $shortcutName, $argume
if ($arguments) {
$wsShell.Arguments = $arguments
}
- if($icon -and $icon.Exists) {
+ if ($icon -and $icon.Exists) {
$wsShell.IconLocation = $icon.FullName
}
$wsShell.Save()
- write-host "Creating shortcut for $shortcutName ($(fname $target))"
+ Write-Host "Creating shortcut for $shortcutName ($(fname $target))"
}
# Removes the Startmenu shortcut if it exists
@@ -63,10 +63,10 @@ function rm_startmenu_shortcuts($manifest, $global, $arch) {
$shortcuts = @(arch_specific 'shortcuts' $manifest $arch)
$shortcuts | Where-Object { $_ -ne $null } | ForEach-Object {
$name = $_.item(1)
- $shortcut = "$(shortcut_folder $global)\$name.lnk"
- write-host "Removing shortcut $(friendly_path $shortcut)"
- if(Test-Path -Path $shortcut) {
- Remove-Item $shortcut
+ $shortcut = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$(shortcut_folder $global)\$name.lnk")
+ Write-Host "Removing shortcut $(friendly_path $shortcut)"
+ if (Test-Path -Path $shortcut) {
+ Remove-Item $shortcut
}
}
}
From e2558ace75dd67b45b7027723c5e7b336f01ad94 Mon Sep 17 00:00:00 2001
From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
Date: Tue, 7 Feb 2023 04:55:54 +0530
Subject: [PATCH 07/75] fix(chore): Handle spaces in git command arguments
(#5375)
* fix(chore): Handle spaces in git command arguments
* changelog
* Use splatting
---
CHANGELOG.md | 2 +-
lib/buckets.ps1 | 2 +-
lib/core.ps1 | 15 ++++++---------
libexec/scoop-info.ps1 | 2 +-
4 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 138e330708..f45932ad68 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,7 +12,7 @@
### Code Refactoring
-- **git:** Use Invoke-Git() with direct path to git.exe to prevent spawning shim subprocesses ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
+- **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))
### Tests
diff --git a/lib/buckets.ps1 b/lib/buckets.ps1
index 704d51a82b..14e3dbf318 100644
--- a/lib/buckets.ps1
+++ b/lib/buckets.ps1
@@ -100,7 +100,7 @@ function list_buckets {
$path = Find-BucketDirectory $_ -Root
if ((Test-Path (Join-Path $path '.git')) -and (Get-Command git -ErrorAction SilentlyContinue)) {
$bucket.Source = Invoke-Git -Path $path -ArgumentList @('config', 'remote.origin.url')
- $bucket.Updated = Invoke-Git -Path $path -ArgumentList @('log', "--format='%aD'", '-n', '1')
+ $bucket.Updated = Invoke-Git -Path $path -ArgumentList @('log', '--format=%aD', '-n', '1') | Get-Date
} else {
$bucket.Source = friendly_path $path
$bucket.Updated = (Get-Item "$path\bucket").LastWriteTime
diff --git a/lib/core.ps1 b/lib/core.ps1
index 3d10baf22d..e2a45729e9 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -145,19 +145,16 @@ function Invoke-Git {
$proxy = get_config PROXY
$git = Get-HelperPath -Helper Git
- $arguments = $ArgumentList -join ' '
- $cmd = "`"$git`" $arguments"
if ($WorkingDirectory) {
- $cmd = "`"$git`" -C `"$WorkingDirectory`" $arguments"
+ $ArgumentList = @('-C', $WorkingDirectory) + $ArgumentList
}
- $sb = [scriptblock]::Create("& $cmd")
if([String]::IsNullOrEmpty($proxy) -or $proxy -eq 'none') {
- return Invoke-Command $sb
+ return & $git @ArgumentList
}
- if($arguments -Match '\b(clone|checkout|pull|fetch|ls-remote)\b') {
+ if($ArgumentList -Match '\b(clone|checkout|pull|fetch|ls-remote)\b') {
$old_https = $env:HTTPS_PROXY
$old_http = $env:HTTP_PROXY
try {
@@ -167,7 +164,7 @@ function Invoke-Git {
}
$env:HTTPS_PROXY = $proxy
$env:HTTP_PROXY = $proxy
- return Invoke-Command $sb
+ return & $git @ArgumentList
}
catch {
error $_
@@ -179,7 +176,7 @@ function Invoke-Git {
}
}
- return Invoke-Command $sb
+ return & $git @ArgumentList
}
function Invoke-GitLog {
@@ -198,7 +195,7 @@ function Invoke-GitLog {
}
$Name = "%Cgreen$($Name.PadRight(12, ' ').Substring(0, 12))%Creset "
}
- Invoke-Git -Path $Path -ArgumentList @('--no-pager', 'log', '--color', '--no-decorate', "--grep='^(chore)'", '--invert-grep', '--abbrev=12', "--format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s $Name%C(cyan)%cr%Creset'", "$CommitHash..HEAD")
+ Invoke-Git -Path $Path -ArgumentList @('--no-pager', 'log', '--color', '--no-decorate', "--grep='^(chore)'", '--invert-grep', '--abbrev=12', "--format=tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s $Name%C(cyan)%cr%Creset", "$CommitHash..HEAD")
}
}
diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1
index 74e2530c36..625a3c6463 100644
--- a/libexec/scoop-info.ps1
+++ b/libexec/scoop-info.ps1
@@ -84,7 +84,7 @@ if ($manifest.depends) {
if (Test-Path $manifest_file) {
if (Get-Command git -ErrorAction Ignore) {
- $gitinfo = (Invoke-Git -Path (Split-Path $manifest_file) -ArgumentList @('log', '-1', '-s', "--format='%aD#%an'", $manifest_file) 2> $null) -Split '#'
+ $gitinfo = (Invoke-Git -Path (Split-Path $manifest_file) -ArgumentList @('log', '-1', '-s', '--format=%aD#%an', $manifest_file) 2> $null) -Split '#'
}
if ($gitinfo) {
$item.'Updated at' = $gitinfo[0] | Get-Date
From 54e3613fca328a1dd22390fb9984b0cd839ab9cb Mon Sep 17 00:00:00 2001
From: Ross Smith II
Date: Sat, 18 Feb 2023 06:50:08 -0800
Subject: [PATCH 08/75] ci(dependabot): Add dependabot.yml for GitHub Actions
(#5377)
---
.github/dependabot.yml | 8 ++++++++
CHANGELOG.md | 4 ++++
2 files changed, 12 insertions(+)
create mode 100644 .github/dependabot.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000000..91df8eba1f
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,8 @@
+---
+# ~/.github/dependabot.yml
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/" # == /.github/workflows/
+ schedule:
+ interval: "daily"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f45932ad68..a26150e727 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,10 @@
- **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))
+### Continuous Integration
+
+- **dependabot:** Add dependabot.yml for GitHub Actions ([#5377](https://github.com/ScoopInstaller/Scoop/pull/5377))
+
### Tests
- **bucket:** Skip manifest validation if no manifest changes ([#5270](https://github.com/ScoopInstaller/Scoop/issues/5270))
From 1d0bd434abe93b3f471744e3816bdc919f5428d2 Mon Sep 17 00:00:00 2001
From: Ercolino
Date: Sun, 19 Feb 2023 10:19:01 +0100
Subject: [PATCH 09/75] builds(checkver): Read the private_host config variable
(#5381)
---
CHANGELOG.md | 4 ++++
bin/checkver.ps1 | 24 +++++++++++++++---------
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a26150e727..73ad1d56b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,10 @@
- **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))
+### Builds
+
+- **checkver:** Read the private_host config variable ([#5381](https://github.com/ScoopInstaller/Scoop/issues/5381))
+
### Continuous Integration
- **dependabot:** Add dependabot.yml for GitHub Actions ([#5377](https://github.com/ScoopInstaller/Scoop/pull/5377))
diff --git a/bin/checkver.ps1 b/bin/checkver.ps1
index 56b8c8c987..e740208d99 100644
--- a/bin/checkver.ps1
+++ b/bin/checkver.ps1
@@ -226,15 +226,21 @@ $Queue | ForEach-Object {
$url = substitute $url $substitutions
$state = New-Object psobject @{
- app = $name;
- file = $file;
- url = $url;
- regex = $regex;
- json = $json;
- jsonpath = $jsonpath;
- xpath = $xpath;
- reverse = $reverse;
- replace = $replace;
+ app = $name
+ file = $file
+ url = $url
+ regex = $regex
+ json = $json
+ jsonpath = $jsonpath
+ xpath = $xpath
+ reverse = $reverse
+ replace = $replace
+ }
+
+ get_config PRIVATE_HOSTS | Where-Object { $_ -ne $null -and $url -match $_.match } | ForEach-Object {
+ (ConvertFrom-StringData -StringData $_.Headers).GetEnumerator() | ForEach-Object {
+ $wc.Headers[$_.Key] = $_.Value
+ }
}
$wc.Headers.Add('Referer', (strip_filename $url))
From 32ca856f6393da23abf22dffa3c6564353f113db Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Sun, 19 Feb 2023 23:56:53 +0800
Subject: [PATCH 10/75] fix(core): Fix `is_in_dir` under Unix (#5391)
---
CHANGELOG.md | 1 +
lib/install.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73ad1d56b6..25f8a0736a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
- **decompress:** Exclude '*.nsis' that may cause error ([#5294](https://github.com/ScoopInstaller/Scoop/issues/5294))
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
+- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
### Code Refactoring
diff --git a/lib/install.ps1 b/lib/install.ps1
index cdbfdf1a79..5b52704114 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -632,7 +632,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) {
From 7c6aeb240ee8f6a1fe799bfa9cc97d6de131c56a Mon Sep 17 00:00:00 2001
From: Jeppe Frandsen
Date: Sat, 25 Feb 2023 09:30:37 +0100
Subject: [PATCH 11/75] fix(install): Fix downloading release assets from
private GitHub repositories (#5361)
Fix download from private GitHub repos
---
CHANGELOG.md | 1 +
lib/install.ps1 | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25f8a0736a..f7d20c67c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
+- **install:** Fix download from private GitHub repositories ([#5357](https://github.com/ScoopInstaller/Scoop/issues/5357))
### Code Refactoring
diff --git a/lib/install.ps1 b/lib/install.ps1
index 5b52704114..384c2e38b7 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -365,7 +365,8 @@ function Invoke-Download ($url, $to, $cookies, $progress) {
}
if ($url -match 'api\.github\.com/repos') {
$wreq.Accept = 'application/octet-stream'
- $wreq.Headers['Authorization'] = "token $(Get-GitHubToken)"
+ $wreq.Headers['Authorization'] = "Bearer $(Get-GitHubToken)"
+ $wreq.Headers['X-GitHub-Api-Version'] = "2022-11-28"
}
if ($cookies) {
$wreq.Headers.Add('Cookie', (cookie_header $cookies))
From c44e2147435a4394f539489872b2029b4fe1268f Mon Sep 17 00:00:00 2001
From: Chawye Hsu
Date: Sat, 25 Feb 2023 20:22:56 +0800
Subject: [PATCH 12/75] feat(config): Support portable config file (#5369)
---
CHANGELOG.md | 1 +
lib/core.ps1 | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7d20c67c9..aadb4f1b39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
### Features
- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
+- **config:** Support portable config file ([#5369](https://github.com/ScoopInstaller/Scoop/issues/5369))
### Bug Fixes
diff --git a/lib/core.ps1 b/lib/core.ps1
index e2a45729e9..7ce39fc62d 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -1297,6 +1297,29 @@ Optimize-SecurityProtocol
# Load Scoop config
$configHome = $env:XDG_CONFIG_HOME, "$env:USERPROFILE\.config" | Select-Object -First 1
$configFile = "$configHome\scoop\config.json"
+# Check if it's the expected install path for scoop: /apps/scoop/current
+$coreRoot = Split-Path $PSScriptRoot
+$pathExpected = ($coreRoot -replace '\\','/') -like '*apps/scoop/current*'
+if ($pathExpected) {
+ # Portable config is located in root directory:
+ # .\current\scoop\apps\\config.json <- a reversed path
+ # Imagine `/apps/scoop/current/` in a reversed format,
+ # and the directory tree:
+ #
+ # ```
+ # :
+ # ├─apps
+ # ├─buckets
+ # ├─cache
+ # ├─persist
+ # ├─shims
+ # ├─config.json
+ # ```
+ $configPortablePath = fullpath "$coreRoot\..\..\..\config.json"
+ if (Test-Path $configPortablePath) {
+ $configFile = $configPortablePath
+ }
+}
$scoopConfig = load_cfg $configFile
# NOTE Scoop config file migration. Remove this after 2023/6/30
From 0a39de86e2900f2e2bf3ddae1390a57b7d2c894f Mon Sep 17 00:00:00 2001
From: 0x574859
Date: Sat, 25 Feb 2023 20:38:09 +0800
Subject: [PATCH 13/75] fix(env): Avoid automatic expansion of `%%` in env
(#5395)
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 3 ++-
lib/core.ps1 | 27 +++++++++++++++++++++++----
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aadb4f1b39..27f66c4e57 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,8 @@
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
-- **install:** Fix download from private GitHub repositories ([#5357](https://github.com/ScoopInstaller/Scoop/issues/5357))
+- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
+- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
### Code Refactoring
diff --git a/lib/core.ps1 b/lib/core.ps1
index 7ce39fc62d..68ad7a3e9e 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -662,10 +662,29 @@ function Invoke-ExternalCommand {
return $true
}
-function env($name,$global,$val='__get') {
- $target = 'User'; if($global) {$target = 'Machine'}
- if($val -eq '__get') { [environment]::getEnvironmentVariable($name,$target) }
- else { [environment]::setEnvironmentVariable($name,$val,$target) }
+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) {
+ $EnvRegisterKey.DeleteValue($name)
+ } 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)
+ }
}
function isFileLocked([string]$path) {
From 3f11454a3c796c4bbedec392c80567ff952633c5 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Sun, 26 Feb 2023 14:31:38 +0800
Subject: [PATCH 14/75] fix(core): Fix scripts' calling parameters (#5365)
---
CHANGELOG.md | 1 +
lib/install.ps1 | 9 +++++++--
libexec/scoop-import.ps1 | 23 +++++++++++------------
3 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27f66c4e57..89cb0b71f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
- **decompress:** Exclude '*.nsis' that may cause error ([#5294](https://github.com/ScoopInstaller/Scoop/issues/5294))
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
+- **core:** Fix scripts' calling parameters ([#5365](https://github.com/ScoopInstaller/Scoop/issues/5365))
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
diff --git a/lib/install.ps1 b/lib/install.ps1
index 384c2e38b7..22b76423ca 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -1067,13 +1067,18 @@ function ensure_none_failed($apps) {
foreach ($app in $apps) {
$app = ($app -split '/|\\')[-1] -replace '\.json$', ''
foreach ($global in $true, $false) {
+ if ($global) {
+ $instArgs = @('--global')
+ } else {
+ $instArgs = @()
+ }
if (failed $app $global) {
if (installed $app $global) {
info "Repair previous failed installation of $app."
- & "$PSScriptRoot\..\libexec\scoop-reset.ps1" $app$(if ($global) { ' --global' })
+ & "$PSScriptRoot\..\libexec\scoop-reset.ps1" $app @instArgs
} else {
warn "Purging previous failed installation of $app."
- & "$PSScriptRoot\..\libexec\scoop-uninstall.ps1" $app$(if ($global) { ' --global' })
+ & "$PSScriptRoot\..\libexec\scoop-uninstall.ps1" $app @instArgs
}
}
}
diff --git a/libexec/scoop-import.ps1 b/libexec/scoop-import.ps1
index 1221e127bf..383e78578e 100644
--- a/libexec/scoop-import.ps1
+++ b/libexec/scoop-import.ps1
@@ -34,20 +34,19 @@ foreach ($item in $import.buckets) {
}
foreach ($item in $import.apps) {
+ $instArgs = @()
+ $holdArgs = @()
$info = $item.Info -Split ', '
- $global = if ('Global install' -in $info) {
- ' --global'
- } else {
- ''
+ if ('Global install' -in $info) {
+ $instArgs += '--global'
+ $holdArgs += '--global'
}
- $arch = if ('64bit' -in $info -and '64bit' -ne $def_arch) {
- ' --arch 64bit'
+ if ('64bit' -in $info -and '64bit' -ne $def_arch) {
+ $instArgs += '--arch', '64bit'
} elseif ('32bit' -in $info -and '32bit' -ne $def_arch) {
- ' --arch 32bit'
+ $instArgs += '--arch', '32bit'
} elseif ('arm64' -in $info -and 'arm64' -ne $def_arch) {
- ' --arch arm64'
- } else {
- ''
+ $instArgs += '--arch', 'arm64'
}
$app = if ($item.Source -in $bucket_names) {
@@ -58,9 +57,9 @@ foreach ($item in $import.apps) {
$item.Source
}
- & "$PSScriptRoot\scoop-install.ps1" $app$global$arch
+ & "$PSScriptRoot\scoop-install.ps1" $app @instArgs
if ('Held package' -in $info) {
- & "$PSScriptRoot\scoop-hold.ps1" $($item.Name)$global
+ & "$PSScriptRoot\scoop-hold.ps1" $item.Name @holdArgs
}
}
From c00dd42cae224cba339f40a5abda4ad6c7ca9020 Mon Sep 17 00:00:00 2001
From: Valinor
Date: Sun, 26 Feb 2023 07:32:16 +0100
Subject: [PATCH 15/75] fix(getopt): Stop split arguments in `getopt()` and
ensure array by explicit arguments type (#5326)
Co-authored-by: Hsiao-nan Cheung
---
CHANGELOG.md | 1 +
lib/getopt.ps1 | 7 +------
test/Scoop-GetOpts.Tests.ps1 | 6 ++++++
3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89cb0b71f6..ec4d91723b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
- **decompress:** Exclude '*.nsis' that may cause error ([#5294](https://github.com/ScoopInstaller/Scoop/issues/5294))
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
+- **getopt:** Stop split arguments in `getopt()` and ensure array by explicit arguments type ([#5326](https://github.com/ScoopInstaller/Scoop/issues/5326))
- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
- **core:** Fix scripts' calling parameters ([#5365](https://github.com/ScoopInstaller/Scoop/issues/5365))
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
diff --git a/lib/getopt.ps1 b/lib/getopt.ps1
index 74ffae7c52..2de3ac6c0a 100644
--- a/lib/getopt.ps1
+++ b/lib/getopt.ps1
@@ -13,7 +13,7 @@
# following arguments are treated as non-option arguments, even if
# they begin with a hyphen. The "--" itself will not be included in
# the returned $opts. (POSIX-compatible)
-function getopt($argv, $shortopts, $longopts) {
+function getopt([String[]]$argv, [String]$shortopts, [String[]]$longopts) {
$opts = @{}; $rem = @()
function err($msg) {
@@ -24,10 +24,6 @@ function getopt($argv, $shortopts, $longopts) {
return [Regex]::Escape($str)
}
- # ensure these are arrays
- $argv = @($argv -split ' ')
- $longopts = @($longopts)
-
for ($i = 0; $i -lt $argv.Length; $i++) {
$arg = $argv[$i]
if ($null -eq $arg) { continue }
@@ -81,6 +77,5 @@ function getopt($argv, $shortopts, $longopts) {
$rem += $arg
}
}
-
$opts, $rem
}
diff --git a/test/Scoop-GetOpts.Tests.ps1 b/test/Scoop-GetOpts.Tests.ps1
index ef4d56a950..c55781ecbf 100644
--- a/test/Scoop-GetOpts.Tests.ps1
+++ b/test/Scoop-GetOpts.Tests.ps1
@@ -17,6 +17,12 @@ Describe 'getopt' -Tag 'Scoop' {
$err | Should -Be 'Option --arb requires an argument.'
}
+ It 'handle space in quote' {
+ $opt, $rem, $err = getopt '-x', 'space arg' 'x:' ''
+ $err | Should -BeNullOrEmpty
+ $opt.x | Should -Be 'space arg'
+ }
+
It 'handle unrecognized short option' {
$null, $null, $err = getopt '-az' 'a' ''
$err | Should -Be 'Option -z not recognized.'
From 8acfeeefcf0f5280922a12e79993a24ba615d1f4 Mon Sep 17 00:00:00 2001
From: Stephen Albert-Moore
Date: Sun, 26 Feb 2023 14:19:54 -0500
Subject: [PATCH 16/75] fix(scoop-info) --verbose file size collection (#5352)
---
CHANGELOG.md | 1 +
libexec/scoop-info.ps1 | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec4d91723b..8d856f9e18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
+- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
### Code Refactoring
diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1
index 625a3c6463..675611435d 100644
--- a/libexec/scoop-info.ps1
+++ b/libexec/scoop-info.ps1
@@ -112,7 +112,7 @@ if ($status.installed) {
# Collect file list from each location
$appFiles = Get-ChildItem $appsdir -Filter $app
- $currentFiles = Get-ChildItem $appFiles -Filter (Select-CurrentVersion $app $global)
+ $currentFiles = Get-ChildItem $appFiles.FullName -Filter (Select-CurrentVersion $app $global)
$persistFiles = Get-ChildItem $persist_dir -ErrorAction Ignore # Will fail if app does not persist data
$cacheFiles = Get-ChildItem $cachedir -Filter "$app#*"
@@ -120,7 +120,7 @@ if ($status.installed) {
$fileTotals = @()
foreach ($fileType in ($appFiles, $currentFiles, $persistFiles, $cacheFiles)) {
if ($null -ne $fileType) {
- $fileSum = (Get-ChildItem $fileType -Recurse | Measure-Object -Property Length -Sum).Sum
+ $fileSum = (Get-ChildItem $fileType.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
$fileTotals += coalesce $fileSum 0
} else {
$fileTotals += 0
From 7826d6fe2d47979043226f19add96f936aad965b Mon Sep 17 00:00:00 2001
From: Richard Kuhnt
Date: Mon, 27 Feb 2023 20:11:40 +0100
Subject: [PATCH 17/75] perf(decompress): disable progress bar to improve
Expand-Archive performance (#5410)
See: https://github.com/ScoopInstaller/Install/pull/42
---------
Co-authored-by: Hsiao-nan Cheung
---
CHANGELOG.md | 4 ++++
lib/decompress.ps1 | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d856f9e18..d7089a089b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
+### Performance Improvements
+
+- **decompress:** Disable progress bar to improve `Expand-Archive` performance ([#5410](https://github.com/ScoopInstaller/Scoop/issues/5410))
+
### Code Refactoring
- **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))
diff --git a/lib/decompress.ps1 b/lib/decompress.ps1
index 785421c1a5..bdee90d620 100644
--- a/lib/decompress.ps1
+++ b/lib/decompress.ps1
@@ -241,8 +241,14 @@ function Expand-ZipArchive {
$OriDestinationPath = $DestinationPath
$DestinationPath = "$DestinationPath\_tmp"
}
+ # Disable progress bar to gain performance
+ $oldProgressPreference = $ProgressPreference
+ $global:ProgressPreference = 'SilentlyContinue'
+
# Compatible with Pscx v3 (https://github.com/Pscx/Pscx) ('Microsoft.PowerShell.Archive' is not needed for Pscx v4)
Microsoft.PowerShell.Archive\Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force
+
+ $global:ProgressPreference = $oldProgressPreference
if ($ExtractDir) {
movedir "$DestinationPath\$ExtractDir" $OriDestinationPath | Out-Null
Remove-Item $DestinationPath -Recurse -Force
From 559c6f9e64912ae341dad29997d59564e08c9e40 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Fri, 10 Mar 2023 17:24:41 +0800
Subject: [PATCH 18/75] feat(bucket): Make official buckets higher priority
(#5398)
---
CHANGELOG.md | 1 +
lib/buckets.ps1 | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d7089a089b..a654e28164 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
- **config:** Support portable config file ([#5369](https://github.com/ScoopInstaller/Scoop/issues/5369))
+- **bucket:** Make official buckets higher priority ([#5398](https://github.com/ScoopInstaller/Scoop/issues/5398))
### Bug Fixes
diff --git a/lib/buckets.ps1 b/lib/buckets.ps1
index 14e3dbf318..9219f9c1a1 100644
--- a/lib/buckets.ps1
+++ b/lib/buckets.ps1
@@ -58,10 +58,18 @@ function Get-LocalBucket {
.SYNOPSIS
List all local buckets.
#>
- $bucketNames = (Get-ChildItem -Path $bucketsdir -Directory).Name
+ $bucketNames = [System.Collections.Generic.List[String]](Get-ChildItem -Path $bucketsdir -Directory).Name
if ($null -eq $bucketNames) {
return @() # Return a zero-length list instead of $null.
} else {
+ $knownBuckets = known_buckets
+ for ($i = $knownBuckets.Count - 1; $i -ge 0 ; $i--) {
+ $name = $knownBuckets[$i]
+ if ($bucketNames.Contains($name)) {
+ [void]$bucketNames.Remove($name)
+ $bucketNames.Insert(0, $name)
+ }
+ }
return $bucketNames
}
}
From 41620bb169d161a6b99443e18cf2069226e60bdc Mon Sep 17 00:00:00 2001
From: "L. Yeung"
Date: Sat, 11 Mar 2023 21:39:45 +0800
Subject: [PATCH 19/75] feat(core): Add `-Silent` switch for
`Invoke-ExternalCommand` (#5346)
---
CHANGELOG.md | 1 +
lib/core.ps1 | 51 +++++++++++++++++++++++++++++----------------------
2 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a654e28164..b4c7526022 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
- **config:** Support portable config file ([#5369](https://github.com/ScoopInstaller/Scoop/issues/5369))
- **bucket:** Make official buckets higher priority ([#5398](https://github.com/ScoopInstaller/Scoop/issues/5398))
+- **core:** Add `-Quiet` switch for `Invoke-ExternalCommand` ([#5346](https://github.com/ScoopInstaller/Scoop/issues/5346))
### Bug Fixes
diff --git a/lib/core.ps1 b/lib/core.ps1
index 68ad7a3e9e..7b1cbf0e02 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -568,6 +568,9 @@ function Invoke-ExternalCommand {
[Parameter(ParameterSetName = "UseShellExecute")]
[Switch]
$RunAs,
+ [Parameter(ParameterSetName = "UseShellExecute")]
+ [Switch]
+ $Quiet,
[Alias("Msg")]
[String]
$Activity,
@@ -597,29 +600,33 @@ function Invoke-ExternalCommand {
if ($RunAs) {
$Process.StartInfo.UseShellExecute = $true
$Process.StartInfo.Verb = 'RunAs'
- } else {
- $Process.StartInfo.CreateNoWindow = $true
- }
- if ($FilePath -match '^((cmd|cscript|wscript|msiexec)(\.exe)?|.*\.(bat|cmd|js|vbs|wsf))$') {
- $Process.StartInfo.Arguments = $ArgumentList -join ' '
- } elseif ($Process.StartInfo.ArgumentList.Add) {
- # ArgumentList is supported in PowerShell 6.1 and later (built on .NET Core 2.1+)
- # ref-1: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.argumentlist?view=net-6.0
- # ref-2: https://docs.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.2#net-framework-vs-net-core
- $ArgumentList | ForEach-Object { $Process.StartInfo.ArgumentList.Add($_) }
- } else {
- # escape arguments manually in lower versions, refer to https://docs.microsoft.com/en-us/previous-versions/17w5ykft(v=vs.85)
- $escapedArgs = $ArgumentList | ForEach-Object {
- # escape N consecutive backslash(es), which are followed by a double quote, to 2N consecutive ones
- $s = $_ -replace '(\\+)"', '$1$1"'
- # escape N consecutive backslash(es), which are at the end of the string, to 2N consecutive ones
- $s = $s -replace '(\\+)$', '$1$1'
- # escape double quotes
- $s = $s -replace '"', '\"'
- # quote the argument
- "`"$s`""
+ }
+ if ($Quiet) {
+ $Process.StartInfo.UseShellExecute = $true
+ $Process.StartInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
+ }
+ if ($ArgumentList.Length -gt 0) {
+ if ($FilePath -match '^((cmd|cscript|wscript|msiexec)(\.exe)?|.*\.(bat|cmd|js|vbs|wsf))$') {
+ $Process.StartInfo.Arguments = $ArgumentList -join ' '
+ } elseif ($Process.StartInfo.ArgumentList.Add) {
+ # ArgumentList is supported in PowerShell 6.1 and later (built on .NET Core 2.1+)
+ # ref-1: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.argumentlist?view=net-6.0
+ # ref-2: https://docs.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.2#net-framework-vs-net-core
+ $ArgumentList | ForEach-Object { $Process.StartInfo.ArgumentList.Add($_) }
+ } else {
+ # escape arguments manually in lower versions, refer to https://docs.microsoft.com/en-us/previous-versions/17w5ykft(v=vs.85)
+ $escapedArgs = $ArgumentList | ForEach-Object {
+ # escape N consecutive backslash(es), which are followed by a double quote, to 2N consecutive ones
+ $s = $_ -replace '(\\+)"', '$1$1"'
+ # escape N consecutive backslash(es), which are at the end of the string, to 2N consecutive ones
+ $s = $s -replace '(\\+)$', '$1$1'
+ # escape double quotes
+ $s = $s -replace '"', '\"'
+ # quote the argument
+ "`"$s`""
+ }
+ $Process.StartInfo.Arguments = $escapedArgs -join ' '
}
- $Process.StartInfo.Arguments = $escapedArgs -join ' '
}
try {
[void]$Process.Start()
From ad0f6178d05192497c07aef55d4f3aff7516b982 Mon Sep 17 00:00:00 2001
From: Ross Smith II
Date: Sat, 11 Mar 2023 05:42:14 -0800
Subject: [PATCH 20/75] feat(bucket): Switch nirsoft bucket to
ScoopInstaller/Nirsoft (#5328)
---
CHANGELOG.md | 1 +
README.md | 6 +++---
buckets.json | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b4c7526022..15ad64f07e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
### Features
- **scoop-update:** Add support for parallel syncing buckets in PowerShell 7 and improve output ([#5122](https://github.com/ScoopInstaller/Scoop/issues/5122))
+- **bucket:** Switch nirsoft bucket to ScoopInstaller/Nirsoft ([#5328](https://github.com/ScoopInstaller/Scoop/issues/5328))
- **config:** Support portable config file ([#5369](https://github.com/ScoopInstaller/Scoop/issues/5369))
- **bucket:** Make official buckets higher priority ([#5398](https://github.com/ScoopInstaller/Scoop/issues/5398))
- **core:** Add `-Quiet` switch for `Invoke-ExternalCommand` ([#5346](https://github.com/ScoopInstaller/Scoop/issues/5346))
diff --git a/README.md b/README.md
index 9895584498..b1aae3249f 100644
--- a/README.md
+++ b/README.md
@@ -119,10 +119,10 @@ The following buckets are known to scoop:
- [extras](https://github.com/ScoopInstaller/Extras) - Apps that don't fit the main bucket's [criteria](https://github.com/ScoopInstaller/Scoop/wiki/Criteria-for-including-apps-in-the-main-bucket)
- [games](https://github.com/Calinou/scoop-games) - Open source/freeware games and game-related tools
- [nerd-fonts](https://github.com/matthewjberger/scoop-nerd-fonts) - Nerd Fonts
-- [nirsoft](https://github.com/kodybrown/scoop-nirsoft) - Almost all of the [250+](https://rasa.github.io/scoop-directory/by-apps#kodybrown_scoop-nirsoft) apps from [Nirsoft](https://nirsoft.net)
-- [sysinternals](https://github.com/niheaven/scoop-sysinternals) - Sysinternals Suite and all individual application from [Microsoft](https://learn.microsoft.com/sysinternals/)
+- [nirsoft](https://github.com/ScoopInstaller/Nirsoft) - Almost all of the 280+ apps from [Nirsoft](https://nirsoft.net)
+- [sysinternals](https://github.com/niheaven/scoop-sysinternals) - Sysinternals Suite and all individual applications from [Microsoft](https://learn.microsoft.com/sysinternals/)
- [java](https://github.com/ScoopInstaller/Java) - A collection of Java development kits (JDKs), Java runtime engines (JREs), Java's virtual machine debugging tools and Java based runtime engines.
-- [nonportable](https://github.com/ScoopInstaller/Nonportable) - Non-portable apps (may require UAC)
+- [nonportable](https://github.com/ScoopInstaller/Nonportable) - Non-portable apps (may require UAC/Administrator rights)
- [php](https://github.com/ScoopInstaller/PHP) - Installers for most versions of PHP
- [versions](https://github.com/ScoopInstaller/Versions) - Alternative versions of apps found in other buckets
diff --git a/buckets.json b/buckets.json
index b192cac40f..6d5b13712c 100644
--- a/buckets.json
+++ b/buckets.json
@@ -2,7 +2,7 @@
"main": "https://github.com/ScoopInstaller/Main",
"extras": "https://github.com/ScoopInstaller/Extras",
"versions": "https://github.com/ScoopInstaller/Versions",
- "nirsoft": "https://github.com/kodybrown/scoop-nirsoft",
+ "nirsoft": "https://github.com/ScoopInstaller/Nirsoft",
"sysinternals": "https://github.com/niheaven/scoop-sysinternals",
"php": "https://github.com/ScoopInstaller/PHP",
"nerd-fonts": "https://github.com/matthewjberger/scoop-nerd-fonts",
From a20bb4f1a60514151b1e853c5b002143a7068733 Mon Sep 17 00:00:00 2001
From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
Date: Thu, 16 Mar 2023 20:09:18 +0530
Subject: [PATCH 21/75] fix(shim): Use bash executable directly (#5433)
* fix(shim): Use bash executable directly
* Update CHANGELOG.md
---
CHANGELOG.md | 1 +
lib/core.ps1 | 12 +-----------
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15ad64f07e..73b1a5ee36 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
+- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
### Performance Improvements
diff --git a/lib/core.ps1 b/lib/core.ps1
index 7b1cbf0e02..4dee038405 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -905,19 +905,9 @@ function shim($path, $global, $name, $arg) {
) -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
- if (!(Get-CommandPath git)) {
- error "Can't shim '$shim': 'git' is needed but not installed."
- error "Please install git ('scoop install git') and try again."
- exit 1
- }
- $gitdir = (Get-Item (Get-CommandPath git) -ErrorAction:Stop).Directory.Parent
- if ($gitdir.FullName -imatch 'mingw') {
- $gitdir = $gitdir.Parent
- }
@(
"@rem $resolved_path",
- "@`"$(Join-Path (Join-Path $gitdir.FullName 'bin') 'bash.exe')`" `"$resolved_path`" $arg %*"
+ "@bash `"$resolved_path`" $arg %*"
) -join "`r`n" | Out-UTF8File "$shim.cmd"
warn_on_overwrite $shim $path
From 2accaae5d1642562ec4e6ca6e485857b8b1d331a Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Mon, 20 Mar 2023 22:44:55 +0800
Subject: [PATCH 22/75] fix(core): Rewrite config file when needed (#5439)
---
CHANGELOG.md | 1 +
lib/core.ps1 | 9 ++-------
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73b1a5ee36..9aa5875c5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@
- **shortcuts:** Output correctly formatted path ([#5333](https://github.com/ScoopInstaller/Scoop/issues/5333))
- **core:** Fix scripts' calling parameters ([#5365](https://github.com/ScoopInstaller/Scoop/issues/5365))
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
+- **core:** Rewrite config file when needed ([#5439](https://github.com/ScoopInstaller/Scoop/issues/5439))
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
diff --git a/lib/core.ps1 b/lib/core.ps1
index 4dee038405..c3d04273a6 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -1339,7 +1339,7 @@ if ($pathExpected) {
$scoopConfig = load_cfg $configFile
# NOTE Scoop config file migration. Remove this after 2023/6/30
-if ($scoopConfig) {
+if ($scoopConfig -and $scoopConfig.PSObject.Properties.Name -contains 'lastUpdate') {
$newConfigNames = @{
'lastUpdate' = 'last_update'
'SCOOP_REPO' = 'scoop_repo'
@@ -1357,14 +1357,9 @@ if ($scoopConfig) {
$value = $scoopConfig.$($_.Key)
$scoopConfig.PSObject.Properties.Remove($_.Key)
$scoopConfig | Add-Member -MemberType NoteProperty -Name $_.Value -Value $value
- if ($_.Key -eq 'lastUpdate') {
- $scoopConfigChg = $true
- }
}
}
- if ($scoopConfigChg) { # Only save config file if there was a change
- ConvertTo-Json $scoopConfig | Out-UTF8File -FilePath $configFile
- }
+ ConvertTo-Json $scoopConfig | Out-UTF8File -FilePath $configFile
}
# END NOTE
From 682a1e2c07e9d47b5c1bba9900a73abfb35e7440 Mon Sep 17 00:00:00 2001
From: Richard Kuhnt
Date: Mon, 20 Mar 2023 16:52:41 +0100
Subject: [PATCH 23/75] fix(git): set HTTP(S)_PROXY only in process scope to
prevent race condition (#5436)
---
CHANGELOG.md | 1 +
lib/core.ps1 | 19 ++++++-------------
2 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9aa5875c5c..03f8c797f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@
- **core:** Fix scripts' calling parameters ([#5365](https://github.com/ScoopInstaller/Scoop/issues/5365))
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
- **core:** Rewrite config file when needed ([#5439](https://github.com/ScoopInstaller/Scoop/issues/5439))
+- **core:** Prevents leaking HTTP(S)_PROXY env vars to current sessions after Invoke-Git in parallel execution ([#5436](https://github.com/ScoopInstaller/Scoop/pull/5436))
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
diff --git a/lib/core.ps1 b/lib/core.ps1
index c3d04273a6..a61f793072 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -155,25 +155,18 @@ function Invoke-Git {
}
if($ArgumentList -Match '\b(clone|checkout|pull|fetch|ls-remote)\b') {
- $old_https = $env:HTTPS_PROXY
- $old_http = $env:HTTP_PROXY
- try {
+ $j = Start-Job -ScriptBlock {
# convert proxy setting for git
- if ($proxy.StartsWith('currentuser@')) {
+ $proxy = $using:proxy
+ if ($proxy -and $proxy.StartsWith('currentuser@')) {
$proxy = $proxy.Replace('currentuser@', ':@')
}
$env:HTTPS_PROXY = $proxy
$env:HTTP_PROXY = $proxy
- return & $git @ArgumentList
- }
- catch {
- error $_
- return
- }
- finally {
- $env:HTTPS_PROXY = $old_https
- $env:HTTP_PROXY = $old_http
+ & $using:git @using:ArgumentList
}
+ $o = $j | Receive-Job -Wait -AutoRemoveJob
+ return $o
}
return & $git @ArgumentList
From cddc52e03b4151700594f2cd179eecfa515f33e6 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Mon, 27 Mar 2023 14:37:10 +0800
Subject: [PATCH 24/75] docs(scoop-info): Fix help message (#5445)
---
CHANGELOG.md | 4 ++++
libexec/scoop-info.ps1 | 6 +++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 03f8c797f3..be4ac97a7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,10 @@
- **bucket:** Skip manifest validation if no manifest changes ([#5270](https://github.com/ScoopInstaller/Scoop/issues/5270))
+### Documentation
+
+- **scoop-info:** Fix help message([#5445](https://github.com/ScoopInstaller/Scoop/issues/5445))
+
## [v0.3.1](https://github.com/ScoopInstaller/Scoop/compare/v0.3.0...v0.3.1) - 2022-11-15
### Features
diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1
index 675611435d..3cf58e4118 100644
--- a/libexec/scoop-info.ps1
+++ b/libexec/scoop-info.ps1
@@ -1,7 +1,7 @@
-# Usage: scoop info [--verbose]
+# Usage: scoop info [options]
# Summary: Display information about an app
-# Options:
-# -v, --verbose Show full paths and URLs
+# Help: Options:
+# -v, --verbose Show full paths and URLs
. "$PSScriptRoot\..\lib\getopt.ps1"
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest'
From 52059ca1acce6d1151919a4a9906ab456d3df847 Mon Sep 17 00:00:00 2001
From: 0x574859
Date: Fri, 7 Apr 2023 13:05:46 +0800
Subject: [PATCH 25/75] fix(env): Apply env immediately by `SendMessageTimeout`
(#5452)
---
CHANGELOG.md | 2 +-
lib/core.ps1 | 25 +++++++++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be4ac97a7e..a685eacf3e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,7 +18,7 @@
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
- **core:** Rewrite config file when needed ([#5439](https://github.com/ScoopInstaller/Scoop/issues/5439))
- **core:** Prevents leaking HTTP(S)_PROXY env vars to current sessions after Invoke-Git in parallel execution ([#5436](https://github.com/ScoopInstaller/Scoop/pull/5436))
-- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395))
+- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395), [#5452](https://github.com/ScoopInstaller/Scoop/pull/5452))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
diff --git a/lib/core.ps1 b/lib/core.ps1
index a61f793072..3b66654b97 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -662,6 +662,30 @@ 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'
@@ -684,6 +708,7 @@ function env($name, $global, $val = '__get') {
[Microsoft.Win32.RegistryValueKind]::String
}
$EnvRegisterKey.SetValue($name, $val, $RegistryValueKind)
+ Publish-Env
}
}
From 1d140585a4895c533a39b08e17ab615cdbfe323f Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Tue, 30 May 2023 05:46:05 +0000
Subject: [PATCH 26/75] fix(scoop-checkup): Skip defender check in Windows
Sandbox (#5519)
---
CHANGELOG.md | 1 +
libexec/scoop-checkup.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a685eacf3e..0bcc94c162 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,7 @@
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
+- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519]https://github.com/ScoopInstaller/Scoop/issues/5519)
### Performance Improvements
diff --git a/libexec/scoop-checkup.ps1 b/libexec/scoop-checkup.ps1
index a775ec3964..6b2ed4760c 100644
--- a/libexec/scoop-checkup.ps1
+++ b/libexec/scoop-checkup.ps1
@@ -10,7 +10,7 @@ $defenderIssues = 0
$adminPrivileges = ([System.Security.Principal.WindowsPrincipal] [System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
-if ($adminPrivileges) {
+if ($adminPrivileges -and $env:USERNAME -ne 'WDAGUtilityAccount') {
$defenderIssues += !(check_windows_defender $false)
$defenderIssues += !(check_windows_defender $true)
}
From 3dfb4bfd978f2c76e3a3080f62d4628901bcde31 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Thu, 29 Jun 2023 16:18:19 +0000
Subject: [PATCH 27/75] fix(buckets): Avoid error messages for unexpected dir
(#5549)
---
CHANGELOG.md | 1 +
lib/buckets.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0bcc94c162..808b9c8ca6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519]https://github.com/ScoopInstaller/Scoop/issues/5519)
+- **buckets:** Avoid error messages for unexpected dir ([#5549]https://github.com/ScoopInstaller/Scoop/issues/5549)
### Performance Improvements
diff --git a/lib/buckets.ps1 b/lib/buckets.ps1
index 9219f9c1a1..63f6afc0a7 100644
--- a/lib/buckets.ps1
+++ b/lib/buckets.ps1
@@ -111,7 +111,7 @@ function list_buckets {
$bucket.Updated = Invoke-Git -Path $path -ArgumentList @('log', '--format=%aD', '-n', '1') | Get-Date
} else {
$bucket.Source = friendly_path $path
- $bucket.Updated = (Get-Item "$path\bucket").LastWriteTime
+ $bucket.Updated = (Get-Item "$path\bucket" -ErrorAction SilentlyContinue).LastWriteTime
}
$bucket.Manifests = Get-ChildItem "$path\bucket" -Force -Recurse -ErrorAction SilentlyContinue |
Measure-Object | Select-Object -ExpandProperty Count
From efdd6dd7ca603b2f63ae68c50359cd47eb31bf32 Mon Sep 17 00:00:00 2001
From: Bill ZHANG <36790218+Lutra-Fs@users.noreply.github.com>
Date: Fri, 11 Aug 2023 23:16:58 +1000
Subject: [PATCH 28/75] docs(CHANGELOG): Add missing brackets for the links
(#5596)
add missing brackets for the links
---
CHANGELOG.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 808b9c8ca6..eba7c57d4a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,8 +22,8 @@
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
-- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519]https://github.com/ScoopInstaller/Scoop/issues/5519)
-- **buckets:** Avoid error messages for unexpected dir ([#5549]https://github.com/ScoopInstaller/Scoop/issues/5549)
+- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
+- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
### Performance Improvements
From 0b4919ca32a9eb555ae3577d37115257a6ad2fa1 Mon Sep 17 00:00:00 2001
From: Bill ZHANG <36790218+Lutra-Fs@users.noreply.github.com>
Date: Mon, 11 Sep 2023 04:58:53 +1000
Subject: [PATCH 29/75] fix(scoop-virustotal): Continue execution when no app
but `-a` flag is provided (#5593)
* fix(scoop-virustotal): continue exec when no app but -a provided
* update CHANGELOG.md
* CHANGELOG: fix typo
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
libexec/scoop-virustotal.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eba7c57d4a..ca2ae10ca1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
+- **scoop-virustotal**: Fix `scoop-virustotal` when `--all' has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
### Performance Improvements
diff --git a/libexec/scoop-virustotal.ps1 b/libexec/scoop-virustotal.ps1
index f22bbbf1c0..30c5e8494b 100644
--- a/libexec/scoop-virustotal.ps1
+++ b/libexec/scoop-virustotal.ps1
@@ -36,7 +36,7 @@
$opt, $apps, $err = getopt $args 'asnup' @('all', 'scan', 'no-depends', 'no-update-scoop', 'passthru')
if ($err) { "scoop virustotal: $err"; exit 1 }
-if (!$apps) { my_usage; exit 1 }
+if (!$apps -and -$all) { my_usage; exit 1 }
$architecture = Format-ArchitectureString
if (is_scoop_outdated) {
From 6a35a22b0b7ac4da58be7d0d983807e5aedf0a72 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Mon, 11 Sep 2023 08:20:07 +0000
Subject: [PATCH 30/75] fix(scoop-checkup): Change the message level of helpers
from ERROR to WARN (#5614)
* fix(scoop-checkup): Downgrade the message level of helpers from ERROR to WARN
* update CHANGELOG
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
libexec/scoop-checkup.ps1 | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca2ae10ca1..be44b989f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,7 @@
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
- **scoop-virustotal**: Fix `scoop-virustotal` when `--all' has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
+- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
### Performance Improvements
diff --git a/libexec/scoop-checkup.ps1 b/libexec/scoop-checkup.ps1
index 6b2ed4760c..111bd3463b 100644
--- a/libexec/scoop-checkup.ps1
+++ b/libexec/scoop-checkup.ps1
@@ -20,17 +20,17 @@ $issues += !(check_long_paths)
$issues += !(Get-WindowsDeveloperModeStatus)
if (!(Test-HelperInstalled -Helper 7zip)) {
- error "'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' or 'scoop install 7zip-zstd'."
$issues++
}
if (!(Test-HelperInstalled -Helper Innounp)) {
- error "'Inno Setup Unpacker' is not installed! It's required for unpacking InnoSetup files. Please run 'scoop install innounp'."
+ warn "'Inno Setup Unpacker' is not installed! It's required for unpacking InnoSetup files. Please run 'scoop install innounp'."
$issues++
}
if (!(Test-HelperInstalled -Helper Dark)) {
- error "'dark' is not installed! It's required for unpacking installers created with the WiX Toolset. Please run 'scoop install dark' or 'scoop install wixtoolset'."
+ warn "'dark' is not installed! It's required for unpacking installers created with the WiX Toolset. Please run 'scoop install dark' or 'scoop install wixtoolset'."
$issues++
}
From aa09601503391a2eae93bb396873bd1f6a35c4bf Mon Sep 17 00:00:00 2001
From: walpo <68171111+walpox@users.noreply.github.com>
Date: Mon, 2 Oct 2023 11:06:06 +0200
Subject: [PATCH 31/75] docs(readme): Improve documentation language (#5638)
* readme.md: refactor HTML blocks
* readme.md: enhance style and fix typos and more
* readme.md: improve composition
* Update README.md
It seems GitHub does not work well with the 'style' attribute, so the deprecated attribute 'align' cannot be replaced.
* readme.md: update writing
* Update README.md
* Update README.md
* Update CHANGELOG.md
---------
Co-authored-by: walpo <3212100-walpo@users.noreply.gitlab.com>
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
README.md | 103 +++++++++++++++++++++++++++------------------------
2 files changed, 55 insertions(+), 49 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be44b989f8..e03c02a22d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -51,6 +51,7 @@
### Documentation
- **scoop-info:** Fix help message([#5445](https://github.com/ScoopInstaller/Scoop/issues/5445))
+- **readme:** Improve documentation language ([#5638](https://github.com/ScoopInstaller/Scoop/issues/5638))
## [v0.3.1](https://github.com/ScoopInstaller/Scoop/compare/v0.3.0...v0.3.1) - 2022-11-15
diff --git a/README.md b/README.md
index b1aae3249f..641c0f6d76 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,17 @@
-
+
Scoop
+
- Scoop
-
-Features
-|
-Installation
-|
-Documentation
+ Features
+ |
+ Installation
+ |
+ Documentation
-- - -
-
+---
+
+
@@ -36,43 +36,48 @@ Scoop is a command-line installer for Windows.
## What does Scoop do?
-Scoop installs programs from the command line with a minimal amount of friction. It:
+Scoop installs apps from the command line with a minimal amount of friction. It:
-- Eliminates permission popup windows
-- Hides GUI wizard-style installers
-- Prevents PATH pollution from installing lots of programs
-- Avoids unexpected side-effects from installing and uninstalling programs
-- Finds and installs dependencies automatically
-- Performs all the extra setup steps itself to get a working program
+- Eliminates [User Account Control](https://learn.microsoft.com/windows/security/application-security/application-control/user-account-control/) (UAC) prompt notifications.
+- Hides the graphical user interface (GUI) of wizard-style installers.
+- Prevents polluting the `PATH` environment variable. Normally, this variable gets cluttered as different apps are installed on the device.
+- Avoids unexpected side effects from installing and uninstalling apps.
+- Resolves and installs dependencies automatically.
+- Performs all the necessary steps to get an app to a working state.
-Scoop is very scriptable, so you can run repeatable setups to get your environment just the way you like, e.g.:
+Scoop is quite script-friendly. Your environment can become the way you like by using repeatable setups. For example:
-```powershell
+```console
scoop install sudo
sudo scoop install 7zip git openssh --global
scoop install aria2 curl grep sed less touch
scoop install python ruby go perl
```
-If you've built software that you'd like others to use, Scoop is an alternative to building an installer (e.g. MSI or InnoSetup) — you just need to zip your program and provide a JSON manifest that describes how to install it.
+If you have built software that you would like others to use, Scoop is an alternative to building an installer (like MSI or InnoSetup). You just need to compress your app to a `.zip` file and provide a JSON manifest that describes how to install it.
## Installation
-Run the following command from a **non-admin** PowerShell to install scoop to its default location `C:\Users\\scoop`.
+Run the following commands from a regular (non-admin) PowerShell terminal to install Scoop:
```powershell
-iwr -useb get.scoop.sh | iex
+Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
```
-Advanced installation instruction and full documentation of the installer are available in [ScoopInstaller/Install](https://github.com/ScoopInstaller/Install). Please create new issues there if you have questions about the installation.
+**Note**: The first command makes your device allow running the installation and management scripts. This is necessary because Windows 10 client devices restrict execution of any PowerShell scripts by default.
-## [Documentation](https://github.com/ScoopInstaller/Scoop/wiki)
+It will install Scoop to its default location:
+
+`C:\Users\\scoop`
+
+You can find the complete documentation about the installer, including advanced installation configurations, in [ScoopInstaller/Install](https://github.com/ScoopInstaller/Install). Please create new issues there if you have questions about the installation.
## Multi-connection downloads with `aria2`
Scoop can utilize [`aria2`](https://github.com/aria2/aria2) to use multi-connection downloads. Simply install `aria2` through Scoop and it will be used for all downloads afterward.
-```powershell
+```console
scoop install aria2
```
@@ -90,54 +95,54 @@ You can tweak the following `aria2` settings with the `scoop config` command:
## Inspiration
-- [Homebrew](http://mxcl.github.io/homebrew/)
-- [sub](https://github.com/37signals/sub#readme)
+- [Homebrew](https://brew.sh/)
+- [Sub](https://signalvnoise.com/posts/3264-automating-with-convention-introducing-sub)
## What sort of apps can Scoop install?
-The apps that install best with Scoop are commonly called "portable" apps: i.e. compressed program files that run stand-alone when extracted and don't have side-effects like changing the registry or putting files outside the program directory.
-
-Since installers are common, Scoop supports them too (and their uninstallers).
+The apps that are most likely to get installed fine with Scoop are those referred to as "portable" apps. These apps are compressed files which can run standalone after being extracted. This type of apps does not produce side effects like changing the Windows Registry or placing files outside the app directory.
-Scoop is also great at handling single-file programs and Powershell scripts. These don't even need to be compressed. See the [runat](https://github.com/ScoopInstaller/Main/blob/master/bucket/runat.json) package for an example: it's really just a GitHub gist.
+Scoop also supports installer files and their uninstallation methods. Likewise, it can handle single-file apps and PowerShell scripts. These do not even need to be compressed. See the [runat](https://github.com/ScoopInstaller/Main/blob/master/bucket/runat.json) package for an example: it is simply a GitHub gist.
### Contribute to this project
-If you'd like to improve Scoop by adding features or fixing bugs, please read our [Contributing Guide](https://github.com/ScoopInstaller/.github/blob/main/.github/CONTRIBUTING.md).
+If you would like to improve Scoop by adding features or fixing bugs, please read our [Contributing Guide](https://github.com/ScoopInstaller/.github/blob/main/.github/CONTRIBUTING.md).
### Support this project
-If you find Scoop useful and would like to support ongoing development and maintenance, here's how:
+If you find Scoop useful and would like to support the ongoing development and maintenance of this project, you can donate here:
-- [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DM2SUH9EUXSKJ) (one-time donation)
+- [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DM2SUH9EUXSKJ) (one-time donations)
## Known application buckets
-The following buckets are known to scoop:
+The following buckets are known to Scoop:
-- [main](https://github.com/ScoopInstaller/Main) - Default bucket for the most common (mostly CLI) apps
-- [extras](https://github.com/ScoopInstaller/Extras) - Apps that don't fit the main bucket's [criteria](https://github.com/ScoopInstaller/Scoop/wiki/Criteria-for-including-apps-in-the-main-bucket)
-- [games](https://github.com/Calinou/scoop-games) - Open source/freeware games and game-related tools
-- [nerd-fonts](https://github.com/matthewjberger/scoop-nerd-fonts) - Nerd Fonts
-- [nirsoft](https://github.com/ScoopInstaller/Nirsoft) - Almost all of the 280+ apps from [Nirsoft](https://nirsoft.net)
-- [sysinternals](https://github.com/niheaven/scoop-sysinternals) - Sysinternals Suite and all individual applications from [Microsoft](https://learn.microsoft.com/sysinternals/)
-- [java](https://github.com/ScoopInstaller/Java) - A collection of Java development kits (JDKs), Java runtime engines (JREs), Java's virtual machine debugging tools and Java based runtime engines.
-- [nonportable](https://github.com/ScoopInstaller/Nonportable) - Non-portable apps (may require UAC/Administrator rights)
-- [php](https://github.com/ScoopInstaller/PHP) - Installers for most versions of PHP
-- [versions](https://github.com/ScoopInstaller/Versions) - Alternative versions of apps found in other buckets
+- [main](https://github.com/ScoopInstaller/Main) - Default bucket which contains popular non-GUI apps.
+- [extras](https://github.com/ScoopInstaller/Extras) - Apps that do not fit the main bucket's [criteria](https://github.com/ScoopInstaller/Scoop/wiki/Criteria-for-including-apps-in-the-main-bucket).
+- [games](https://github.com/Calinou/scoop-games) - Open-source and freeware video games and game-related tools.
+- [nerd-fonts](https://github.com/matthewjberger/scoop-nerd-fonts) - Nerd Fonts.
+- [nirsoft](https://github.com/ScoopInstaller/Nirsoft) - A collection of over 250+ apps from [Nirsoft](https://nirsoft.net).
+- [sysinternals](https://github.com/niheaven/scoop-sysinternals) - The Sysinternals suite from [Microsoft](https://learn.microsoft.com/sysinternals/).
+- [java](https://github.com/ScoopInstaller/Java) - A collection of Java development kits (JDKs) and Java runtime engines (JREs), Java's virtual machine debugging tools and Java based runtime engines.
+- [nonportable](https://github.com/ScoopInstaller/Nonportable) - Non-portable apps (may trigger UAC prompts).
+- [php](https://github.com/ScoopInstaller/PHP) - Installers for most versions of PHP.
+- [versions](https://github.com/ScoopInstaller/Versions) - Alternative versions of apps found in other buckets.
-The main bucket is installed by default. To add any of the other buckets, type:
+The `main` bucket is installed by default. You can make use of more buckets by typing:
```console
-scoop bucket add bucketname
+scoop bucket add
```
-For example, to add the extras bucket, type:
+For example, to add the `extras` bucket, type:
```console
scoop bucket add extras
```
+You would be able to install apps from the `extras` bucket now.
+
## Other application buckets
-Many other application buckets hosted on Github can be found in the [Scoop Directory](https://rasa.github.io/scoop-directory/) or via [other search engines](https://rasa.github.io/scoop-directory/#other-search-engines).
+Many other application buckets hosted on GitHub can be found on [ScoopSearch](https://scoop.sh/) or via [other search engines](https://rasa.github.io/scoop-directory/#other-search-engines).
From 43579714cc350fe5beb6820c26cfdd737afa4a61 Mon Sep 17 00:00:00 2001
From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
Date: Mon, 2 Oct 2023 20:59:50 +0530
Subject: [PATCH 32/75] fix(env): Publish environment change when deleting
variable (#5631)
* fix(env): Publish environment change when deleting variable
* Update CHANGELOG.md
---
CHANGELOG.md | 2 +-
lib/core.ps1 | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e03c02a22d..c50f808295 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,7 +18,7 @@
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
- **core:** Rewrite config file when needed ([#5439](https://github.com/ScoopInstaller/Scoop/issues/5439))
- **core:** Prevents leaking HTTP(S)_PROXY env vars to current sessions after Invoke-Git in parallel execution ([#5436](https://github.com/ScoopInstaller/Scoop/pull/5436))
-- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395), [#5452](https://github.com/ScoopInstaller/Scoop/pull/5452))
+- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395), [#5452](https://github.com/ScoopInstaller/Scoop/pull/5452), [#5631](https://github.com/ScoopInstaller/Scoop/pull/5631))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
diff --git a/lib/core.ps1 b/lib/core.ps1
index 3b66654b97..9796f8c6c2 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -699,6 +699,7 @@ function env($name, $global, $val = '__get') {
$EnvRegisterKey.GetValue($name, $null, $RegistryValueOption)
} elseif ($val -eq $null) {
$EnvRegisterKey.DeleteValue($name)
+ Publish-Env
} else {
$RegistryValueKind = if ($val.Contains('%')) {
[Microsoft.Win32.RegistryValueKind]::ExpandString
From 353137f0a9aef9a3da31eed62f4554d24af19bf4 Mon Sep 17 00:00:00 2001
From: Sp1d3R <98212676+spider2048@users.noreply.github.com>
Date: Tue, 3 Oct 2023 00:09:48 +0530
Subject: [PATCH 33/75] fix(shim): Remove console window for GUI apps (#5559)
* Change shim subsystem to prevent console window for GUI apps.
* Removed redundant log
* Update core.ps1
* Fixes file access rights and the log message
* update changelog
* Update CHANGELOG.md (PR Number)
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---------
Co-authored-by: Quasar
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
lib/core.ps1 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c50f808295..0624105c0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
### Bug Fixes
+- **shim:** Remove console window for GUI applications ([#5559](https://github.com/ScoopInstaller/Scoop/issues/5559))
- **decompress:** Exclude '*.nsis' that may cause error ([#5294](https://github.com/ScoopInstaller/Scoop/issues/5294))
- **autoupdate:** Fix file hash extraction ([#5295](https://github.com/ScoopInstaller/Scoop/issues/5295))
- **getopt:** Stop split arguments in `getopt()` and ensure array by explicit arguments type ([#5326](https://github.com/ScoopInstaller/Scoop/issues/5326))
diff --git a/lib/core.ps1 b/lib/core.ps1
index 9796f8c6c2..a1d3427182 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -1,3 +1,56 @@
+# Returns the subsystem of the EXE
+function Get-Subsystem($filePath) {
+ try {
+ $fileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
+ $binaryReader = [System.IO.BinaryReader]::new($fileStream)
+ } catch {
+ return -1 # leave the subsystem part silently
+ }
+
+ try {
+ $fileStream.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null
+ $peOffset = $binaryReader.ReadInt32()
+
+ $fileStream.Seek($peOffset, [System.IO.SeekOrigin]::Begin) | Out-Null
+ $fileHeaderOffset = $fileStream.Position
+
+ $fileStream.Seek(18, [System.IO.SeekOrigin]::Current) | Out-Null
+ $fileStream.Seek($fileHeaderOffset + 0x5C, [System.IO.SeekOrigin]::Begin) | Out-Null
+
+ return $binaryReader.ReadInt16()
+ } finally {
+ $binaryReader.Close()
+ $fileStream.Close()
+ }
+}
+
+function Change-Subsystem($filePath, $targetSubsystem) {
+ try {
+ $fileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
+ $binaryReader = [System.IO.BinaryReader]::new($fileStream)
+ $binaryWriter = [System.IO.BinaryWriter]::new($fileStream)
+ } catch {
+ Write-Output "Error opening File:'$filePath'"
+ return
+ }
+
+ try {
+ $fileStream.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null
+ $peOffset = $binaryReader.ReadInt32()
+
+ $fileStream.Seek($peOffset, [System.IO.SeekOrigin]::Begin) | Out-Null
+ $fileHeaderOffset = $fileStream.Position
+
+ $fileStream.Seek(18, [System.IO.SeekOrigin]::Current) | Out-Null
+ $fileStream.Seek($fileHeaderOffset + 0x5C, [System.IO.SeekOrigin]::Begin) | Out-Null
+
+ $binaryWriter.Write([System.Int16] $targetSubsystem)
+ } finally {
+ $binaryReader.Close()
+ $fileStream.Close()
+ }
+}
+
function Optimize-SecurityProtocol {
# .NET Framework 4.7+ has a default security protocol called 'SystemDefault',
# which allows the operating system to choose the best protocol to use.
@@ -839,6 +892,13 @@ function shim($path, $global, $name, $arg) {
if ($arg) {
Write-Output "args = $arg" | Out-UTF8File "$shim.shim" -Append
}
+
+ $target_subsystem = Get-Subsystem $resolved_path
+
+ if (($target_subsystem -ne 3) -and ($target_subsystem -ge 0)) { # Subsystem -eq 3 means `Console`, -ge 0 to ignore
+ Write-Output "Making $shim.exe a GUI binary."
+ Change-Subsystem "$shim.exe" $target_subsystem
+ }
} elseif ($path -match '\.(bat|cmd)$') {
# shim .bat, .cmd so they can be used by programs with no awareness of PSH
warn_on_overwrite "$shim.cmd" $path
From 6898773a8d51df4e226ab6088b32a489dd99a50a Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Tue, 3 Oct 2023 10:53:00 +0000
Subject: [PATCH 34/75] fix(core): Use relative path as fallback of `$scoopdir`
(#5544)
* fix(core): Use relative path as fallback of `$scoopdir`(Scoop root directory)
* typo
* changelog
* re
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
lib/core.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0624105c0a..f3be8bf3b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
+- **core:** Use relative path as fallback of `$scoopdir` ([#5544](https://github.com/ScoopInstaller/Scoop/issues/5544))
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
- **scoop-virustotal**: Fix `scoop-virustotal` when `--all' has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
diff --git a/lib/core.ps1 b/lib/core.ps1
index a1d3427182..389a028df4 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -1443,7 +1443,7 @@ if ($scoopConfig -and $scoopConfig.PSObject.Properties.Name -contains 'lastUpdat
# END NOTE
# Scoop root directory
-$scoopdir = $env:SCOOP, (get_config ROOT_PATH), "$([System.Environment]::GetFolderPath('UserProfile'))\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
+$scoopdir = $env:SCOOP, (get_config ROOT_PATH), (Resolve-Path "$PSScriptRoot\..\..\..\.."), "$([System.Environment]::GetFolderPath('UserProfile'))\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
# 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
From becc7a7b76f28cc384ec526db214331aa1aee5dc Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Tue, 3 Oct 2023 10:59:44 +0000
Subject: [PATCH 35/75] fix(core): Avoid error messages when deleting
non-existent environment variable (#5547)
* fix(core): Check if the envrionment variable exists before delete
* CHANGELOG
* Use `try, catch`, value of env variable may is null/empty
* UPDATE CHANGELOG
* Brackets
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
lib/core.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3be8bf3b7..2557311c4a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
+- **core:** Avoid error messages when deleting non-existent environment variable ([#5547](https://github.com/ScoopInstaller/Scoop/issues/5547))
- **core:** Use relative path as fallback of `$scoopdir` ([#5544](https://github.com/ScoopInstaller/Scoop/issues/5544))
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
diff --git a/lib/core.ps1 b/lib/core.ps1
index 389a028df4..441eeef716 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -751,7 +751,7 @@ function env($name, $global, $val = '__get') {
$RegistryValueOption = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
$EnvRegisterKey.GetValue($name, $null, $RegistryValueOption)
} elseif ($val -eq $null) {
- $EnvRegisterKey.DeleteValue($name)
+ try { $EnvRegisterKey.DeleteValue($name) } catch { }
Publish-Env
} else {
$RegistryValueKind = if ($val.Contains('%')) {
From 00c92b04d6279f7e64b174533195df13050aad85 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Tue, 3 Oct 2023 13:28:02 +0000
Subject: [PATCH 36/75] fix(install): Avoid error when unlinking non-existent
junction/hardlink (#5552)
* fix(install): Avoid error when unlinking non-existent junction / hardlink
* CHANGELOG
* Update CHANGELOG.md
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
lib/install.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2557311c4a..5470e126a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@
- **core:** Prevents leaking HTTP(S)_PROXY env vars to current sessions after Invoke-Git in parallel execution ([#5436](https://github.com/ScoopInstaller/Scoop/pull/5436))
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395), [#5452](https://github.com/ScoopInstaller/Scoop/pull/5452), [#5631](https://github.com/ScoopInstaller/Scoop/pull/5631))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
+- **install:** Avoid error when unlinking non-existent junction/hardlink ([#5552](https://github.com/ScoopInstaller/Scoop/issues/5552))
- **scoop-info:** Fix errors in file size collection when `--verbose` ([#5352](https://github.com/ScoopInstaller/Scoop/pull/5352))
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
- **core:** Avoid error messages when deleting non-existent environment variable ([#5547](https://github.com/ScoopInstaller/Scoop/issues/5547))
diff --git a/lib/install.ps1 b/lib/install.ps1
index 22b76423ca..519c26403d 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -1185,7 +1185,7 @@ function unlink_persist_data($manifest, $dir) {
if ($persist) {
@($persist) | ForEach-Object {
$source, $null = persist_def $_
- $source = Get-Item "$dir\$source"
+ $source = Get-Item "$dir\$source" -ErrorAction SilentlyContinue
if ($source.LinkType) {
$source_path = $source.FullName
# directory (junction)
From 6d79d62cc83f649f3655b89202e25244ceae8978 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Tue, 3 Oct 2023 13:29:10 +0000
Subject: [PATCH 37/75] fix(core): Handle scoop aliases and broken
(edited,copied) shim (#5551)
* fix(core): Avoid error messages when shim broked, Allow get path for scoop aliases
* update `scoop-which`
* Add CHANGELOG entry
* Update CHANGELOG.md
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
lib/core.ps1 | 7 +++++--
libexec/scoop-which.ps1 | 4 ++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5470e126a0..2c7821e332 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
- **core:** Fix `is_in_dir` under Unix ([#5391](https://github.com/ScoopInstaller/Scoop/issues/5391))
- **core:** Rewrite config file when needed ([#5439](https://github.com/ScoopInstaller/Scoop/issues/5439))
- **core:** Prevents leaking HTTP(S)_PROXY env vars to current sessions after Invoke-Git in parallel execution ([#5436](https://github.com/ScoopInstaller/Scoop/pull/5436))
+- **core:** Handle scoop aliases and broken(edited,copied) shim ([#5551](https://github.com/ScoopInstaller/Scoop/issues/5551))
- **env:** Avoid automatic expansion of `%%` in env ([#5395](https://github.com/ScoopInstaller/Scoop/issues/5395), [#5452](https://github.com/ScoopInstaller/Scoop/pull/5452), [#5631](https://github.com/ScoopInstaller/Scoop/pull/5631))
- **install:** Fix download from private GitHub repositories ([#5361](https://github.com/ScoopInstaller/Scoop/issues/5361))
- **install:** Avoid error when unlinking non-existent junction/hardlink ([#5552](https://github.com/ScoopInstaller/Scoop/issues/5552))
diff --git a/lib/core.ps1 b/lib/core.ps1
index 441eeef716..e3c8881992 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -469,7 +469,10 @@ function Get-CommandPath {
} catch {
return $null
}
- $commandPath = if ($comm.Path -like "$userShims*" -or $comm.Path -like "$globalShims*") {
+ $commandPath = if ($comm.Path -like "$userShims\scoop-*.ps1") {
+ # Scoop aliases
+ $comm.Source
+ } elseif ($comm.Path -like "$userShims*" -or $comm.Path -like "$globalShims*") {
Get-ShimTarget ($comm.Path -replace '\.exe$', '.shim')
} elseif ($comm.CommandType -eq 'Application') {
$comm.Source
@@ -847,7 +850,7 @@ function Get-ShimTarget($ShimPath) {
if (!$shimTarget) {
$shimTarget = ((Select-String -Path $ShimPath -Pattern '[''"]([^@&]*?)[''"]' -AllMatches).Matches.Groups | Select-Object -Last 1).Value
}
- $shimTarget | Convert-Path
+ $shimTarget | Convert-Path -ErrorAction SilentlyContinue
}
}
diff --git a/libexec/scoop-which.ps1 b/libexec/scoop-which.ps1
index d221a5db84..677b034376 100644
--- a/libexec/scoop-which.ps1
+++ b/libexec/scoop-which.ps1
@@ -4,7 +4,7 @@
param($command)
if (!$command) {
- 'ERROR: missing'
+ error ' missing'
my_usage
exit 1
}
@@ -12,7 +12,7 @@ if (!$command) {
$path = Get-CommandPath $command
if ($null -eq $path) {
- Write-Host "'$command' not found / not a scoop shim."
+ warn "'$command' not found, not a scoop shim, or a broken shim."
exit 2
} else {
friendly_path $path
From acc271d115c85d8584954be6a71492b121053a8a Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Tue, 3 Oct 2023 13:57:01 +0000
Subject: [PATCH 38/75] fix(scoop-(un)hold): Correct output the messages when
manifest not found, (already|not) held (#5554)
* fix(scoop-(un)hold): Abort when manifest not found
* abort when already held or not held
* use continue
* CHANGELOG
* Update CHANGELOG.md
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
libexec/scoop-hold.ps1 | 10 +++++++++-
libexec/scoop-unhold.ps1 | 8 ++++++++
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c7821e332..b020ab2fda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,7 @@
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
- **scoop-virustotal**: Fix `scoop-virustotal` when `--all' has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
+- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
### Performance Improvements
diff --git a/libexec/scoop-hold.ps1 b/libexec/scoop-hold.ps1
index 2d52310c79..43f11b3259 100644
--- a/libexec/scoop-hold.ps1
+++ b/libexec/scoop-hold.ps1
@@ -47,15 +47,23 @@ $apps | ForEach-Object {
return
}
- if (get_config NO_JUNCTION){
+ if (get_config NO_JUNCTION) {
$version = Select-CurrentVersion -App $app -Global:$global
} else {
$version = 'current'
}
$dir = versiondir $app $version $global
$json = install_info $app $version $global
+ if (!$json) {
+ error "Failed to hold '$app'."
+ continue
+ }
$install = @{}
$json | Get-Member -MemberType Properties | ForEach-Object { $install.Add($_.Name, $json.($_.Name)) }
+ if ($install.hold) {
+ info "'$app' is already held."
+ continue
+ }
$install.hold = $true
save_install_info $install $dir
success "$app is now held and can not be updated anymore."
diff --git a/libexec/scoop-unhold.ps1 b/libexec/scoop-unhold.ps1
index e678247972..4e2413a340 100644
--- a/libexec/scoop-unhold.ps1
+++ b/libexec/scoop-unhold.ps1
@@ -53,8 +53,16 @@ $apps | ForEach-Object {
}
$dir = versiondir $app $version $global
$json = install_info $app $version $global
+ if (!$json) {
+ error "Failed to unhold '$app'"
+ continue
+ }
$install = @{}
$json | Get-Member -MemberType Properties | ForEach-Object { $install.Add($_.Name, $json.($_.Name)) }
+ if (!$install.hold) {
+ info "'$app' is not held."
+ continue
+ }
$install.hold = $null
save_install_info $install $dir
success "$app is no longer held and can be updated again."
From b3c05e71fac58f20f90ea4ae2a0f86fa0f6444ed Mon Sep 17 00:00:00 2001
From: Richard Kuhnt
Date: Tue, 3 Oct 2023 16:05:45 +0200
Subject: [PATCH 39/75] perf(scoop-search): Improve performance for local
search (#5644)
* perf(search): improve local search performance
* Update libexec/scoop-search.ps1
Co-authored-by: Hsiao-nan Cheung
* Update libexec/scoop-search.ps1
Co-authored-by: Hsiao-nan Cheung
* Update libexec/scoop-search.ps1
Co-authored-by: Hsiao-nan Cheung
* Update libexec/scoop-search.ps1
Co-authored-by: Hsiao-nan Cheung
* Update libexec/scoop-search.ps1
Co-authored-by: Hsiao-nan Cheung
* Update libexec/scoop-search.ps1
Co-authored-by: Hsiao-nan Cheung
* Added [JsonDocument]::Parse for testing
* Fix array length check
* Used wrong function
* Add fallback function for PowerShell 5
* Check for System.Text.Json in Assemblies instead
* Show help output
* Revert "Show help output"
This reverts commit d3d6b01d0846d7c82fec0cbae5b898bdc1426ef9.
* Update CHANGELOG.md
---------
Co-authored-by: Hsiao-nan Cheung
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 3 +-
libexec/scoop-search.ps1 | 118 +++++++++++++++++++++++++++++----------
2 files changed, 90 insertions(+), 31 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b020ab2fda..355360824a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,13 +29,14 @@
- **core:** Use relative path as fallback of `$scoopdir` ([#5544](https://github.com/ScoopInstaller/Scoop/issues/5544))
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
-- **scoop-virustotal**: Fix `scoop-virustotal` when `--all' has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
+- **scoop-virustotal:** Fix `scoop-virustotal` when `--all` has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
### Performance Improvements
- **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))
### Code Refactoring
diff --git a/libexec/scoop-search.ps1 b/libexec/scoop-search.ps1
index adef8b1835..a9013afd02 100644
--- a/libexec/scoop-search.ps1
+++ b/libexec/scoop-search.ps1
@@ -9,7 +9,7 @@ param($query)
. "$PSScriptRoot\..\lib\manifest.ps1" # 'manifest'
. "$PSScriptRoot\..\lib\versions.ps1" # 'Get-LatestVersion'
-$list = @()
+$list = [System.Collections.Generic.List[PSCustomObject]]::new()
try {
$query = New-Object Regex $query, 'IgnoreCase'
@@ -32,24 +32,90 @@ function bin_match($manifest, $query) {
if ((strip_ext $fname) -match $query) { $fname }
elseif ($alias -match $query) { $alias }
}
+
+ if ($bins) { return $bins }
+ else { return $false }
+}
+
+function bin_match_json($json, $query) {
+ [System.Text.Json.JsonElement]$bin = [System.Text.Json.JsonElement]::new()
+ if (!$json.RootElement.TryGetProperty("bin", [ref] $bin)) { return $false }
+ $bins = @()
+ if($bin.ValueKind -eq [System.Text.Json.JsonValueKind]::String -and [System.IO.Path]::GetFileNameWithoutExtension($bin) -match $query) {
+ $bins += [System.IO.Path]::GetFileName($bin)
+ } elseif ($bin.ValueKind -eq [System.Text.Json.JsonValueKind]::Array) {
+ foreach($subbin in $bin.EnumerateArray()) {
+ if($subbin.ValueKind -eq [System.Text.Json.JsonValueKind]::String -and [System.IO.Path]::GetFileNameWithoutExtension($subbin) -match $query) {
+ $bins += [System.IO.Path]::GetFileName($subbin)
+ } elseif ($subbin.ValueKind -eq [System.Text.Json.JsonValueKind]::Array) {
+ if([System.IO.Path]::GetFileNameWithoutExtension($subbin[0]) -match $query) {
+ $bins += [System.IO.Path]::GetFileName($subbin[0])
+ } elseif ($subbin.GetArrayLength() -ge 2 -and $subbin[1] -match $query) {
+ $bins += $subbin[1]
+ }
+ }
+ }
+ }
+
if ($bins) { return $bins }
else { return $false }
}
function search_bucket($bucket, $query) {
- $apps = apps_in_bucket (Find-BucketDirectory $bucket) | ForEach-Object { @{ name = $_ } }
+ $apps = Get-ChildItem (Find-BucketDirectory $bucket) -Filter '*.json' -Recurse
+
+ $apps | ForEach-Object {
+ $json = [System.Text.Json.JsonDocument]::Parse([System.IO.File]::ReadAllText($_.FullName))
+ $name = $_.BaseName
+
+ if ($name -match $query) {
+ $list.Add([PSCustomObject]@{
+ Name = $name
+ Version = $json.RootElement.GetProperty("version")
+ Source = $bucket
+ Binaries = ""
+ })
+ } else {
+ $bin = bin_match_json $json $query
+ if ($bin) {
+ $list.Add([PSCustomObject]@{
+ Name = $name
+ Version = $json.RootElement.GetProperty("version")
+ Source = $bucket
+ Binaries = $bin -join ' | '
+ })
+ }
+ }
+ }
+}
- if ($query) {
- $apps = $apps | Where-Object {
- if ($_.name -match $query) { return $true }
- $bin = bin_match (manifest $_.name $bucket) $query
+# fallback function for PowerShell 5
+function search_bucket_legacy($bucket, $query) {
+ $apps = Get-ChildItem (Find-BucketDirectory $bucket) -Filter '*.json' -Recurse
+
+ $apps | ForEach-Object {
+ $manifest = [System.IO.File]::ReadAllText($_.FullName) | ConvertFrom-Json -ErrorAction Continue
+ $name = $_.BaseName
+
+ if ($name -match $query) {
+ $list.Add([PSCustomObject]@{
+ Name = $name
+ Version = $manifest.Version
+ Source = $bucket
+ Binaries = ""
+ })
+ } else {
+ $bin = bin_match $manifest $query
if ($bin) {
- $_.bin = $bin
- return $true
+ $list.Add([PSCustomObject]@{
+ Name = $name
+ Version = $manifest.Version
+ Source = $bucket
+ Binaries = $bin -join ' | '
+ })
}
}
}
- $apps | ForEach-Object { $_.version = (Get-LatestVersion -AppName $_.name -Bucket $bucket); $_ }
}
function download_json($url) {
@@ -96,43 +162,35 @@ function search_remotes($query) {
(add them using 'scoop bucket add ')"
}
+ $remote_list = @()
$results | ForEach-Object {
- $name = $_.bucket
+ $bucket = $_.bucket
$_.results | ForEach-Object {
$item = [ordered]@{}
$item.Name = $_
- $item.Source = $name
- $list += [PSCustomObject]$item
+ $item.Source = $bucket
+ $remote_list += [PSCustomObject]$item
}
}
-
- $list
+ $remote_list
}
-Get-LocalBucket | ForEach-Object {
- $res = search_bucket $_ $query
- $local_results = $local_results -or $res
- if ($res) {
- $name = "$_"
+$jsonTextAvailable = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-object { [System.IO.Path]::GetFileNameWithoutExtension($_.Location) -eq "System.Text.Json" }
- $res | ForEach-Object {
- $item = [ordered]@{}
- $item.Name = $_.name
- $item.Version = $_.version
- $item.Source = $name
- $item.Binaries = ""
- if ($_.bin) { $item.Binaries = $_.bin -join ' | ' }
- $list += [PSCustomObject]$item
- }
+Get-LocalBucket | ForEach-Object {
+ if ($jsonTextAvailable) {
+ search_bucket $_ $query
+ } else {
+ search_bucket_legacy $_ $query
}
}
-if ($list.Length -gt 0) {
+if ($list.Count -gt 0) {
Write-Host "Results from local buckets..."
$list
}
-if (!$local_results -and !(github_ratelimit_reached)) {
+if ($list.Count -eq 0 -and !(github_ratelimit_reached)) {
$remote_results = search_remotes $query
if (!$remote_results) {
warn "No matches found."
From 863af42d4e3a77afe4b13b2b92e0352269595fb6 Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Thu, 5 Oct 2023 06:51:29 +0000
Subject: [PATCH 40/75] fix(core): Fix detection of Git (#5545)
* fix(core): Fix `Test-GitAvailable`
* fix(core): Fallback git(32bit) to `Get-HelperPath`
* check value of `$internalgit` also
* changlog
* path already tested when invoke `Get-AppFilePAth`
---
CHANGELOG.md | 1 +
lib/core.ps1 | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 355360824a..de17e381c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,7 @@
- **shim:** Use bash executable directly ([#5433](https://github.com/ScoopInstaller/Scoop/issues/5433))
- **core:** Avoid error messages when deleting non-existent environment variable ([#5547](https://github.com/ScoopInstaller/Scoop/issues/5547))
- **core:** Use relative path as fallback of `$scoopdir` ([#5544](https://github.com/ScoopInstaller/Scoop/issues/5544))
+- **core:** Fix detection of Git ([#5545](https://github.com/ScoopInstaller/Scoop/issues/5545))
- **scoop-checkup:** Skip defender check in Windows Sandbox ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **buckets:** Avoid error messages for unexpected dir ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5549))
- **scoop-virustotal:** Fix `scoop-virustotal` when `--all` has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
diff --git a/lib/core.ps1 b/lib/core.ps1
index e3c8881992..33e59ba562 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -402,7 +402,7 @@ Function Test-CommandAvailable {
}
Function Test-GitAvailable {
- Return [Boolean](Test-Path (Get-HelperPath -Helper Git) -ErrorAction Ignore)
+ return [Boolean](Get-HelperPath -Helper Git)
}
function Get-HelperPath {
@@ -420,8 +420,8 @@ function Get-HelperPath {
process {
switch ($Helper) {
'Git' {
- $internalgit = "$(versiondir 'git' 'current')\mingw64\bin\git.exe"
- if (Test-Path $internalgit) {
+ $internalgit = (Get-AppFilePath 'git' 'mingw64\bin\git.exe'), (Get-AppFilePath 'git' 'mingw32\bin\git.exe') | Where-Object { $_ -ne $null }
+ if ($internalgit) {
$HelperPath = $internalgit
} else {
$HelperPath = (Get-Command git -ErrorAction Ignore).Source
From ab34b7fb61c034c05fed1b11ac4ae67afc2205ae Mon Sep 17 00:00:00 2001
From: Gerardo Grignoli
Date: Thu, 5 Oct 2023 08:10:03 -0300
Subject: [PATCH 41/75] feat(core): Allow global install of PowerShell modules
(#5611)
* Allow global install of PowerShell modules to $env:ProgramFiles\WindowsPowerShell\Modules
* tabs vs spaces
* Updated CHANGELOG.md
* Changed global install of PowerShell modules to $globaldir\Modules
---
CHANGELOG.md | 1 +
lib/core.ps1 | 1 +
lib/psmodules.ps1 | 15 ++++++---------
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de17e381c8..d60402c9eb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
- **config:** Support portable config file ([#5369](https://github.com/ScoopInstaller/Scoop/issues/5369))
- **bucket:** Make official buckets higher priority ([#5398](https://github.com/ScoopInstaller/Scoop/issues/5398))
- **core:** Add `-Quiet` switch for `Invoke-ExternalCommand` ([#5346](https://github.com/ScoopInstaller/Scoop/issues/5346))
+- **core:** Allow global install of PowerShell modules ([#5611](https://github.com/ScoopInstaller/Scoop/issues/5611))
### Bug Fixes
diff --git a/lib/core.ps1 b/lib/core.ps1
index 33e59ba562..06c4f1591c 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -317,6 +317,7 @@ function filesize($length) {
function basedir($global) { if($global) { return $globaldir } $scoopdir }
function appsdir($global) { "$(basedir $global)\apps" }
function shimdir($global) { "$(basedir $global)\shims" }
+function modulesdir($global) { "$(basedir $global)\modules" }
function appdir($app, $global) { "$(appsdir $global)\$app" }
function versiondir($app, $version, $global) { "$(appdir $app $global)\$version" }
diff --git a/lib/psmodules.ps1 b/lib/psmodules.ps1
index 2fbb6e6525..c65fd65c7b 100644
--- a/lib/psmodules.ps1
+++ b/lib/psmodules.ps1
@@ -1,22 +1,17 @@
-$modulesdir = "$scoopdir\modules"
-
function install_psmodule($manifest, $dir, $global) {
$psmodule = $manifest.psmodule
if (!$psmodule) { return }
- if ($global) {
- abort 'Installing PowerShell modules globally is not implemented!'
- }
+ $targetdir = ensure (modulesdir $global)
- $modulesdir = ensure $modulesdir
- ensure_in_psmodulepath $modulesdir $global
+ ensure_in_psmodulepath $targetdir $global
$module_name = $psmodule.name
if (!$module_name) {
abort "Invalid manifest: The 'name' property is missing from 'psmodule'."
}
- $linkfrom = "$modulesdir\$module_name"
+ $linkfrom = "$targetdir\$module_name"
Write-Host "Installing PowerShell module '$module_name'"
Write-Host "Linking $(friendly_path $linkfrom) => $(friendly_path $dir)"
@@ -36,7 +31,9 @@ function uninstall_psmodule($manifest, $dir, $global) {
$module_name = $psmodule.name
Write-Host "Uninstalling PowerShell module '$module_name'."
- $linkfrom = "$modulesdir\$module_name"
+ $targetdir = modulesdir $global
+
+ $linkfrom = "$targetdir\$module_name"
if (Test-Path $linkfrom) {
Write-Host "Removing $(friendly_path $linkfrom)"
$linkfrom = Convert-Path $linkfrom
From 15f9bbec9704345801a6c9e2e3194bd368546288 Mon Sep 17 00:00:00 2001
From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
Date: Fri, 6 Oct 2023 14:51:45 +0530
Subject: [PATCH 42/75] fix(update): Change error message to a better
instruction (#5677)
* fix(update): Change error message to a better instruction
* Update CHANGELOG.md
---
CHANGELOG.md | 1 +
libexec/scoop-update.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d60402c9eb..bc390b4cb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,7 @@
- **scoop-virustotal:** Fix `scoop-virustotal` when `--all` has been passed without app ([#5593](https://github.com/ScoopInstaller/Scoop/pull/5593))
- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
+- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
### Performance Improvements
diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1
index 3bcdcb7500..50f82090a5 100644
--- a/libexec/scoop-update.ps1
+++ b/libexec/scoop-update.ps1
@@ -89,7 +89,7 @@ function Sync-Scoop {
Rename-Item $newdir 'current' -ErrorAction Stop
} catch {
Write-Warning $_
- abort "Scoop update failed. Folder in use. Paste $newdir into $currentdir."
+ abort "Scoop update failed. Folder in use. Please rename folders $currentdir to ``old`` and $newdir to ``current``."
}
}
} else {
From 3a3f41c556c044150d86f259c1e3583687b41929 Mon Sep 17 00:00:00 2001
From: Dustin <131928587+dooptydoo90x@users.noreply.github.com>
Date: Sun, 8 Oct 2023 08:34:36 -0500
Subject: [PATCH 43/75] fix(shim): Fix shim adding bug related to
Resolve-Path(#5493)
* fixed shim add bug related to #5492
* Updated CHANGLOG.md per contributor guidelines
---
CHANGELOG.md | 1 +
lib/core.ps1 | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc390b4cb9..80932a9ff9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -79,6 +79,7 @@
- **shim:** Exit if shim creating failed 'cause no git ([#5225](https://github.com/ScoopInstaller/Scoop/issues/5225))
- **scoop-import:** Add correct architecture argument ([#5210](https://github.com/ScoopInstaller/Scoop/issues/5210))
- **scoop-config:** Output `[DateTime]` as `[String]` ([#5232](https://github.com/ScoopInstaller/Scoop/issues/5232))
+- **shim:** fixed shim add bug related to Resolve-Path ([#5492](https://github.com/ScoopInstaller/Scoop/issues/5492))
### Code Refactoring
diff --git a/lib/core.ps1 b/lib/core.ps1
index 06c4f1591c..125e679205 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -883,10 +883,10 @@ function shim($path, $global, $name, $arg) {
$shim = "$abs_shimdir\$($name.tolower())"
# convert to relative path
+ $resolved_path = Convert-Path $path
Push-Location $abs_shimdir
- $relative_path = Resolve-Path -Relative $path
+ $relative_path = Resolve-Path -Relative $resolved_path
Pop-Location
- $resolved_path = Convert-Path $path
if ($path -match '\.(exe|com)$') {
# for programs with no awareness of any shell
From 2847e0a37c981ffc709af0edab4ceceb44a7656b Mon Sep 17 00:00:00 2001
From: "L. Yeung"
Date: Tue, 10 Oct 2023 19:17:46 +0800
Subject: [PATCH 44/75] fix(scoop-shim): Avoid unexpected output of `list`
subcommand (#5681)
* fix(shim): Avoid unexpected output of `list` subcommand
* Update libexec/scoop-shim.ps1
Co-authored-by: Hsiao-nan Cheung
---------
Co-authored-by: Hsiao-nan Cheung
---
CHANGELOG.md | 1 +
libexec/scoop-shim.ps1 | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 80932a9ff9..9e96f74863 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@
- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
+- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
### Performance Improvements
diff --git a/libexec/scoop-shim.ps1 b/libexec/scoop-shim.ps1
index 41263afe6a..6cbd53dbd3 100644
--- a/libexec/scoop-shim.ps1
+++ b/libexec/scoop-shim.ps1
@@ -12,7 +12,7 @@
#
# To list all shims or matching shims, use the 'list' subcommand:
#
-# scoop shim list [/...]
+# scoop shim list [...]
#
# To show a shim's information, use the 'info' subcommand:
#
@@ -144,7 +144,7 @@ switch ($SubCommand) {
$other | ForEach-Object {
try {
$pattern = $_
- [Regex]::New($pattern)
+ [void][Regex]::New($pattern)
} catch {
Write-Host "ERROR: Invalid pattern: " -ForegroundColor Red -NoNewline
Write-Host $pattern -ForegroundColor Magenta
From 14b38b4092ce9bc66b31fd3de30b5c109be135ef Mon Sep 17 00:00:00 2001
From: "L. Yeung"
Date: Tue, 10 Oct 2023 19:20:53 +0800
Subject: [PATCH 45/75] fix(scoop-shim): Check literal path in `Get-ShimPath`
(#5680)
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 1 +
libexec/scoop-shim.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e96f74863..5ab4fe6484 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@
- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
+- **shim:** Check literal path in `Get-ShimPath` ([#5680](https://github.com/ScoopInstaller/Scoop/issues/5680))
- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
### Performance Improvements
diff --git a/libexec/scoop-shim.ps1 b/libexec/scoop-shim.ps1
index 6cbd53dbd3..cf775b1d6b 100644
--- a/libexec/scoop-shim.ps1
+++ b/libexec/scoop-shim.ps1
@@ -82,7 +82,7 @@ function Get-ShimInfo($ShimPath) {
function Get-ShimPath($ShimName, $Global) {
'.shim', '.ps1' | ForEach-Object {
$shimPath = Join-Path (shimdir $Global) "$ShimName$_"
- if (Test-Path $shimPath) {
+ if (Test-Path -LiteralPath $shimPath) {
return $shimPath
}
}
From 6cdcc75ad84add9deedad81f1c9c16dc43f868c0 Mon Sep 17 00:00:00 2001
From: Sp1d3R <98212676+spider2048@users.noreply.github.com>
Date: Sat, 14 Oct 2023 16:04:46 +0530
Subject: [PATCH 46/75] fix(shim): Fix a minor issue with `Get-Subsystem`
(#5684)
* Fix PE read error and refractor
* refactor Change-Subsystem -> Set-Subsystem and additional `catch` block
* refactor Change-Subsystem -> Set-Subsystem and additional `catch` block
* add a return value to `Set-PESubsystem`
* fix trailing whitespace
---
lib/core.ps1 | 26 ++++++++++----------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/lib/core.ps1 b/lib/core.ps1
index 125e679205..b971c484db 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -1,13 +1,8 @@
-# Returns the subsystem of the EXE
-function Get-Subsystem($filePath) {
+function Get-PESubsystem($filePath) {
try {
$fileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
$binaryReader = [System.IO.BinaryReader]::new($fileStream)
- } catch {
- return -1 # leave the subsystem part silently
- }
- try {
$fileStream.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null
$peOffset = $binaryReader.ReadInt32()
@@ -18,23 +13,20 @@ function Get-Subsystem($filePath) {
$fileStream.Seek($fileHeaderOffset + 0x5C, [System.IO.SeekOrigin]::Begin) | Out-Null
return $binaryReader.ReadInt16()
+ } catch {
+ return -1
} finally {
$binaryReader.Close()
$fileStream.Close()
}
}
-function Change-Subsystem($filePath, $targetSubsystem) {
+function Set-PESubsystem($filePath, $targetSubsystem) {
try {
$fileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
$binaryReader = [System.IO.BinaryReader]::new($fileStream)
$binaryWriter = [System.IO.BinaryWriter]::new($fileStream)
- } catch {
- Write-Output "Error opening File:'$filePath'"
- return
- }
- try {
$fileStream.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null
$peOffset = $binaryReader.ReadInt32()
@@ -45,10 +37,13 @@ function Change-Subsystem($filePath, $targetSubsystem) {
$fileStream.Seek($fileHeaderOffset + 0x5C, [System.IO.SeekOrigin]::Begin) | Out-Null
$binaryWriter.Write([System.Int16] $targetSubsystem)
+ } catch {
+ return $false
} finally {
$binaryReader.Close()
$fileStream.Close()
}
+ return $true
}
function Optimize-SecurityProtocol {
@@ -897,11 +892,10 @@ function shim($path, $global, $name, $arg) {
Write-Output "args = $arg" | Out-UTF8File "$shim.shim" -Append
}
- $target_subsystem = Get-Subsystem $resolved_path
-
- if (($target_subsystem -ne 3) -and ($target_subsystem -ge 0)) { # Subsystem -eq 3 means `Console`, -ge 0 to ignore
+ $target_subsystem = Get-PESubsystem $resolved_path
+ if ($target_subsystem -eq 2) { # we only want to make shims GUI
Write-Output "Making $shim.exe a GUI binary."
- Change-Subsystem "$shim.exe" $target_subsystem
+ Set-PESubsystem "$shim.exe" $target_subsystem | Out-Null
}
} elseif ($path -match '\.(bat|cmd)$') {
# shim .bat, .cmd so they can be used by programs with no awareness of PSH
From 7b35e19d4cc32eb8cd562559c5a72f488d57a946 Mon Sep 17 00:00:00 2001
From: Hagai Gold
Date: Thu, 19 Oct 2023 10:49:31 +0300
Subject: [PATCH 47/75] fix(perf): Do not call `scoop` externally from inside
the code (#5695)
* fix: do not call `scoop` externally from inside the code
* update CHANGELOG.md
* update CHANGELOG.md
---
CHANGELOG.md | 1 +
libexec/scoop-create.ps1 | 2 +-
libexec/scoop-download.ps1 | 2 +-
libexec/scoop-install.ps1 | 2 +-
libexec/scoop-virustotal.ps1 | 2 +-
5 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ab4fe6484..a972451137 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,7 @@
- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
- **shim:** Check literal path in `Get-ShimPath` ([#5680](https://github.com/ScoopInstaller/Scoop/issues/5680))
- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
+- **scoop:** Do not call `scoop` externally from inside the code ([#5695](https://github.com/ScoopInstaller/Scoop/issues/5695))
### Performance Improvements
diff --git a/libexec/scoop-create.ps1 b/libexec/scoop-create.ps1
index 3a33d09ea0..6c40e96c5e 100644
--- a/libexec/scoop-create.ps1
+++ b/libexec/scoop-create.ps1
@@ -59,7 +59,7 @@ function choose_item($list, $query) {
}
if (!$url) {
- scoop help create
+ & "$PSScriptRoot\scoop-help.ps1" create
} else {
create_manifest $url
}
diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1
index d339e7907f..3ab2fa2867 100644
--- a/libexec/scoop-download.ps1
+++ b/libexec/scoop-download.ps1
@@ -43,7 +43,7 @@ if (is_scoop_outdated) {
if ($opt.u -or $opt.'no-update-scoop') {
warn "Scoop is out of date."
} else {
- scoop update
+ & "$PSScriptRoot\scoop-update.ps1"
}
}
diff --git a/libexec/scoop-install.ps1 b/libexec/scoop-install.ps1
index 994bb5b4cf..61cad28883 100644
--- a/libexec/scoop-install.ps1
+++ b/libexec/scoop-install.ps1
@@ -56,7 +56,7 @@ if (is_scoop_outdated) {
if ($opt.u -or $opt.'no-update-scoop') {
warn "Scoop is out of date."
} else {
- scoop update
+ & "$PSScriptRoot\scoop-update.ps1"
}
}
diff --git a/libexec/scoop-virustotal.ps1 b/libexec/scoop-virustotal.ps1
index 30c5e8494b..93b60f232d 100644
--- a/libexec/scoop-virustotal.ps1
+++ b/libexec/scoop-virustotal.ps1
@@ -43,7 +43,7 @@ if (is_scoop_outdated) {
if ($opt.u -or $opt.'no-update-scoop') {
warn 'Scoop is out of date.'
} else {
- scoop update
+ & "$PSScriptRoot\scoop-update.ps1"
}
}
From 7e81e49152fb9fe74cc789d447831bc0fd0dcd22 Mon Sep 17 00:00:00 2001
From: Bill ZHANG <36790218+Lutra-Fs@users.noreply.github.com>
Date: Thu, 26 Oct 2023 18:28:10 +1100
Subject: [PATCH 48/75] fix(scoop-reset): Don't abort when multiple apps are
passed and an app is running (#5687)
* fix(scoop-reset): change #2952 fix to be the same with scoop-install
* update changelog
* Update CHANGELOG.md
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---------
Co-authored-by: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
---
CHANGELOG.md | 3 ++-
libexec/scoop-reset.ps1 | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a972451137..371904301b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,7 +37,8 @@
- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
- **shim:** Check literal path in `Get-ShimPath` ([#5680](https://github.com/ScoopInstaller/Scoop/issues/5680))
- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
-- **scoop:** Do not call `scoop` externally from inside the code ([#5695](https://github.com/ScoopInstaller/Scoop/issues/5695))
+- **scoop-reset:** Don't abort when multiple apps are passed and an app is running ([#5687](https://github.com/ScoopInstaller/Scoop/issues/5687))
+- **core:** Do not call `scoop` externally from inside the code ([#5695](https://github.com/ScoopInstaller/Scoop/issues/5695))
### Performance Improvements
diff --git a/libexec/scoop-reset.ps1 b/libexec/scoop-reset.ps1
index e10ef9e4f9..c30eeb6e1b 100644
--- a/libexec/scoop-reset.ps1
+++ b/libexec/scoop-reset.ps1
@@ -69,7 +69,7 @@ $apps | ForEach-Object {
#region Workaround for #2952
if (test_running_process $app $global) {
- continue
+ return
}
#endregion Workaround for #2952
From fb3169629fa89b762e39503148cbc96223c68a6a Mon Sep 17 00:00:00 2001
From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
Date: Thu, 26 Oct 2023 14:13:25 +0530
Subject: [PATCH 49/75] fix(scoop-checkup): Don't throw 7zip error when
external 7zip is used (#5703)
* fix(scoop-checkup): Don't throw 7zip error when external 7zip is used
* Update CHANGELOG.md
---
CHANGELOG.md | 1 +
libexec/scoop-checkup.ps1 | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 371904301b..bf8ec0b3a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -39,6 +39,7 @@
- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
- **scoop-reset:** Don't abort when multiple apps are passed and an app is running ([#5687](https://github.com/ScoopInstaller/Scoop/issues/5687))
- **core:** Do not call `scoop` externally from inside the code ([#5695](https://github.com/ScoopInstaller/Scoop/issues/5695))
+- **scoop-checkup:** Don't throw 7zip error when external 7zip is used ([#5703](https://github.com/ScoopInstaller/Scoop/issues/5703))
### Performance Improvements
diff --git a/libexec/scoop-checkup.ps1 b/libexec/scoop-checkup.ps1
index 111bd3463b..02def4eaa5 100644
--- a/libexec/scoop-checkup.ps1
+++ b/libexec/scoop-checkup.ps1
@@ -19,7 +19,7 @@ $issues += !(check_main_bucket)
$issues += !(check_long_paths)
$issues += !(Get-WindowsDeveloperModeStatus)
-if (!(Test-HelperInstalled -Helper 7zip)) {
+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'."
$issues++
}
From 5328bef269d845f0940ef45a094a8fb487e43a00 Mon Sep 17 00:00:00 2001
From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com>
Date: Fri, 5 Jan 2024 23:46:28 +0530
Subject: [PATCH 50/75] fix(config): Warn users about misconfigured token
(#5777)
* Warn users about misconfigured token
* Update CHANGELOG.md
---
CHANGELOG.md | 1 +
lib/install.ps1 | 12 +++++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf8ec0b3a5..6012fc2dd2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,7 @@
- **scoop-reset:** Don't abort when multiple apps are passed and an app is running ([#5687](https://github.com/ScoopInstaller/Scoop/issues/5687))
- **core:** Do not call `scoop` externally from inside the code ([#5695](https://github.com/ScoopInstaller/Scoop/issues/5695))
- **scoop-checkup:** Don't throw 7zip error when external 7zip is used ([#5703](https://github.com/ScoopInstaller/Scoop/issues/5703))
+- **config:** Warn users about misconfigured GitHub token ([#5777](https://github.com/ScoopInstaller/Scoop/issues/5777))
### Performance Improvements
diff --git a/lib/install.ps1 b/lib/install.ps1
index 519c26403d..60f6d5a649 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -107,6 +107,9 @@ function Start-Download ($url, $to, $cookies) {
Invoke-Download $url $to $cookies $progress
} catch {
$e = $_.exception
+ if ($e.Response.StatusCode -eq 'Unauthorized') {
+ warn "Token might be misconfigured."
+ }
if($e.innerexception) { $e = $e.innerexception }
throw $e
}
@@ -246,7 +249,14 @@ function Invoke-CachedAria2Download ($app, $version, $manifest, $architecture, $
} else {
$download_finished = $false
# create aria2 input file content
- $urlstxt_content += "$(handle_special_urls $url)`n"
+ try {
+ $try_url = handle_special_urls $url
+ } catch {
+ if ($_.Exception.Response.StatusCode -eq 'Unauthorized') {
+ warn "Token might be misconfigured."
+ }
+ }
+ $urlstxt_content += "$try_url`n"
if (!$url.Contains('sourceforge.net')) {
$urlstxt_content += " referer=$(strip_filename $url)`n"
}
From 48f793532cd619e9fd289147de3eb3af13c70a6e Mon Sep 17 00:00:00 2001
From: HUMORCE
Date: Fri, 23 Feb 2024 17:41:44 +0800
Subject: [PATCH 51/75] fix(manifest): Correct source of manifest (#5575)
---
CHANGELOG.md | 1 +
lib/depends.ps1 | 4 ++--
lib/install.ps1 | 4 ++--
lib/manifest.ps1 | 21 ++++++++++-----------
libexec/scoop-cat.ps1 | 14 +++++++-------
libexec/scoop-download.ps1 | 2 +-
6 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6012fc2dd2..6c1e438891 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@
- **scoop-checkup:** Change the message level of helpers from ERROR to WARN ([#5549](https://github.com/ScoopInstaller/Scoop/issues/5614))
- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
+- **manifest:** Correct source of manifest ([#5575](https://github.com/ScoopInstaller/Scoop/issues/5575))
- **shim:** Check literal path in `Get-ShimPath` ([#5680](https://github.com/ScoopInstaller/Scoop/issues/5680))
- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
- **scoop-reset:** Don't abort when multiple apps are passed and an app is running ([#5687](https://github.com/ScoopInstaller/Scoop/issues/5687))
diff --git a/lib/depends.ps1 b/lib/depends.ps1
index 9c8d29042d..bd4ed19cf2 100644
--- a/lib/depends.ps1
+++ b/lib/depends.ps1
@@ -37,9 +37,9 @@ function Get-Dependency {
if (!$manifest) {
if (((Get-LocalBucket) -notcontains $bucket) -and $bucket) {
- warn "Bucket '$bucket' not installed. Add it with 'scoop bucket add $bucket' or 'scoop bucket add $bucket '."
+ warn "Bucket '$bucket' not added. Add it with $(if($bucket -in (known_buckets)) { "'scoop bucket add $bucket' or " })'scoop bucket add $bucket '."
}
- abort "Couldn't find manifest for '$AppName'$(if(!$bucket) { '.' } else { " from '$bucket' bucket." })"
+ abort "Couldn't find manifest for '$AppName'$(if($bucket) { " from '$bucket' bucket" } elseif($url) { " at '$url'" })."
}
$deps = @(Get-InstallationHelper $manifest $Architecture) + @($manifest.depends) | Select-Object -Unique
diff --git a/lib/install.ps1 b/lib/install.ps1
index 60f6d5a649..31b6de73f6 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -9,7 +9,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
$app, $manifest, $bucket, $url = Get-Manifest $app
if(!$manifest) {
- abort "Couldn't find manifest for '$app'$(if($url) { " at the URL $url" })."
+ abort "Couldn't find manifest for '$app'$(if($bucket) { " from '$bucket' bucket" } elseif($url) { " at '$url'" })."
}
$version = $manifest.version
@@ -43,7 +43,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
return
}
}
- Write-Output "Installing '$app' ($version) [$architecture]$(if ($bucket) { " from $bucket bucket" })"
+ Write-Output "Installing '$app' ($version) [$architecture]$(if ($bucket) { " from '$bucket' bucket" } else { " from '$url'" })"
$dir = ensure (versiondir $app $version $global)
$original_dir = $dir # keep reference to real (not linked) directory
diff --git a/lib/manifest.ps1 b/lib/manifest.ps1
index 8b8a685736..5e0d9fe2c2 100644
--- a/lib/manifest.ps1
+++ b/lib/manifest.ps1
@@ -7,7 +7,7 @@ function parse_json($path) {
try {
Get-Content $path -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop
} catch {
- warn "Error parsing JSON at $path."
+ warn "Error parsing JSON at '$path'."
}
}
@@ -27,7 +27,7 @@ function url_manifest($url) {
try {
$str | ConvertFrom-Json -ErrorAction Stop
} catch {
- warn "Error parsing JSON at $url."
+ warn "Error parsing JSON at '$url'."
}
}
@@ -44,24 +44,23 @@ function Get-Manifest($app) {
if ($bucket) {
$manifest = manifest $app $bucket
} else {
- foreach ($bucket in Get-LocalBucket) {
- $manifest = manifest $app $bucket
+ foreach ($tekcub in Get-LocalBucket) {
+ $manifest = manifest $app $tekcub
if ($manifest) {
+ $bucket = $tekcub
break
}
}
}
if (!$manifest) {
# couldn't find app in buckets: check if it's a local path
- $appPath = $app
- $bucket = $null
- if (!$appPath.EndsWith('.json')) {
- $appPath += '.json'
- }
- if (Test-Path $appPath) {
- $url = Convert-Path $appPath
+ if (Test-Path $app) {
+ $url = Convert-Path $app
$app = appname_from_url $url
$manifest = url_manifest $url
+ } else {
+ if (($app -match '\\/') -or $app.EndsWith('.json')) { $url = $app }
+ $app = appname_from_url $app
}
}
}
diff --git a/libexec/scoop-cat.ps1 b/libexec/scoop-cat.ps1
index 3e840c7149..5cf363162d 100644
--- a/libexec/scoop-cat.ps1
+++ b/libexec/scoop-cat.ps1
@@ -14,14 +14,14 @@ if (!$app) { error ' missing'; my_usage; exit 1 }
$null, $manifest, $bucket, $url = Get-Manifest $app
if ($manifest) {
- $style = get_config CAT_STYLE
- if ($style) {
- $manifest | ConvertToPrettyJson | bat --no-paging --style $style --language json
- } else {
- $manifest | ConvertToPrettyJson
- }
+ $style = get_config CAT_STYLE
+ if ($style) {
+ $manifest | ConvertToPrettyJson | bat --no-paging --style $style --language json
+ } else {
+ $manifest | ConvertToPrettyJson
+ }
} else {
- abort "Couldn't find manifest for '$app'$(if($url) { " at the URL $url" })."
+ abort "Couldn't find manifest for '$app'$(if($bucket) { " from '$bucket' bucket" } elseif($url) { " at '$url'" })."
}
exit $exitCode
diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1
index 3ab2fa2867..ef43f8f41d 100644
--- a/libexec/scoop-download.ps1
+++ b/libexec/scoop-download.ps1
@@ -70,7 +70,7 @@ foreach ($curr_app in $apps) {
}
if(!$manifest) {
- error "Couldn't find manifest for '$app'$(if($url) { " at the URL $url" })."
+ error "Couldn't find manifest for '$app'$(if($bucket) { " from '$bucket' bucket" } elseif($url) { " at '$url'" })."
continue
}
$version = $manifest.version
From 7e3dc73b83c92e0e99aa50b599f24c64c79574e2 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Wed, 6 Mar 2024 21:04:46 +0800
Subject: [PATCH 52/75] refactor(core): Cleanup some old codes, e.g., `msi`
section and config migration (#5715)
---
CHANGELOG.md | 1 +
lib/core.ps1 | 25 ---
lib/install.ps1 | 438 +++++++++++++++++----------------------
lib/manifest.ps1 | 1 -
libexec/scoop-config.ps1 | 18 --
schema.json | 8 -
6 files changed, 187 insertions(+), 304 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c1e438891..cb4d363a60 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -52,6 +52,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))
### Builds
diff --git a/lib/core.ps1 b/lib/core.ps1
index b971c484db..24b6c8b0c7 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -1415,31 +1415,6 @@ if ($pathExpected) {
}
$scoopConfig = load_cfg $configFile
-# NOTE Scoop config file migration. Remove this after 2023/6/30
-if ($scoopConfig -and $scoopConfig.PSObject.Properties.Name -contains 'lastUpdate') {
- $newConfigNames = @{
- 'lastUpdate' = 'last_update'
- 'SCOOP_REPO' = 'scoop_repo'
- 'SCOOP_BRANCH' = 'scoop_branch'
- '7ZIPEXTRACT_USE_EXTERNAL' = 'use_external_7zip'
- 'MSIEXTRACT_USE_LESSMSI' = 'use_lessmsi'
- 'NO_JUNCTIONS' = 'no_junction'
- 'manifest_review' = 'show_manifest'
- 'rootPath' = 'root_path'
- 'globalPath' = 'global_path'
- 'cachePath' = 'cache_path'
- }
- $newConfigNames.GetEnumerator() | ForEach-Object {
- if ($null -ne $scoopConfig.$($_.Key)) {
- $value = $scoopConfig.$($_.Key)
- $scoopConfig.PSObject.Properties.Remove($_.Key)
- $scoopConfig | Add-Member -MemberType NoteProperty -Name $_.Value -Value $value
- }
- }
- ConvertTo-Json $scoopConfig | Out-UTF8File -FilePath $configFile
-}
-# END NOTE
-
# 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
diff --git a/lib/install.ps1 b/lib/install.ps1
index 31b6de73f6..7dc772e7be 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -8,13 +8,13 @@ function nightly_version($quiet = $false) {
function install_app($app, $architecture, $global, $suggested, $use_cache = $true, $check_hash = $true) {
$app, $manifest, $bucket, $url = Get-Manifest $app
- if(!$manifest) {
- abort "Couldn't find manifest for '$app'$(if($bucket) { " from '$bucket' bucket" } elseif($url) { " at '$url'" })."
+ if (!$manifest) {
+ abort "Couldn't find manifest for '$app'$(if ($bucket) { " from '$bucket' bucket" } elseif ($url) { " at '$url'" })."
}
$version = $manifest.version
- if(!$version) { abort "Manifest doesn't specify a version." }
- if($version -match '[^\w\.\-\+_]') {
+ if (!$version) { abort "Manifest doesn't specify a version." }
+ if ($version -match '[^\w\.\-\+_]') {
abort "Manifest version has unsupported character '$($matches[0])'."
}
@@ -38,7 +38,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
} else {
$manifest | ConvertToPrettyJson
}
- $answer = Read-Host -Prompt "Continue installation? [Y/n]"
+ $answer = Read-Host -Prompt 'Continue installation? [Y/n]'
if (($answer -eq 'n') -or ($answer -eq 'N')) {
return
}
@@ -71,7 +71,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
save_installed_manifest $app $bucket $dir $url
save_install_info @{ 'architecture' = $architecture; 'url' = $url; 'bucket' = $bucket } $dir
- if($manifest.suggest) {
+ if ($manifest.suggest) {
$suggested[$app] = $manifest.suggest
}
@@ -83,11 +83,11 @@ 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)
- if(!(test-path $cached) -or !$use_cache) {
+ if (!(Test-Path $cached) -or !$use_cache) {
ensure $cachedir | Out-Null
Start-Download $url "$cached.download" $cookies
- Move-Item "$cached.download" $cached -force
- } else { write-host "Loading $(url_remote_filename $url) from cache"}
+ Move-Item "$cached.download" $cached -Force
+ } else { Write-Host "Loading $(url_remote_filename $url) from cache" }
if (!($null -eq $to)) {
if ($use_cache) {
@@ -100,7 +100,7 @@ function Invoke-CachedDownload ($app, $version, $url, $to, $cookies = $null, $us
function Start-Download ($url, $to, $cookies) {
$progress = [console]::isoutputredirected -eq $false -and
- $host.name -ne 'Windows PowerShell ISE Host'
+ $host.name -ne 'Windows PowerShell ISE Host'
try {
$url = handle_special_urls $url
@@ -108,50 +108,50 @@ function Start-Download ($url, $to, $cookies) {
} catch {
$e = $_.exception
if ($e.Response.StatusCode -eq 'Unauthorized') {
- warn "Token might be misconfigured."
+ warn 'Token might be misconfigured.'
}
- if($e.innerexception) { $e = $e.innerexception }
+ if ($e.innerexception) { $e = $e.innerexception }
throw $e
}
}
function aria_exit_code($exitcode) {
$codes = @{
- 0='All downloads were successful'
- 1='An unknown error occurred'
- 2='Timeout'
- 3='Resource was not found'
- 4='Aria2 saw the specified number of "resource not found" error. See --max-file-not-found option'
- 5='Download aborted because download speed was too slow. See --lowest-speed-limit option'
- 6='Network problem occurred.'
- 7='There were unfinished downloads. This error is only reported if all finished downloads were successful and there were unfinished downloads in a queue when aria2 exited by pressing Ctrl-C by an user or sending TERM or INT signal'
- 8='Remote server did not support resume when resume was required to complete download'
- 9='There was not enough disk space available'
- 10='Piece length was different from one in .aria2 control file. See --allow-piece-length-change option'
- 11='Aria2 was downloading same file at that moment'
- 12='Aria2 was downloading same info hash torrent at that moment'
- 13='File already existed. See --allow-overwrite option'
- 14='Renaming file failed. See --auto-file-renaming option'
- 15='Aria2 could not open existing file'
- 16='Aria2 could not create new file or truncate existing file'
- 17='File I/O error occurred'
- 18='Aria2 could not create directory'
- 19='Name resolution failed'
- 20='Aria2 could not parse Metalink document'
- 21='FTP command failed'
- 22='HTTP response header was bad or unexpected'
- 23='Too many redirects occurred'
- 24='HTTP authorization failed'
- 25='Aria2 could not parse bencoded file (usually ".torrent" file)'
- 26='".torrent" file was corrupted or missing information that aria2 needed'
- 27='Magnet URI was bad'
- 28='Bad/unrecognized option was given or unexpected option argument was given'
- 29='The remote server was unable to handle the request due to a temporary overloading or maintenance'
- 30='Aria2 could not parse JSON-RPC request'
- 31='Reserved. Not used'
- 32='Checksum validation failed'
- }
- if($null -eq $codes[$exitcode]) {
+ 0 = 'All downloads were successful'
+ 1 = 'An unknown error occurred'
+ 2 = 'Timeout'
+ 3 = 'Resource was not found'
+ 4 = 'Aria2 saw the specified number of "resource not found" error. See --max-file-not-found option'
+ 5 = 'Download aborted because download speed was too slow. See --lowest-speed-limit option'
+ 6 = 'Network problem occurred.'
+ 7 = 'There were unfinished downloads. This error is only reported if all finished downloads were successful and there were unfinished downloads in a queue when aria2 exited by pressing Ctrl-C by an user or sending TERM or INT signal'
+ 8 = 'Remote server did not support resume when resume was required to complete download'
+ 9 = 'There was not enough disk space available'
+ 10 = 'Piece length was different from one in .aria2 control file. See --allow-piece-length-change option'
+ 11 = 'Aria2 was downloading same file at that moment'
+ 12 = 'Aria2 was downloading same info hash torrent at that moment'
+ 13 = 'File already existed. See --allow-overwrite option'
+ 14 = 'Renaming file failed. See --auto-file-renaming option'
+ 15 = 'Aria2 could not open existing file'
+ 16 = 'Aria2 could not create new file or truncate existing file'
+ 17 = 'File I/O error occurred'
+ 18 = 'Aria2 could not create directory'
+ 19 = 'Name resolution failed'
+ 20 = 'Aria2 could not parse Metalink document'
+ 21 = 'FTP command failed'
+ 22 = 'HTTP response header was bad or unexpected'
+ 23 = 'Too many redirects occurred'
+ 24 = 'HTTP authorization failed'
+ 25 = 'Aria2 could not parse bencoded file (usually ".torrent" file)'
+ 26 = '".torrent" file was corrupted or missing information that aria2 needed'
+ 27 = 'Magnet URI was bad'
+ 28 = 'Bad/unrecognized option was given or unexpected option argument was given'
+ 29 = 'The remote server was unable to handle the request due to a temporary overloading or maintenance'
+ 30 = 'Aria2 could not parse JSON-RPC request'
+ 31 = 'Reserved. Not used'
+ 32 = 'Checksum validation failed'
+ }
+ if ($null -eq $codes[$exitcode]) {
return 'An unknown error occurred'
}
return $codes[$exitcode]
@@ -160,7 +160,7 @@ function aria_exit_code($exitcode) {
function get_filename_from_metalink($file) {
$bytes = get_magic_bytes_pretty $file ''
# check if file starts with '"}
+ $dashes += switch ($p) {
+ 100 { '=' }
+ default { '>' }
}
# the remaining characters are filled with spaces
- $spaces = switch($dashes.Length) {
- $midwidth {[string]::Empty}
+ $spaces = switch ($dashes.Length) {
+ $midwidth { [string]::Empty }
default {
- [string]::Join("", ((1..($midwidth - $dashes.Length)) | ForEach-Object {" "}))
+ [string]::Join('', ((1..($midwidth - $dashes.Length)) | ForEach-Object { ' ' }))
}
}
@@ -514,32 +514,32 @@ function Format-DownloadProgress ($url, $read, $total, $console) {
}
function Write-DownloadProgress ($read, $total, $url) {
- $console = $host.UI.RawUI;
- $left = $console.CursorPosition.X;
- $top = $console.CursorPosition.Y;
- $width = $console.BufferSize.Width;
+ $console = $host.UI.RawUI
+ $left = $console.CursorPosition.X
+ $top = $console.CursorPosition.Y
+ $width = $console.BufferSize.Width
- if($read -eq 0) {
+ if ($read -eq 0) {
$maxOutputLength = $(Format-DownloadProgress $url 100 $total $console).length
if (($left + $maxOutputLength) -gt $width) {
# not enough room to print progress on this line
# print on new line
- write-host
+ Write-Host
$left = 0
- $top = $top + 1
- if($top -gt $console.CursorPosition.Y) { $top = $console.CursorPosition.Y }
+ $top = $top + 1
+ if ($top -gt $console.CursorPosition.Y) { $top = $console.CursorPosition.Y }
}
}
- write-host $(Format-DownloadProgress $url $read $total $console) -nonewline
+ Write-Host $(Format-DownloadProgress $url $read $total $console) -NoNewline
[console]::SetCursorPosition($left, $top)
}
function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture, $dir, $use_cache = $true, $check_hash = $true) {
# we only want to show this warning once
- if(!$use_cache) { warn "Cache is being ignored." }
+ if (!$use_cache) { warn 'Cache is being ignored.' }
- # can be multiple urls: if there are, then msi or installer should go last,
+ # can be multiple urls: if there are, then installer should go last,
# so that $fname is set properly
$urls = @(script:url $manifest $architecture)
@@ -552,42 +552,42 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture
# needs to be extracted, will get the next dir from the queue
$extract_dirs = @(extract_dir $manifest $architecture)
$extract_tos = @(extract_to $manifest $architecture)
- $extracted = 0;
+ $extracted = 0
# download first
- if(Test-Aria2Enabled) {
+ if (Test-Aria2Enabled) {
Invoke-CachedAria2Download $app $version $manifest $architecture $dir $cookies $use_cache $check_hash
} else {
- foreach($url in $urls) {
+ foreach ($url in $urls) {
$fname = url_filename $url
try {
Invoke-CachedDownload $app $version $url "$dir\$fname" $cookies $use_cache
} catch {
- write-host -f darkred $_
+ Write-Host -f darkred $_
abort "URL $url is not valid"
}
- if($check_hash) {
+ if ($check_hash) {
$manifest_hash = hash_for_url $manifest $url $architecture
$ok, $err = check_hash "$dir\$fname" $manifest_hash $(show_app $app $bucket)
- if(!$ok) {
+ if (!$ok) {
error $err
$cached = cache_path $app $version $url
- if(test-path $cached) {
+ if (Test-Path $cached) {
# rm cached file
- Remove-Item -force $cached
+ Remove-Item -Force $cached
}
- if($url.Contains('sourceforge.net')) {
+ if ($url.Contains('sourceforge.net')) {
Write-Host -f yellow 'SourceForge.net is known for causing hash validation fails. Please try again before opening a ticket.'
}
- abort $(new_issue_msg $app $bucket "hash check failed")
+ abort $(new_issue_msg $app $bucket 'hash check failed')
}
}
}
}
- foreach($url in $urls) {
+ foreach ($url in $urls) {
$fname = url_filename $url
$extract_dir = $extract_dirs[$extracted]
@@ -597,32 +597,29 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture
$extract_fn = $null
if ($manifest.innosetup) {
$extract_fn = 'Expand-InnoArchive'
- } elseif($fname -match '\.zip$') {
+ } elseif ($fname -match '\.zip$') {
# Use 7zip when available (more fast)
if (((get_config USE_EXTERNAL_7ZIP) -and (Test-CommandAvailable 7z)) -or (Test-HelperInstalled -Helper 7zip)) {
$extract_fn = 'Expand-7zipArchive'
} else {
$extract_fn = 'Expand-ZipArchive'
}
- } elseif($fname -match '\.msi$') {
- # check manifest doesn't use deprecated install method
- if(msi $manifest $architecture) {
- warn "MSI install is deprecated. If you maintain this manifest, please refer to the manifest reference docs."
- } else {
- $extract_fn = 'Expand-MsiArchive'
- }
- } elseif(Test-ZstdRequirement -Uri $fname) { # Zstd first
+ } elseif ($fname -match '\.msi$') {
+ $extract_fn = 'Expand-MsiArchive'
+ } elseif (Test-ZstdRequirement -Uri $fname) {
+ # Zstd first
$extract_fn = 'Expand-ZstdArchive'
- } elseif(Test-7zipRequirement -Uri $fname) { # 7zip
+ } elseif (Test-7zipRequirement -Uri $fname) {
+ # 7zip
$extract_fn = 'Expand-7zipArchive'
}
- if($extract_fn) {
- Write-Host "Extracting " -NoNewline
+ if ($extract_fn) {
+ Write-Host 'Extracting ' -NoNewline
Write-Host $fname -f Cyan -NoNewline
- Write-Host " ... " -NoNewline
+ Write-Host ' ... ' -NoNewline
& $extract_fn -Path "$dir\$fname" -DestinationPath "$dir\$extract_to" -ExtractDir $extract_dir -Removal
- Write-Host "done." -f Green
+ Write-Host 'done.' -f Green
$extracted++
}
}
@@ -631,7 +628,7 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture
}
function cookie_header($cookies) {
- if(!$cookies) { return }
+ if (!$cookies) { return }
$vals = $cookies.psobject.properties | ForEach-Object {
"$($_.name)=$($_.value)"
@@ -654,14 +651,14 @@ function ftp_file_size($url) {
# hashes
function hash_for_url($manifest, $url, $arch) {
- $hashes = @(hash $manifest $arch) | Where-Object { $_ -ne $null };
+ $hashes = @(hash $manifest $arch) | Where-Object { $_ -ne $null }
- if($hashes.length -eq 0) { return $null }
+ if ($hashes.length -eq 0) { return $null }
$urls = @(script:url $manifest $arch)
$index = [array]::indexof($urls, $url)
- if($index -eq -1) { abort "Couldn't find hash in manifest for '$url'." }
+ if ($index -eq -1) { abort "Couldn't find hash in manifest for '$url'." }
@($hashes)[$index]
}
@@ -669,14 +666,14 @@ function hash_for_url($manifest, $url, $arch) {
# returns (ok, err)
function check_hash($file, $hash, $app_name) {
$file = fullpath $file
- if(!$hash) {
+ 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
}
- Write-Host "Checking hash of " -NoNewline
+ Write-Host 'Checking hash of ' -NoNewline
Write-Host $(url_remote_filename $url) -f Cyan -NoNewline
- Write-Host " ... " -nonewline
+ Write-Host ' ... ' -NoNewline
$algorithm, $expected = get_hash $hash
if ($null -eq $algorithm) {
return $false, "Hash type '$algorithm' isn't supported."
@@ -685,152 +682,89 @@ function check_hash($file, $hash, $app_name) {
$actual = (Get-FileHash -Path $file -Algorithm $algorithm).Hash.ToLower()
$expected = $expected.ToLower()
- if($actual -ne $expected) {
+ if ($actual -ne $expected) {
$msg = "Hash check failed!`n"
$msg += "App: $app_name`n"
$msg += "URL: $url`n"
- if(Test-Path $file) {
+ if (Test-Path $file) {
$msg += "First bytes: $((get_magic_bytes_pretty $file ' ').ToUpper())`n"
}
- if($expected -or $actual) {
+ if ($expected -or $actual) {
$msg += "Expected: $expected`n"
$msg += "Actual: $actual"
}
return $false, $msg
}
- Write-Host "ok." -f Green
+ Write-Host 'ok.' -f Green
return $true, $null
}
# for dealing with installers
function args($config, $dir, $global) {
- if($config) { return $config | ForEach-Object { (format $_ @{'dir'=$dir;'global'=$global}) } }
+ if ($config) { return $config | ForEach-Object { (format $_ @{'dir' = $dir; 'global' = $global }) } }
@()
}
function run_installer($fname, $manifest, $architecture, $dir, $global) {
- # MSI or other installer
- $msi = msi $manifest $architecture
$installer = installer $manifest $architecture
- if($installer.script) {
- write-output "Running installer script..."
+ if ($installer.script) {
+ Write-Output 'Running installer script...'
Invoke-Command ([scriptblock]::Create($installer.script -join "`r`n"))
return
}
-
- if($msi) {
- install_msi $fname $dir $msi
- } elseif($installer) {
- install_prog $fname $dir $installer $global
- }
-}
-
-# deprecated (see also msi_installed)
-function install_msi($fname, $dir, $msi) {
- $msifile = "$dir\$(coalesce $msi.file "$fname")"
- if(!(is_in_dir $dir $msifile)) {
- abort "Error in manifest: MSI file $msifile is outside the app directory."
- }
- if(!($msi.code)) { abort "Error in manifest: Couldn't find MSI code."}
- if(msi_installed $msi.code) { abort "The MSI package is already installed on this system." }
-
- $logfile = "$dir\install.log"
-
- $arg = @("/i `"$msifile`"", '/norestart', "/lvp `"$logfile`"", "TARGETDIR=`"$dir`"",
- "INSTALLDIR=`"$dir`"") + @(args $msi.args $dir)
-
- if($msi.silent) { $arg += '/qn', 'ALLUSERS=2', 'MSIINSTALLPERUSER=1' }
- else { $arg += '/qb-!' }
-
- $continue_exit_codes = @{ 3010 = "a restart is required to complete installation" }
-
- $installed = Invoke-ExternalCommand 'msiexec' $arg -Activity "Running installer..." -ContinueExitCodes $continue_exit_codes
- if(!$installed) {
- abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
- }
- Remove-Item $logfile
- Remove-Item $msifile
-}
-
-# deprecated
-# get-wmiobject win32_product is slow and checks integrity of each installed program,
-# so this uses the [wmi] type accelerator instead
-# http://blogs.technet.com/b/heyscriptingguy/archive/2011/12/14/use-powershell-to-find-and-uninstall-software.aspx
-function msi_installed($code) {
- $path = "hklm:\software\microsoft\windows\currentversion\uninstall\$code"
- if(!(test-path $path)) { return $false }
- $key = Get-Item $path
- $name = $key.getvalue('displayname')
- $version = $key.getvalue('displayversion')
- $classkey = "IdentifyingNumber=`"$code`",Name=`"$name`",Version=`"$version`""
- try { $wmi = [wmi]"Win32_Product.$classkey"; $true } catch { $false }
+ install_prog $fname $dir $installer $global
}
function install_prog($fname, $dir, $installer, $global) {
$prog = "$dir\$(coalesce $installer.file "$fname")"
- if(!(is_in_dir $dir $prog)) {
+ if (!(is_in_dir $dir $prog)) {
abort "Error in manifest: Installer $prog is outside the app directory."
}
$arg = @(args $installer.args $dir $global)
- if($prog.endswith('.ps1')) {
+ if ($prog.endswith('.ps1')) {
& $prog @arg
} else {
- $installed = Invoke-ExternalCommand $prog $arg -Activity "Running installer..."
- if(!$installed) {
+ $installed = Invoke-ExternalCommand $prog $arg -Activity 'Running installer...'
+ if (!$installed) {
abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
}
# Don't remove installer if "keep" flag is set to true
- if(!($installer.keep -eq "true")) {
+ if (!($installer.keep -eq 'true')) {
Remove-Item $prog
}
}
}
function run_uninstaller($manifest, $architecture, $dir) {
- $msi = msi $manifest $architecture
$uninstaller = uninstaller $manifest $architecture
$version = $manifest.version
- if($uninstaller.script) {
- write-output "Running uninstaller script..."
+ if ($uninstaller.script) {
+ Write-Output 'Running uninstaller script...'
Invoke-Command ([scriptblock]::Create($uninstaller.script -join "`r`n"))
return
}
- if($msi -or $uninstaller) {
- $exe = $null; $arg = $null; $continue_exit_codes = @{}
-
- if($msi) {
- $code = $msi.code
- $exe = "msiexec";
- $arg = @("/norestart", "/x $code")
- if($msi.silent) {
- $arg += '/qn', 'ALLUSERS=2', 'MSIINSTALLPERUSER=1'
- } else {
- $arg += '/qb-!'
- }
-
- $continue_exit_codes.1605 = 'not installed, skipping'
- $continue_exit_codes.3010 = 'restart required'
- } elseif($uninstaller) {
- $exe = "$dir\$($uninstaller.file)"
- $arg = args $uninstaller.args
- if(!(is_in_dir $dir $exe)) {
- warn "Error in manifest: Installer $exe is outside the app directory, skipping."
- $exe = $null;
- } elseif(!(test-path $exe)) {
- warn "Uninstaller $exe is missing, skipping."
- $exe = $null;
- }
+ if ($uninstaller.file) {
+ $exe = "$dir\$($uninstaller.file)"
+ $arg = args $uninstaller.args
+ if (!(is_in_dir $dir $exe)) {
+ warn "Error in manifest: Installer $exe is outside the app directory, skipping."
+ $exe = $null
+ } elseif (!(Test-Path $exe)) {
+ warn "Uninstaller $exe is missing, skipping."
+ $exe = $null
}
- if($exe) {
- if($exe.endswith('.ps1')) {
+ if ($exe) {
+ if ($exe.endswith('.ps1')) {
& $exe @arg
} else {
- $uninstalled = Invoke-ExternalCommand $exe $arg -Activity "Running uninstaller..." -ContinueExitCodes $continue_exit_codes
- if(!$uninstalled) { abort "Uninstallation aborted." }
+ $uninstalled = Invoke-ExternalCommand $exe $arg -Activity 'Running uninstaller...'
+ if (!$uninstalled) {
+ abort 'Uninstallation aborted.'
+ }
}
}
}
@@ -838,7 +772,7 @@ function run_uninstaller($manifest, $architecture, $dir) {
# get target, name, arguments for shim
function shim_def($item) {
- if($item -is [array]) { return $item }
+ if ($item -is [array]) { return $item }
return $item, (strip_ext (fname $item)), $null
}
@@ -846,18 +780,18 @@ function create_shims($manifest, $dir, $global, $arch) {
$shims = @(arch_specific 'bin' $manifest $arch)
$shims | Where-Object { $_ -ne $null } | ForEach-Object {
$target, $name, $arg = shim_def $_
- write-output "Creating shim for '$name'."
+ Write-Output "Creating shim for '$name'."
- if(test-path "$dir\$target" -pathType leaf) {
+ if (Test-Path "$dir\$target" -PathType leaf) {
$bin = "$dir\$target"
- } elseif(test-path $target -pathType leaf) {
+ } elseif (Test-Path $target -PathType leaf) {
$bin = $target
} else {
$bin = search_in_path $target
}
- if(!$bin) { abort "Can't shim '$target': File doesn't exist."}
+ if (!$bin) { abort "Can't shim '$target': File doesn't exist." }
- shim $bin $global $name (substitute $arg @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir})
+ shim $bin $global $name (substitute $arg @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir })
}
}
@@ -949,15 +883,15 @@ function ensure_install_dir_not_in_path($dir, $global) {
$path = (env 'path' $global)
$fixed, $removed = find_dir_or_subdir $path "$dir"
- if($removed) {
- $removed | ForEach-Object { "Installer added '$(friendly_path $_)' to path. Removing."}
+ if ($removed) {
+ $removed | ForEach-Object { "Installer added '$(friendly_path $_)' to path. Removing." }
env 'path' $global $fixed
}
- if(!$global) {
+ if (!$global) {
$fixed, $removed = find_dir_or_subdir (env 'path' $true) "$dir"
- if($removed) {
- $removed | ForEach-Object { warn "Installer added '$_' to system path. You might want to remove this manually (requires admin permission)."}
+ if ($removed) {
+ $removed | ForEach-Object { warn "Installer added '$_' to system path. You might want to remove this manually (requires admin permission)." }
}
}
}
@@ -967,8 +901,8 @@ function find_dir_or_subdir($path, $dir) {
$fixed = @()
$removed = @()
$path.split(';') | ForEach-Object {
- if($_) {
- if(($_ -eq $dir) -or ($_ -like "$dir\*")) { $removed += $_ }
+ if ($_) {
+ if (($_ -eq $dir) -or ($_ -like "$dir\*")) { $removed += $_ }
else { $fixed += $_ }
}
}
@@ -1009,8 +943,8 @@ function env_set($manifest, $dir, $global, $arch) {
$env_set = arch_specific 'env_set' $manifest $arch
if ($env_set) {
$env_set | Get-Member -Member NoteProperty | ForEach-Object {
- $name = $_.name;
- $val = format $env_set.$($_.name) @{ "dir" = $dir }
+ $name = $_.name
+ $val = format $env_set.$($_.name) @{ 'dir' = $dir }
env $name $global $val
Set-Content env:\$name $val
}
@@ -1032,7 +966,7 @@ function Invoke-HookScript {
param(
[Parameter(Mandatory = $true)]
[ValidateSet('pre_install', 'post_install',
- 'pre_uninstall', 'post_uninstall')]
+ 'pre_uninstall', 'post_uninstall')]
[String] $HookType,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
@@ -1050,10 +984,10 @@ function Invoke-HookScript {
}
function show_notes($manifest, $dir, $original_dir, $persist_dir) {
- if($manifest.notes) {
- write-output "Notes"
- write-output "-----"
- write-output (wraptext (substitute $manifest.notes @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir}))
+ if ($manifest.notes) {
+ Write-Output 'Notes'
+ Write-Output '-----'
+ Write-Output (wraptext (substitute $manifest.notes @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir }))
}
}
@@ -1098,23 +1032,23 @@ function ensure_none_failed($apps) {
function show_suggestions($suggested) {
$installed_apps = (installed_apps $true) + (installed_apps $false)
- foreach($app in $suggested.keys) {
- $features = $suggested[$app] | get-member -type noteproperty | ForEach-Object { $_.name }
- foreach($feature in $features) {
+ foreach ($app in $suggested.keys) {
+ $features = $suggested[$app] | Get-Member -type noteproperty | ForEach-Object { $_.name }
+ foreach ($feature in $features) {
$feature_suggestions = $suggested[$app].$feature
$fulfilled = $false
- foreach($suggestion in $feature_suggestions) {
+ foreach ($suggestion in $feature_suggestions) {
$suggested_app, $bucket, $null = parse_app $suggestion
- if($installed_apps -contains $suggested_app) {
- $fulfilled = $true;
- break;
+ if ($installed_apps -contains $suggested_app) {
+ $fulfilled = $true
+ break
}
}
- if(!$fulfilled) {
- write-host "'$app' suggests installing '$([string]::join("' or '", $feature_suggestions))'."
+ if (!$fulfilled) {
+ Write-Host "'$app' suggests installing '$([string]::join("' or '", $feature_suggestions))'."
}
}
}
@@ -1139,19 +1073,19 @@ function persist_def($persist) {
function persist_data($manifest, $original_dir, $persist_dir) {
$persist = $manifest.persist
- if($persist) {
+ if ($persist) {
$persist_dir = ensure $persist_dir
if ($persist -is [String]) {
- $persist = @($persist);
+ $persist = @($persist)
}
$persist | ForEach-Object {
$source, $target = persist_def $_
- write-host "Persisting $source"
+ Write-Host "Persisting $source"
- $source = $source.TrimEnd("/").TrimEnd("\\")
+ $source = $source.TrimEnd('/').TrimEnd('\\')
$source = fullpath "$dir\$source"
$target = fullpath "$persist_dir\$target"
@@ -1215,7 +1149,7 @@ function unlink_persist_data($manifest, $dir) {
# check whether write permission for Users usergroup is set to global persist dir, if not then set
function persist_permission($manifest, $global) {
- if($global -and $manifest.persist -and (is_admin)) {
+ if ($global -and $manifest.persist -and (is_admin)) {
$path = persistdir $null $global
$user = New-Object System.Security.Principal.SecurityIdentifier 'S-1-5-32-545'
$target_rule = New-Object System.Security.AccessControl.FileSystemAccessRule($user, 'Write', 'ObjectInherit', 'none', 'Allow')
diff --git a/lib/manifest.ps1 b/lib/manifest.ps1
index 5e0d9fe2c2..f66755c6f4 100644
--- a/lib/manifest.ps1
+++ b/lib/manifest.ps1
@@ -155,7 +155,6 @@ function generate_user_manifest($app, $bucket, $version) {
function url($manifest, $arch) { arch_specific 'url' $manifest $arch }
function installer($manifest, $arch) { arch_specific 'installer' $manifest $arch }
function uninstaller($manifest, $arch) { arch_specific 'uninstaller' $manifest $arch }
-function msi($manifest, $arch) { arch_specific 'msi' $manifest $arch }
function hash($manifest, $arch) { arch_specific 'hash' $manifest $arch }
function extract_dir($manifest, $arch) { arch_specific 'extract_dir' $manifest $arch}
function extract_to($manifest, $arch) { arch_specific 'extract_to' $manifest $arch}
diff --git a/libexec/scoop-config.ps1 b/libexec/scoop-config.ps1
index 09487da7c5..dbc1925305 100644
--- a/libexec/scoop-config.ps1
+++ b/libexec/scoop-config.ps1
@@ -151,30 +151,12 @@ if (!$name) {
} elseif ($name -like '--help') {
my_usage
} elseif ($name -like 'rm') {
- # NOTE Scoop config file migration. Remove this after 2023/6/30
- if ($value -notin 'SCOOP_REPO', 'SCOOP_BRANCH' -and $value -in $newConfigNames.Keys) {
- warn ('Config option "{0}" is deprecated, please use "{1}" instead next time.' -f $value, $newConfigNames.$value)
- $value = $newConfigNames.$value
- }
- # END NOTE
set_config $value $null | Out-Null
Write-Host "'$value' has been removed"
} elseif ($null -ne $value) {
- # NOTE Scoop config file migration. Remove this after 2023/6/30
- if ($name -notin 'SCOOP_REPO', 'SCOOP_BRANCH' -and $name -in $newConfigNames.Keys) {
- warn ('Config option "{0}" is deprecated, please use "{1}" instead next time.' -f $name, $newConfigNames.$name)
- $name = $newConfigNames.$name
- }
- # END NOTE
set_config $name $value | Out-Null
Write-Host "'$name' has been set to '$value'"
} else {
- # NOTE Scoop config file migration. Remove this after 2023/6/30
- if ($name -notin 'SCOOP_REPO', 'SCOOP_BRANCH' -and $name -in $newConfigNames.Keys) {
- warn ('Config option "{0}" is deprecated, please use "{1}" instead next time.' -f $name, $newConfigNames.$name)
- $name = $newConfigNames.$name
- }
- # END NOTE
$value = get_config $name
if($null -eq $value) {
Write-Host "'$name' is not set"
diff --git a/schema.json b/schema.json
index 239218cc23..6c24d4da20 100644
--- a/schema.json
+++ b/schema.json
@@ -127,10 +127,6 @@
"installer": {
"$ref": "#/definitions/installer"
},
- "msi": {
- "$ref": "#/definitions/stringOrArrayOfStrings",
- "description": "Deprecated"
- },
"post_install": {
"$ref": "#/definitions/stringOrArrayOfStrings"
},
@@ -603,10 +599,6 @@
"license": {
"$ref": "#/definitions/license"
},
- "msi": {
- "$ref": "#/definitions/stringOrArrayOfStrings",
- "description": "Deprecated"
- },
"notes": {
"$ref": "#/definitions/stringOrArrayOfStrings"
},
From 54e0514833b25601b7f27a237e6846b2700c7714 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Thu, 7 Mar 2024 10:55:27 +0800
Subject: [PATCH 53/75] fix(install): Fix bugs in #5715 (#5824)
---
CHANGELOG.md | 2 +-
lib/install.ps1 | 58 +++++++++++++++++++++++--------------------------
2 files changed, 28 insertions(+), 32 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb4d363a60..81e03b058c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -52,7 +52,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))
+- **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))
### Builds
diff --git a/lib/install.ps1 b/lib/install.ps1
index 7dc772e7be..3fe945229a 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -712,27 +712,23 @@ function run_installer($fname, $manifest, $architecture, $dir, $global) {
Invoke-Command ([scriptblock]::Create($installer.script -join "`r`n"))
return
}
- install_prog $fname $dir $installer $global
-}
-
-function install_prog($fname, $dir, $installer, $global) {
- $prog = "$dir\$(coalesce $installer.file "$fname")"
- if (!(is_in_dir $dir $prog)) {
- abort "Error in manifest: Installer $prog is outside the app directory."
- }
- $arg = @(args $installer.args $dir $global)
-
- if ($prog.endswith('.ps1')) {
- & $prog @arg
- } else {
- $installed = Invoke-ExternalCommand $prog $arg -Activity 'Running installer...'
- if (!$installed) {
- abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
+ if ($installer) {
+ $prog = "$dir\$(coalesce $installer.file "$fname")"
+ if (!(is_in_dir $dir $prog)) {
+ abort "Error in manifest: Installer $prog is outside the app directory."
}
-
- # Don't remove installer if "keep" flag is set to true
- if (!($installer.keep -eq 'true')) {
- Remove-Item $prog
+ $arg = @(args $installer.args $dir $global)
+ if ($prog.endswith('.ps1')) {
+ & $prog @arg
+ } else {
+ $installed = Invoke-ExternalCommand $prog $arg -Activity 'Running installer...'
+ if (!$installed) {
+ abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
+ }
+ # Don't remove installer if "keep" flag is set to true
+ if (!($installer.keep -eq 'true')) {
+ Remove-Item $prog
+ }
}
}
}
@@ -747,21 +743,21 @@ function run_uninstaller($manifest, $architecture, $dir) {
}
if ($uninstaller.file) {
- $exe = "$dir\$($uninstaller.file)"
+ $prog = "$dir\$($uninstaller.file)"
$arg = args $uninstaller.args
- if (!(is_in_dir $dir $exe)) {
- warn "Error in manifest: Installer $exe is outside the app directory, skipping."
- $exe = $null
- } elseif (!(Test-Path $exe)) {
- warn "Uninstaller $exe is missing, skipping."
- $exe = $null
+ if (!(is_in_dir $dir $prog)) {
+ warn "Error in manifest: Installer $prog is outside the app directory, skipping."
+ $prog = $null
+ } elseif (!(Test-Path $prog)) {
+ warn "Uninstaller $prog is missing, skipping."
+ $prog = $null
}
- if ($exe) {
- if ($exe.endswith('.ps1')) {
- & $exe @arg
+ if ($prog) {
+ if ($prog.endswith('.ps1')) {
+ & $prog @arg
} else {
- $uninstalled = Invoke-ExternalCommand $exe $arg -Activity 'Running uninstaller...'
+ $uninstalled = Invoke-ExternalCommand $prog $arg -Activity 'Running uninstaller...'
if (!$uninstalled) {
abort 'Uninstallation aborted.'
}
From 6f9ed1d4649bf7fed6abbcb4686db9351d9ddb63 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Wed, 13 Mar 2024 13:22:58 +0800
Subject: [PATCH 54/75] fix(ci): Update 'psmodulecache' version to 'main'
(#5828)
---
.github/workflows/ci.yml | 4 ++--
CHANGELOG.md | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3e87fa1b2e..3c7541f7bb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,7 +14,7 @@ jobs:
with:
fetch-depth: 2
- name: Init Test Suite
- uses: potatoqualitee/psmodulecache@v5.1
+ uses: potatoqualitee/psmodulecache@main
with:
modules-to-cache: BuildHelpers
shell: powershell
@@ -30,7 +30,7 @@ jobs:
with:
fetch-depth: 2
- name: Init Test Suite
- uses: potatoqualitee/psmodulecache@v5.1
+ uses: potatoqualitee/psmodulecache@main
with:
modules-to-cache: BuildHelpers
shell: pwsh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 81e03b058c..c15938c374 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -60,7 +60,8 @@
### Continuous Integration
-- **dependabot:** Add dependabot.yml for GitHub Actions ([#5377](https://github.com/ScoopInstaller/Scoop/pull/5377))
+- **dependabot:** Add dependabot.yml for GitHub Actions ([#5377](https://github.com/ScoopInstaller/Scoop/issues/5377))
+- **module:** Update 'psmodulecache' version to 'main' ([#5828](https://github.com/ScoopInstaller/Scoop/issues/5828))
### Tests
From 9d07c33e871a4e91f0a2d5ff4e112cf3185b8805 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Wed, 13 Mar 2024 18:41:58 +0800
Subject: [PATCH 55/75] fix(decompress): Remove unused parent dir w/
'extract_dir' (#5682)
---
CHANGELOG.md | 1 +
lib/decompress.ps1 | 28 ++++++++++++++++------------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c15938c374..b33caca7ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,7 @@
- **scoop-(un)hold:** Correct output the messages when manifest not found, (already|not) held ([#5519](https://github.com/ScoopInstaller/Scoop/issues/5519))
- **scoop-update:** Change error message to a better instruction ([#5677](https://github.com/ScoopInstaller/Scoop/issues/5677))
- **manifest:** Correct source of manifest ([#5575](https://github.com/ScoopInstaller/Scoop/issues/5575))
+- **decompress:** Remove unused parent dir w/ 'extract_dir' ([#5682](https://github.com/ScoopInstaller/Scoop/issues/5682))
- **shim:** Check literal path in `Get-ShimPath` ([#5680](https://github.com/ScoopInstaller/Scoop/issues/5680))
- **shim:** Avoid unexpected output of `list` subcommand ([#5681](https://github.com/ScoopInstaller/Scoop/issues/5681))
- **scoop-reset:** Don't abort when multiple apps are passed and an app is running ([#5687](https://github.com/ScoopInstaller/Scoop/issues/5687))
diff --git a/lib/decompress.ps1 b/lib/decompress.ps1
index bdee90d620..4fade6dd0a 100644
--- a/lib/decompress.ps1
+++ b/lib/decompress.ps1
@@ -46,12 +46,6 @@ function Expand-7zipArchive {
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
}
- if (!$IsTar -and $ExtractDir) {
- movedir "$DestinationPath\$ExtractDir" $DestinationPath | Out-Null
- }
- if (Test-Path $LogPath) {
- Remove-Item $LogPath -Force
- }
if ($IsTar) {
# Check for tar
$Status = Invoke-ExternalCommand $7zPath @('l', $Path) -LogPath $LogPath
@@ -63,8 +57,15 @@ function Expand-7zipArchive {
abort "Failed to list files in $Path.`nNot a 7-Zip supported archive file."
}
}
+ if (!$IsTar -and $ExtractDir) {
+ movedir "$DestinationPath\$ExtractDir" $DestinationPath | Out-Null
+ # Remove temporary directory
+ Remove-Item "$DestinationPath\$($ExtractDir -replace '[\\/].*')" -Recurse -Force -ErrorAction Ignore
+ }
+ if (Test-Path $LogPath) {
+ Remove-Item $LogPath -Force
+ }
if ($Removal) {
- # Remove original archive file
if (($Path -replace '.*\.([^\.]*)$', '$1') -eq '001') {
# Remove splited 7-zip archive parts
Get-ChildItem "$($Path -replace '\.[^\.]*$', '').???" | Remove-Item -Force
@@ -72,6 +73,7 @@ function Expand-7zipArchive {
# Remove splitted RAR archive parts
Get-ChildItem "$($Path -replace '\.part(\d+)\.rar$', '').part*.rar" | Remove-Item -Force
} else {
+ # Remove original archive file
Remove-Item $Path -Force
}
}
@@ -112,17 +114,19 @@ function Expand-ZstdArchive {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
}
$IsTar = (strip_ext $Path) -match '\.tar$'
+ if ($IsTar) {
+ # Check for tar
+ $TarFile = Join-Path $DestinationPath (strip_ext (fname $Path))
+ Expand-7zipArchive -Path $TarFile -DestinationPath $DestinationPath -ExtractDir $ExtractDir -Removal
+ }
if (!$IsTar -and $ExtractDir) {
movedir (Join-Path $DestinationPath $ExtractDir) $DestinationPath | Out-Null
+ # Remove temporary directory
+ Remove-Item "$DestinationPath\$($ExtractDir -replace '[\\/].*')" -Recurse -Force -ErrorAction Ignore
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
}
- if ($IsTar) {
- # Check for tar
- $TarFile = Join-Path $DestinationPath (strip_ext (fname $Path))
- Expand-7zipArchive -Path $TarFile -DestinationPath $DestinationPath -ExtractDir $ExtractDir -Removal
- }
}
function Expand-MsiArchive {
From 3186fef105b59d49b3abc813c168a05239982fc5 Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Wed, 20 Mar 2024 17:17:48 +0800
Subject: [PATCH 56/75] fix(update/uninstall): Remove items from PATH correctly
(#5833)
---
CHANGELOG.md | 1 +
lib/install.ps1 | 15 ++++++++++-----
libexec/scoop-update.ps1 | 5 ++---
3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b33caca7ec..c29b636dda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,7 @@
- **core:** Do not call `scoop` externally from inside the code ([#5695](https://github.com/ScoopInstaller/Scoop/issues/5695))
- **scoop-checkup:** Don't throw 7zip error when external 7zip is used ([#5703](https://github.com/ScoopInstaller/Scoop/issues/5703))
- **config:** Warn users about misconfigured GitHub token ([#5777](https://github.com/ScoopInstaller/Scoop/issues/5777))
+- **update/uninstall:** Remove items from PATH correctly ([#5833](https://github.com/ScoopInstaller/Scoop/issues/5833))
### Performance Improvements
diff --git a/lib/install.ps1 b/lib/install.ps1
index 3fe945229a..0ed13707e8 100644
--- a/lib/install.ps1
+++ b/lib/install.ps1
@@ -917,7 +917,6 @@ function env_add_path($manifest, $dir, $global, $arch) {
} 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."
}
@@ -928,10 +927,16 @@ function env_add_path($manifest, $dir, $global, $arch) {
function env_rm_path($manifest, $dir, $global, $arch) {
$env_add_path = arch_specific 'env_add_path' $manifest $arch
- $env_add_path | Where-Object { $_ } | ForEach-Object {
- $path_dir = Join-Path $dir $_
-
- remove_from_path $path_dir $global
+ $dir = $dir.TrimEnd('\')
+ if ($env_add_path) {
+ $env_add_path | Where-Object { $_ } | ForEach-Object {
+ if ($_ -eq '.') {
+ $path_dir = $dir
+ } else {
+ $path_dir = Join-Path $dir $_
+ }
+ remove_from_path $path_dir $global
+ }
}
}
diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1
index 50f82090a5..e632be72fb 100644
--- a/libexec/scoop-update.ps1
+++ b/libexec/scoop-update.ps1
@@ -289,15 +289,14 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c
Write-Host "Uninstalling '$app' ($old_version)"
run_uninstaller $old_manifest $architecture $dir
rm_shims $app $old_manifest $global $architecture
- env_rm_path $old_manifest $dir $global $architecture
- env_rm $old_manifest $global $architecture
# If a junction was used during install, that will have been used
# as the reference directory. Otherwise it will just be the version
# directory.
$refdir = unlink_current $dir
-
uninstall_psmodule $old_manifest $refdir $global
+ env_rm_path $old_manifest $refdir $global $architecture
+ env_rm $old_manifest $global $architecture
if ($force -and ($old_version -eq $version)) {
if (!(Test-Path "$dir/../_$version.old")) {
From 90766f9315696d1e5ef982ce1ad6385616336d7a Mon Sep 17 00:00:00 2001
From: Suhas <98212676+spider2048@users.noreply.github.com>
Date: Wed, 20 Mar 2024 19:46:10 +0530
Subject: [PATCH 57/75] fix(shim): Allow GUI applications to attach to the
shell's console when launched using the GUI shim (#5721)
---
CHANGELOG.md | 1 +
supporting/shimexe/bin/checksum.sha256 | 2 +-
supporting/shimexe/bin/checksum.sha512 | 2 +-
supporting/shimexe/bin/shim.exe | Bin 7680 -> 7680 bytes
supporting/shimexe/shim.cs | 13 ++++++++++++-
5 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c29b636dda..caf89b9fca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,7 @@
- **scoop-checkup:** Don't throw 7zip error when external 7zip is used ([#5703](https://github.com/ScoopInstaller/Scoop/issues/5703))
- **config:** Warn users about misconfigured GitHub token ([#5777](https://github.com/ScoopInstaller/Scoop/issues/5777))
- **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))
### Performance Improvements
diff --git a/supporting/shimexe/bin/checksum.sha256 b/supporting/shimexe/bin/checksum.sha256
index 7a67617054..2f462bd732 100644
--- a/supporting/shimexe/bin/checksum.sha256
+++ b/supporting/shimexe/bin/checksum.sha256
@@ -1 +1 @@
-9726c3a429009a5b22bd92cb8ab96724c670e164e7240e83f27b7c8b7bd1ca39 *shim.exe
+1e4a9e4b305ef78b375159b25e2f8a90243584efd56ed6994072a8dfc2147ade *shim.exe
diff --git a/supporting/shimexe/bin/checksum.sha512 b/supporting/shimexe/bin/checksum.sha512
index 915750f159..5344ca9314 100644
--- a/supporting/shimexe/bin/checksum.sha512
+++ b/supporting/shimexe/bin/checksum.sha512
@@ -1 +1 @@
-18a737674afde4d5e7e1647d8d1e98471bb260513c57739651f92fdf1647d76c92f0cd0a9bb458daf4eae4bdab9d31404162acf6d74a041e6415752b75d722e0 *shim.exe
+f580833905e45b02a433c03647fb0caa3692336c8bde9621c286684629c78d1c56a292bea2887ea0ae941b8beec50322f31975c23ab5644c2b85f3c2108f383d *shim.exe
diff --git a/supporting/shimexe/bin/shim.exe b/supporting/shimexe/bin/shim.exe
index f6f3930334a09939684a8bdd25210df16304afe8..19a7fa36e9bc24035835d54d3530741d6528135b 100644
GIT binary patch
delta 2247
zcmZ8je{2-T75-*+cg}m~BVOP6dF(+7Cm*w~zVY}EXP#)3w-;u9@;Pxe6k?_GdMD5rHp_fC
zC|1g?iSURxoM|b*JX?tp4vuDl9k&63Is&NhVzNElA#L$uI3T}RAERkS@sq%qA0>?!
zHy9fJR<;N?ydry+yPoo0AeyN1EqWZTCHE7Ae5B5ow6um>t>$u4yF|Tc<~`a9TS|3W
z$GjMqmr~?GJ;93wX%6*4!-81Mq4jMySi&(;{dOPc8y9ApIOIHjoUbvGUFX|6Q!3$B
z47IMWw51~b7N??^%k~$9oAau3Jb8^S$lW5kCyd%nDb_-jmNNW`X{NV*7N*V5gzN0Z
zgnR3?g!nY
zaW`n=kndD(kSD1RRuh9Y8rBjPtm%(ggLY0;)!$QH6*)1|`BRl!D*XbuI#VV{gS
z3P%jCm*?%<(55?!JJqBWMMj;sqxh%wSxcb@mk~wWIz#^t#Uw3RvuYzWe^p&1CahPu
z_PW%T1A@GaN#pu0TTeX1pbEdXH5RN77<#>Z-d2$I2lgUt7yHSVGL6C^0s*Y8P
zW9Re~dd1G^lekMLTp(9y5`Dza+Zv}0f7RH3XYkKb`&=^krla|L2K$ZWgyE-EKkd8G
zU*>Qh`gx*9mBwQR&)AwTGrUe{?g|~~1`~8)6ayl~a}1guO=BkGsl8&MVOkYMN$@v?
zk5(tuq~N`%s4n&O|51aYd_?G%W5M-?bBvYPkN`%J
z^?9kH2G!Ht(CZcTZ~2@^V_R0Q`*wPsEo(r(Q8VeY_N-{Yy|?DdoP5y8Zz6^{PU?O=
z#luKkAX?bZPTJT*bnqE-^$rsw7~##W!XK4@i=-`i_0C#)t;(m|{5$AV7I=o?ZsIR!68I|@Nc@}$1kxtxADCp`7VwDrJoCJogNBdbWtGJUW-T8N
z<3}P-46Qt-uvT@D|6O$88}QYqa2(It-LyPLA3eK?Reh^0dhtE{N^Ga;3Y|`&kG(&I
zchvx%$CLIK&|%WNKpY}(w}*+#?T7FJejvxlA5jx{8NQez|B_O~F7j&nAH_NJtH&An
zg!N;hZ_Vp0@)e?Goin`r8xBp@6q5L*d=nQDmsiN=?Q7iiHs?Ct
zuJ{KYv=)hv@H6Ri?NOdPiNH#VRc52-aN23)2G*+8qKb`MCtSAacCm)-eTkUBIpPw$
zBTgfW_cx0s^oVADYj~p9So)pTqkPRa3kx25yHPkO@@{Vw5u7yIMVA?4y#LxB$Bl3{
zT36_}=@!GWSIFVyC8Oc>IpwU?~_K-ZOIW
zf#8wwId4NlFgCR1;R(hV=g&%M`^4yIUvbNUvGJ+!ns=z??6&V-YCV4H?qeeUV)OGC
zy28oY0f!rs>ABz6HVD^-kX1ZEI{aIr9NwSwYSWc}HS`HOHP6g6r({bZd?xv?xkah}
QIC67g&TITo%(O@T3;B&}T>t<8
delta 2128
zcmZ8i3v5$W82-+=_nxlpnCrT>W1G@B*e=}|qbLM3KoP{6$;4&AlrRAa86tPK1AHL2
zzKE|FmzxkD#AsY1D$d7z#26C=6$olD#)#qr69`cthJ@e?jo&%jV(_N@{_p?KfBtj+
z$8C#k#kR*Ev=5yadSc+wTKP$K;H4#^KMcC8dPas)
z%e;&ArR0RP$0|l5Dw&Nc=}jb0bx$AjQ)7NWyww6L1l}fA8Ie{6yh(I!P#L{uV;$F+
zM9giVwct1Epwe|IqRG;x_E5=F`EFhR$+V0Md)yUi&Z@B2M3VBFiQW_qErbzk)&H#C
zR4$dImX(%-9_!5xsmw*vZKWyGQYd91imbmqW~<3;vL>W;otvgeD`Q%08FaHj(Q#+D
zabW7V0y`-WDe}(#eD8*}1!jRF!}U|vcXi?nxh{JB!miwWN}Dx55*%};he^QBBOBDI
z8lS0~Ib?Zsi8!D7*)8>K@^ZLAT8_e<24~3K_64ZdBa16lpA|us+HFU0!kTU=EWl5Q
zz_AADe_Zs@Qe$?_f#$o^eqz*mmwV4hZMj8|`{*;SciVblHG?X=XKQS-jxzKNd$+Cd
zCwUp##VYbz9;2|q_+-qH+tr{G!E#&UVICjB-(rxL1U6`3dODeMEV0_{gwdiRhF55t
z4BtW&<2asA8Z|-9sw>Ag)Djp^ZEPqBhTVWZOM8yvJXPZ=H;numlAbdCqi;KX)_B=hJr
zJt|@#9acArk%nolMcpc*On?JHZK)^--SQFbtaH1#0N16pK7e~H-xn1q=PRYv!}0+U
z$NW+4F{c@o*g2{#R*#4TJ{r|d$?YPA%lHNY+p31xmMY9M+CbHt_Oqf2i_TkHVzm1>
zAA?-eEqRppmDuZ3SXjkw+2|lT$eQumL=0gi2fPGtDSD3i=3aXPhy7)mXl#zr+qk7AUuTEeHP=*0_`
zi`(#wXeK^lHRBF6s%hjuifOn9X*ClM;VHX~mLh%h>J_Z#S0cx`dPgjxWgmT>!$LOp
zMLcMCVVa5mx=+zf#kG5g)%F^^jwj?ga!+}97Y(97-lY`r67o{|Z^ehWM%~Y#+pOn^
zY3nuOG5HqpFZrI~9}p8(fen0H9>f=LydX;%O%-bY_jBgw2{M!fZ{OXyH5ZA~B9Ph&A{^Jdb*O
zD{9z)3H+AhWqi!{DQ9iQe#{pZ!ffZ|!a<9cz6fC{XZLc3JL?G8MYiX>XEQslf278q
z7IDzf^KE_f`oG_4_FGSv6ta`N0*A>?@FtkAXG7@ELT{xasB#^{DNEi`tLxnqGD6|>2+(q{_Xcex%UsB-u~su
zo1YGjR&))|jaP}_rb<6JQdwTMWAray-{9?R@K0s6+?frk6K8^(5?hALl7BjKUv@ZF
K`>Pme4gCw%u~YH@
diff --git a/supporting/shimexe/shim.cs b/supporting/shimexe/shim.cs
index 1337341ef6..b7a2c0e56e 100644
--- a/supporting/shimexe/shim.cs
+++ b/supporting/shimexe/shim.cs
@@ -21,6 +21,12 @@ static extern bool CreateProcess(string lpApplicationName,
out PROCESS_INFORMATION lpProcessInformation);
const int ERROR_ELEVATION_REQUIRED = 740;
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern bool AttachConsole(int dwProcessId);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern IntPtr GetConsoleWindow();
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO {
public Int32 cb;
@@ -89,7 +95,12 @@ static int Main(string[] args) {
cmd_args += pass_args;
}
if(!string.IsNullOrEmpty(cmd_args)) cmd_args = " " + cmd_args;
- var cmd = "\"" + path + "\"" + cmd_args;
+ var cmd = path + cmd_args;
+
+ // Fix when GUI applications want to write to a console
+ if (GetConsoleWindow() == IntPtr.Zero) {
+ AttachConsole(-1);
+ }
if(!CreateProcess(null, cmd, IntPtr.Zero, IntPtr.Zero,
bInheritHandles: true,
From 5354ab5d164a6fdfb8d279fdc917bf4e1faf090b Mon Sep 17 00:00:00 2001
From: Hsiao-nan Cheung
Date: Thu, 21 Mar 2024 13:30:51 +0800
Subject: [PATCH 58/75] builds(supporting): Update Json to 13.0.3, Json.Schema
to 3.0.15 (#5835)
---
CHANGELOG.md | 1 +
supporting/shimexe/bin/checksum.sha256 | 2 +-
supporting/shimexe/bin/checksum.sha512 | 2 +-
supporting/shimexe/bin/shim.exe | Bin 7680 -> 8192 bytes
supporting/shimexe/build.ps1 | 2 +-
supporting/shimexe/packages.config | 3 +-
supporting/shimexe/shim.csproj | 15 +++++++---
.../validator/bin/Newtonsoft.Json.Schema.dll | Bin 259072 -> 261632 bytes
supporting/validator/bin/Newtonsoft.Json.dll | Bin 701992 -> 711952 bytes
supporting/validator/bin/Scoop.Validator.dll | Bin 7680 -> 7680 bytes
supporting/validator/bin/checksum.sha256 | 8 +++---
supporting/validator/bin/checksum.sha512 | 8 +++---
supporting/validator/bin/validator.exe | Bin 5632 -> 6144 bytes
supporting/validator/build.ps1 | 2 +-
supporting/validator/packages.config | 6 ++--
supporting/validator/validator.csproj | 26 ++++++++++++------
16 files changed, 47 insertions(+), 28 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index caf89b9fca..743d6466fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -60,6 +60,7 @@
### Builds
- **checkver:** Read the private_host config variable ([#5381](https://github.com/ScoopInstaller/Scoop/issues/5381))
+- **supporting:** Update Json to 13.0.3, Json.Schema to 3.0.15 ([#5835](https://github.com/ScoopInstaller/Scoop/issues/5835))
### Continuous Integration
diff --git a/supporting/shimexe/bin/checksum.sha256 b/supporting/shimexe/bin/checksum.sha256
index 2f462bd732..be9604386e 100644
--- a/supporting/shimexe/bin/checksum.sha256
+++ b/supporting/shimexe/bin/checksum.sha256
@@ -1 +1 @@
-1e4a9e4b305ef78b375159b25e2f8a90243584efd56ed6994072a8dfc2147ade *shim.exe
+be80df7b3e50671e360eac64b195543ff38d4a6ae4926d71fbde7d4f70195945 *shim.exe
diff --git a/supporting/shimexe/bin/checksum.sha512 b/supporting/shimexe/bin/checksum.sha512
index 5344ca9314..ed53cb10f9 100644
--- a/supporting/shimexe/bin/checksum.sha512
+++ b/supporting/shimexe/bin/checksum.sha512
@@ -1 +1 @@
-f580833905e45b02a433c03647fb0caa3692336c8bde9621c286684629c78d1c56a292bea2887ea0ae941b8beec50322f31975c23ab5644c2b85f3c2108f383d *shim.exe
+7f2bf0f3870ad00ec24a349e8a1643607da54a414cd0d91f0b4ba0d629e9df2a8ce5658915e4f91738e411eca99ff5625274ed3e072c661755169d7530bf3d9e *shim.exe
diff --git a/supporting/shimexe/bin/shim.exe b/supporting/shimexe/bin/shim.exe
index 19a7fa36e9bc24035835d54d3530741d6528135b..aedc51715dca73278ffab7892b346ac9852bbbda 100644
GIT binary patch
delta 3040
zcmZ8j3v3kE6}|7x%$wa=?|Ntd_{Z9g*W>jEV{GUr5WB{rw4sh;8*KV91{N?~7-!Zd
zr6la4q$xpBgF8{x(5Na^RMARFl{zX4p>3$r4@xR%rKtHd6gB-MQYsV`p}MM2&zoJ-
zkdf!Sd+xpO-TU6XZ`P$dOZ_L0H{IW~_2*Q1u2K^PST|7u3SU|INbkarwuX9piH4=3
zpXgO}p)p#ugQyBT1w)aej?$H#Jh_P+!91a_7mliD-Xh~W~sK@pr1g*pK0mvu#uh7Vqv0TSOzd4
zbO+X1D*$34Go#991u=9sSs@G#xr0h*n)0hC@Tyv=T$s#GiHqORI5N
z9+62z{S`&TZ=n(*Q=zgp9zk5SLi|~?DvQ$Lyot6jV;l2hzwDRZ=J`?Nptf`-Ge?oq
z3iYNyMMNQuuq`ENvQX4^tI6G>))dh(Mn@xeMscc1`wp;xo>(QkVr03VoUmJDx_o8Y
z&Ok6kq9-7@-3mE5xn|ivR(^a#J*1tDp#0@}DthP@h4)}}t9wR>RlB`2zU
z`Zs2Jo)uZ#fHhEMy9zijQNp39%eva^A!TLSLSfrGxsr8oA7>R0tvaP)*q
z5ZZ-sDR5(vl-nlSid70Kf=AHPd|VUsvWNS4Osl4O*|yZ@Xxui<+wzqUp
zljeD4Efzhl#*on6>RK&CpJUHsi3S7^^pYxlI=oD@X2Hk9bz-ClG9;wx0WR@%O=4W%
z4jdziJ7@xXz9u9td3ZyWa>~3y`p@J
zMd@R*`M_F~r&x^g6?RqYp*UTxuvd!W`^fhF3SFl>!&0;pABN?;SI~ZsEu@5YmaU*e
zx7m(*>>&!!i?GRRKY_h)x&&0{d9<%er-2$h?6vZ5fjYf~{_s)1&hSH3{F2JivjU$5
zP}wV#^Ok7UC@s^Fn)BlSa!GIm81y{f#d3_wc-GVW8UCDFapf3oS0w&U{u*jb-aeE8
zNusgw`GGtD3>OI>6Od!nuD1b~lrDOde!zNwuPHq^zSCkI*+MTuYL-e
zrNY;zhX#%t8LD`ek5Vy^o3)
z=`Z{c$a~@l{hlmVgnSA2cZAkLM)kE5^ai~wPGafH$}_`Hd&P3Y=1k
zgr7L&PxKxI`M;#B{ToR?p>ei^uY!*;Hi{@S)FG;wpPf!K)K1lH2KY>=Ai1E2xi<;lA$ay#8%
z?|7Pe8fJ}n6Lc0^{TsQ;LsWc?HZq+Y!Kfc09NdL|+yE8L(a(Z(#?x2Rq^CD&3S2Fr
z$hSQgP-!&Kt>;em2T#6TcMe`3^;=4zZLncX7kG8NgLDQ*w0dzWVDV259oU)My*syi
zU=E-Do%3@!8nh40&g65>rrg1tGd=fV(=Dg*!t~yp`|V&?=-%9((dj+8xx@F)=W~U{
z^TBOQ*_v|}L)A+xzGY^YV;Af_b6tb>?%cq^>HOisjH{VnufDa?*tD}ZH|L%(|L9Id
z<~RKJ`r?sQd1vTkcGvb(!E0}lnr6(Wq={(|Ow+^qh#m~#F=J*5gWnfv^Wh{S18!9`
z#m3#1XxmUuO;ZHG7{_e+`b0dko`*tOnzOo8GR%2Aavy789+I>*PykP;+NCk_pb{~%owrAweiM;(|
zJUEcg+xKso&(F=w=5tW^Hy_-Wb7oL2@-YhF|84hbEFAhmuPlD~In?XkjMeacy>3nX
Yx_hiv4w8^f6evAe*gdg
delta 2678
zcmZ8jYiwLc75--Ky|cS_AK82N8T`nu9Xr>r_|-ZHO6s<$5~mL*PEukJA)uzn31P!J
z0UM~-l$1325yiPxRf>d~hJuPBqSjzqH39`xBvK$MwEYvBrb;DLsZ~R1g^D7JZ)WX6
zx$^zyJC8Z%%$%9Ko*kaO>BK`V*IqgHV=O&a(1N(=1F}>^>&jaP=YDoi>e>J>sujb)
zAMLqvCb1hxP=1+)#;`2A!*Q|3-ISrK#5Wrr6I~)7E{HXvF}y5VN~;H{=Cg^fgoDGa
zz?Kz&pd0~IIG69MHT1c7h8q5PfdjY|MQ97?;JN`Ta^oserS(7%qY$`+L^OzV=xGU9
zk6TUB7!8PSwTn~*DbflPxrI*SsoJVH>HwUplGU4+sc$dlY8GqroyDBZv8_k7S4U{h
zs36VhI-|-&yhz|t>S^&*ouoWfy+cRQ6=jsC=&?+fJdB|DSdQ0@6lY)RqA0(L^RFNwN0
zMqn;GaKc8rSYwaGZ_P^O3^UnnJ%#oeX0{gMqObHVTDG3#E7@->XbFI%TA=v%ko39TW5eP9Itc#TelsoPJHbvlPng0<7q$0v318bY~gX|
z5k>399U~h!?xuWAgo{pl(<+Lb4emSG1~3iuP2{nG9p0ikY8NEi!AIfCGVUlmU~s*>
zV6Q+Irz+f`rYsjFb-{M=PwUf`!bV($i==gi{_lz@YFf>#VQBt>dWo2^p6A@_Qfu}L
z&8Lj#gSO`T7*pYQ_Ee3-p!GIGueUGQ3etYtPT_8`m%N#26ux0=*KU*YtUBYkxYyQr
zmFZnL@{C>|4rt(qLoX(cUDkFxXQa6BaF)6b_CATENaKe_%2Be)Y1A%J%yD0m*g89n
z5wUglB<>Un7s(Zx#3=D|w#He*UoiSV82qc$K9>x>>S+F^!7-ybZun_6M*VhZ+>J3V
z=zgW~h`}>8TMMgZP^i@B1gz9i}m(^6GT3V!|gXz8Sy
z68fWDmxk1L{zn=Y4+wn&>b6Da2zO#j38(>cIBFdi8I*X_v~*QIEV9_XBt7DEbAO&)
zlE&3zEa>GW=>z$sC}J~jBk=v=0$a8cV@8@Qp0m%2mDu$$+kHm*9^#m%O}Fde8W$sR
zk!WErJ89#yLL
zQ#fIN9{ncG)5I^5_t|@hE%rVCjWv`#3Awo{SV_j#?&!}K5qS#
z7+4EBjeMSHS?3M^J+aA}=8yZY<*RrJN%;o_qY!qd_X)fqRypFBb{kYhR4Z?!Q-VO@~Ri5o(5y43#$1r5ZIM2V+C*s*{
z`iGjI>yMrr#9s{mxNeGG|L^x9+pdqA^ZR8g<&>moEEdvI=KMXPSr~-2
zHKSSBE?r_EP#->-Z5=Ckj{u?#LoFz)0B$(Z93^hj5%`teqL(_qA8W)m(_1e
zrF8yjmg^siMwl^!j7X$~Ng6ihZfM9xmg@1KQx=OdR!pV6MA}P-`*J;TorHxjbU8eo
syDiM;oBg8xL0NhRG%wAS^K$iIxGVque5&|wM{XFL_nO}obA6Hj0G>d68vp
-
+
diff --git a/supporting/shimexe/shim.csproj b/supporting/shimexe/shim.csproj
index 3324f0bb06..3cd82cfc8c 100644
--- a/supporting/shimexe/shim.csproj
+++ b/supporting/shimexe/shim.csproj
@@ -1,7 +1,10 @@
-
-
+
+
Debug
AnyCPU
@@ -29,8 +32,12 @@
- This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
+ This project references NuGet package(s) that are missing on this computer.
+ Enable NuGet Package Restore to download them. For more information, see
+ http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
-
+
diff --git a/supporting/validator/bin/Newtonsoft.Json.Schema.dll b/supporting/validator/bin/Newtonsoft.Json.Schema.dll
index f3abd1fa42750dd602d105a4d960552877af560d..1185cf45037d5ac7b5a22ad0bc5c7d7aa7b2c470 100644
GIT binary patch
literal 261632
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