Skip to content

Commit 2739836

Browse files
authored
Merge branch 'develop' into fix/scoop-config-scoop-repo-help
2 parents 5952871 + a7a7d34 commit 2739836

38 files changed

Lines changed: 554 additions & 295 deletions

.github/workflows/ci.yml

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
1-
name: Scoop Core CI Tests
1+
name: CI
22

33
on:
44
pull_request:
55
workflow_dispatch:
66

77
jobs:
8-
test_powershell:
9-
name: WindowsPowerShell
8+
test:
9+
name: Test
1010
runs-on: windows-latest
11+
strategy:
12+
matrix:
13+
shell: [powershell, pwsh]
14+
defaults:
15+
run:
16+
shell: ${{ matrix.shell }}
1117
steps:
1218
- name: Checkout
13-
uses: actions/checkout@main
19+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
1420
with:
21+
# Need at least 2 commits to properly gather changed files for linting
1522
fetch-depth: 2
16-
- name: Init Test Suite
17-
uses: potatoqualitee/psmodulecache@main
23+
- name: Install and cache test dependencies
24+
uses: potatoqualitee/psmodulecache@ee5e9494714abf56f6efbfa51527b2aec5c761b8 # v6.2.1
1825
with:
19-
modules-to-cache: BuildHelpers
20-
shell: powershell
21-
- name: Test Scoop Core
22-
shell: powershell
23-
run: ./test/bin/test.ps1
24-
test_pwsh:
25-
name: PowerShell
26-
runs-on: windows-latest
27-
steps:
28-
- name: Checkout
29-
uses: actions/checkout@main
30-
with:
31-
fetch-depth: 2
32-
- name: Init Test Suite
33-
uses: potatoqualitee/psmodulecache@main
34-
with:
35-
modules-to-cache: BuildHelpers
36-
shell: pwsh
37-
- name: Test Scoop Core
38-
shell: pwsh
26+
modules-to-cache: PSScriptAnalyzer, BuildHelpers, Pester
27+
shell: ${{ matrix.shell }}
28+
- name: Run tests
3929
run: ./test/bin/test.ps1

CHANGELOG.md

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,68 @@
1+
## [Unreleased](https://github.com/ScoopInstaller/Scoop/compare/v0.5.3...develop)
2+
3+
### Features
4+
5+
- **install:** Add output for the setting and removal of environment variables ([#6460](https://github.com/ScoopInstaller/Scoop/issues/6460))
6+
- **scoop-uninstall:** Allow access to `$bucket` in uninstall scripts ([#6380](https://github.com/ScoopInstaller/Scoop/issues/6380))
7+
- **install:** Add separator at the end of notes, highlight suggestions ([#6418](https://github.com/ScoopInstaller/Scoop/issues/6418))
8+
- **download|scoop-download:** Add GitHub issue prompt when the default downloader fails ([#6539](https://github.com/ScoopInstaller/Scoop/issues/6539))
9+
- **download|scoop-config:** Allow disabling automatic fallback to the default downloader when Aria2c download fails ([#6538](https://github.com/ScoopInstaller/Scoop/issues/6538))
10+
11+
### Bug Fixes
12+
13+
- **core:** Fix the grep parameter in the `Invoke-GitLog` function ([#6407](https://github.com/ScoopInstaller/Scoop/issues/6407))
14+
- **buckets:** Skip Git invocation if unavailable in `new_issue_msg` ([#6591](https://github.com/ScoopInstaller/Scoop/issues/6591))
15+
- **buckets:** Fix the filtering condition when retrieving the number of manifests ([#6509](https://github.com/ScoopInstaller/Scoop/issues/6509))
16+
- **scoop-download:** Fix function `nightly_version` not defined error ([#6386](https://github.com/ScoopInstaller/Scoop/issues/6386))
17+
- **scoop-download:** Fix incorrect download success state ([#6473](https://github.com/ScoopInstaller/Scoop/issues/6473))
18+
- **scoop-uninstall:** Correct `-Global` Switch ([#6454](https://github.com/ScoopInstaller/Scoop/issues/6454))
19+
- **scoop-update:** Force sync tags w/ remote branch while scoop update ([#6439](https://github.com/ScoopInstaller/Scoop/issues/6439))
20+
- **autoupdate:** Use origin URL to handle URLs with fragment in GitHub mode ([#6455](https://github.com/ScoopInstaller/Scoop/issues/6455))
21+
- **autoupdate:** Ensure GitHub API requests use token ([#6535](https://github.com/ScoopInstaller/Scoop/issues/6535))
22+
- **buckets|scoop-info:** Switch git log date format to ISO 8601 to avoid locale issues ([#6446](https://github.com/ScoopInstaller/Scoop/issues/6446))
23+
- **scoop-version:** Fix logic error caused by missing brackets ([#6463](https://github.com/ScoopInstaller/Scoop/issues/6463))
24+
- **getopt:** Teach getopt to respect the `--%` token ([#6477](https://github.com/ScoopInstaller/Scoop/issues/6477))
25+
- **core|manifest:** Avoid error messages when searching non-existent 'deprecated' directory ([#6471](https://github.com/ScoopInstaller/Scoop/issues/6471))
26+
- **path:** Trim ending slash when initializing paths ([#6501](https://github.com/ScoopInstaller/Scoop/issues/6501))
27+
- **checkver:** Allow script to run when URL fetch fails but script exists ([#6490](https://github.com/ScoopInstaller/Scoop/issues/6490), [#6556](https://github.com/ScoopInstaller/Scoop/issues/6556))
28+
- **install:** Don't add to `$Error` when checking for service `cexecsvc` ([#6520](https://github.com/ScoopInstaller/Scoop/issues/6520))
29+
- **checkver:** Fix incorrect version returned when script fails without output ([#6547](https://github.com/ScoopInstaller/Scoop/issues/6547))
30+
- **uninstall:** Import `url_filename` from `download.ps1` ([#6530](https://github.com/ScoopInstaller/Scoop/issues/6530))
31+
- **schema:** Add missing `hash.mode` value `github` ([#6533](https://github.com/ScoopInstaller/Scoop/issues/6533))
32+
- **core:** Skip NO_JUNCTION logic when $app is 'scoop' in `currentdir` function ([#6541](https://github.com/ScoopInstaller/Scoop/issues/6541))
33+
- **core:** Fix substitute handling of substring keys ([#6561](https://github.com/ScoopInstaller/Scoop/issues/6561))
34+
- **core:** Check `$deprecated_dir` exists before accessing it ([#6574](https://github.com/ScoopInstaller/Scoop/issues/6574))
35+
- **checkver:** Remove redundant always-true condition in GitHub checkver logic ([#6571](https://github.com/ScoopInstaller/Scoop/issues/6571))
36+
- **core:** Give `dark` higher priority when use `Extract-DarkArchive` ([#6637](https://github.com/ScoopInstaller/Scoop/issues/6637))
37+
- **checkver:** Harden github checkver ([#6641](https://github.com/ScoopInstaller/Scoop/issues/6641))
38+
- **scoop-search:** Select latest search result semantically ([#6643](https://github.com/ScoopInstaller/Scoop/issues/6643))
39+
40+
### Code Refactoring
41+
42+
- **output:** Replace raw prints with functions for standardized output ([#6449](https://github.com/ScoopInstaller/Scoop/issues/6449))
43+
- **output:** Combine the separated outputs into a single output ([#6545](https://github.com/ScoopInstaller/Scoop/issues/6545))
44+
- **scoop-list:** Use simpler method to check the deprecated status of the manifest to improve performance ([#6599](https://github.com/ScoopInstaller/Scoop/issues/6599))
45+
46+
### Builds
47+
48+
- **supporting:** Update System.Data.SQLite to 2.0.2 ([#6555](https://github.com/ScoopInstaller/Scoop/issues/6555), [#6560](https://github.com/ScoopInstaller/Scoop/issues/6560))
49+
50+
### Continuous Integration
51+
52+
- **workflow:** Drop Appveyor support and refactor GitHub Actions workflow ([#6626](https://github.com/ScoopInstaller/Scoop/issues/6626))
53+
154
## [v0.5.3](https://github.com/ScoopInstaller/Scoop/compare/v0.5.2...v0.5.3) - 2025-08-11
255

356
### Features
457

5-
**autoupdate:** GitHub predefined hashes support ([#6416](https://github.com/ScoopInstaller/Scoop/issues/6416), [#6435](https://github.com/ScoopInstaller/Scoop/issues/6435))
58+
- **autoupdate:** GitHub predefined hashes support ([#6416](https://github.com/ScoopInstaller/Scoop/issues/6416), [#6435](https://github.com/ScoopInstaller/Scoop/issues/6435))
659

760
### Bug Fixes
861

962
- **scoop-download|install|update:** Fallback to default downloader when aria2 fails ([#4292](https://github.com/ScoopInstaller/Scoop/issues/4292))
10-
- **decompress**: `Expand-7zipArchive` only delete temp dir / `$extractDir` if it is empty ([#6092](https://github.com/ScoopInstaller/Scoop/issues/6092))
11-
- **decompress**: Replace deprecated 7ZIPEXTRACT_USE_EXTERNAL config with USE_EXTERNAL_7ZIP ([#6327](https://github.com/ScoopInstaller/Scoop/issues/6327))
12-
- **commands**: Handling broken aliases ([#6141](https://github.com/ScoopInstaller/Scoop/issues/6141))
63+
- **decompress:** `Expand-7zipArchive` only delete temp dir / `$extractDir` if it is empty ([#6092](https://github.com/ScoopInstaller/Scoop/issues/6092))
64+
- **decompress:** Replace deprecated 7ZIPEXTRACT_USE_EXTERNAL config with USE_EXTERNAL_7ZIP ([#6327](https://github.com/ScoopInstaller/Scoop/issues/6327))
65+
- **commands:** Handling broken aliases ([#6141](https://github.com/ScoopInstaller/Scoop/issues/6141))
1366
- **shim:** Do not suppress `stderr`, properly check `wslpath`/`cygpath` command first ([#6114](https://github.com/ScoopInstaller/Scoop/issues/6114))
1467
- **scoop-bucket:** Add missing import for `no_junction` envs ([#6181](https://github.com/ScoopInstaller/Scoop/issues/6181))
1568
- **scoop-uninstall:** Fix uninstaller does not gain Global state ([#6430](https://github.com/ScoopInstaller/Scoop/issues/6430))

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
<a href="https://discord.gg/s9yRQHt">
2525
<img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
2626
</a>
27-
<a href="https://gitter.im/lukesampson/scoop">
28-
<img src="https://badges.gitter.im/lukesampson/scoop.png" alt="Gitter Chat" />
29-
</a>
3027
<a href="./LICENSE">
3128
<img src="https://img.shields.io/badge/license-UNLICENSE%20or%20MIT-blue" alt="License" />
3229
</a>

appveyor.yml

Lines changed: 0 additions & 35 deletions
This file was deleted.

bin/checkver.ps1

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ Get-Event | Remove-Event
108108
Get-EventSubscriber | Unregister-Event
109109

110110
# start all downloads
111+
$in_progress = 0
111112
$Queue | ForEach-Object {
112113
$name, $json, $file = $_
113114

@@ -119,7 +120,6 @@ $Queue | ForEach-Object {
119120
} else {
120121
$wc.Headers.Add('User-Agent', (Get-UserAgent))
121122
}
122-
Register-ObjectEvent $wc downloadDataCompleted -ErrorAction Stop | Out-Null
123123

124124
# Not Specified
125125
if ($json.checkver.url) {
@@ -139,27 +139,46 @@ $Queue | ForEach-Object {
139139
$jsonpath = ''
140140
$xpath = ''
141141
$replace = ''
142-
$useGithubAPI = $false
143142

144-
# GitHub
145-
if ($regex) {
146-
$githubRegex = $regex
147-
} else {
148-
$githubRegex = '/releases/tag/(?:v|V)?([\d.]+)'
149-
}
150-
if ($json.checkver -eq 'github') {
151-
if (!$json.homepage.StartsWith('https://github.com/')) {
152-
error "$name checkver expects the homepage to be a github repository"
143+
## GitHub
144+
#
145+
# ```json
146+
# "homepage": "<valid-repository-url>",
147+
# "checkver": "github"
148+
# ```
149+
#
150+
# or
151+
#
152+
# ```json
153+
# "checkver": {
154+
# "github": "<valid-repository-url-or-repository-api-url>"
155+
# }
156+
# ```
157+
if (($json.checkver -eq 'github') -or $json.checkver.github) {
158+
$githubUrlPattern = '^https://((www\.)?github\.com/[\w.-]+/[\w.-]+/?|api\.github\.com/repos/[\w.-]+/[\w.-]+/.+)$'
159+
$regex = if ($regex) { $regex } else { '/releases/tag/(?:v|V)?([\d.]+)' }
160+
161+
$inputGithubUrl = $json.homepage
162+
$fieldUsed = 'homepage'
163+
if ($json.checkver.github) {
164+
$inputGithubUrl = $json.checkver.github
165+
$fieldUsed = 'checkver.github'
166+
}
167+
168+
if ($inputGithubUrl -notmatch $githubUrlPattern) {
169+
error "$name checkver expects $fieldUsed to be a valid GitHub repository URL"
170+
return
153171
}
154-
$url = $json.homepage.TrimEnd('/') + '/releases/latest'
155-
$regex = $githubRegex
156-
$useGithubAPI = $true
157-
}
158172

159-
if ($json.checkver.github) {
160-
$url = $json.checkver.github.TrimEnd('/') + '/releases/latest'
161-
$regex = $githubRegex
162-
if ($json.checkver.PSObject.Properties.Count -eq 1) { $useGithubAPI = $true }
173+
$url = $inputGithubUrl.TrimEnd('/')
174+
if ($url -notlike 'https://api.github.com*') {
175+
$url = $url + '/releases/latest'
176+
}
177+
178+
if ($GitHubToken) {
179+
$url = $url -replace '//(www\.)?github\.com/', '//api.github.com/repos/'
180+
$wc.Headers.Add('Authorization', "token $GitHubToken")
181+
}
163182
}
164183

165184
# SourceForge
@@ -216,13 +235,6 @@ $Queue | ForEach-Object {
216235

217236
$reverse = $json.checkver.reverse -and $json.checkver.reverse -eq 'true'
218237

219-
if ($url -like '*api.github.com/*') { $useGithubAPI = $true }
220-
221-
if ($useGithubAPI -and ($null -ne $GitHubToken)) {
222-
$url = $url -replace '//(www\.)?github.com/', '//api.github.com/repos/'
223-
$wc.Headers.Add('Authorization', "token $GitHubToken")
224-
}
225-
226238
$url = substitute $url $substitutions
227239

228240
$state = New-Object psobject @{
@@ -244,7 +256,9 @@ $Queue | ForEach-Object {
244256
}
245257

246258
$wc.Headers.Add('Referer', (strip_filename $url))
259+
Register-ObjectEvent $wc downloadDataCompleted -ErrorAction Stop | Out-Null
247260
$wc.DownloadDataAsync($url, $state)
261+
$in_progress++
248262
}
249263

250264
function next($er) {
@@ -253,7 +267,6 @@ function next($er) {
253267
}
254268

255269
# wait for all to complete
256-
$in_progress = $Queue.length
257270
while ($in_progress -gt 0) {
258271
$ev = Wait-Event
259272
Remove-Event $ev.SourceIdentifier
@@ -274,18 +287,28 @@ while ($in_progress -gt 0) {
274287
$expected_ver = $json.version
275288
$ver = $Version
276289

290+
$matchesHashtable = @{}
291+
277292
if (!$ver) {
278293
if (!$regexp -and $replace) {
279294
next "'replace' requires 're' or 'regex'"
280295
continue
281296
}
282297
$err = $ev.SourceEventArgs.Error
283298
if ($err) {
284-
next "$($err.message)`r`nURL $url is not valid"
285-
continue
299+
if (!$script) {
300+
next "$($err.message)`r`nURL $url is not valid"
301+
continue
302+
} else {
303+
# Run script despite URL download failure
304+
Write-Host "$($err.message)`r`nURL $url is not valid. Falling back to checkver.script ..."
305+
}
286306
}
287307

288-
if ($url) {
308+
$page = $null
309+
$source = $url
310+
311+
if ($url -and !$err) {
289312
$ms = New-Object System.IO.MemoryStream
290313
$ms.Write($result, 0, $result.Length)
291314
$ms.Seek(0, 0) | Out-Null
@@ -294,12 +317,17 @@ while ($in_progress -gt 0) {
294317
}
295318
$page = (New-Object System.IO.StreamReader($ms, (Get-Encoding $wc))).ReadToEnd()
296319
}
297-
$source = $url
320+
298321
if ($script) {
299322
$page = Invoke-Command ([scriptblock]::Create($script -join "`r`n"))
300323
$source = 'the output of script'
301324
}
302325

326+
if ($null -eq $page) {
327+
next "couldn't retrieve content from $source"
328+
continue
329+
}
330+
303331
if ($jsonpath) {
304332
# Return only a single value if regex is absent
305333
$noregex = [String]::IsNullOrEmpty($regexp)
@@ -358,7 +386,6 @@ while ($in_progress -gt 0) {
358386
}
359387

360388
if ($match -and $match.Success) {
361-
$matchesHashtable = @{}
362389
$re.GetGroupNames() | ForEach-Object { $matchesHashtable.Add($_, $match.Groups[$_].Value) }
363390
$ver = $matchesHashtable['1']
364391
if ($replace) {

bin/scoop.ps1

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ switch ($subCommand) {
2020
}
2121
({ $subCommand -in @('-v', '--version') }) {
2222
Write-Host 'Current Scoop version:'
23-
if (Test-GitAvailable -and (Test-Path "$PSScriptRoot\..\.git") -and (get_config SCOOP_BRANCH 'master') -ne 'master') {
24-
Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('log', 'HEAD', '-1', '--oneline')
23+
if ((Test-GitAvailable) -and (Test-Path "$PSScriptRoot\..\.git") -and ((get_config SCOOP_BRANCH 'master') -ne 'master')) {
24+
Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
2525
} else {
2626
$version = Select-String -Pattern '^## \[(v[\d.]+)\].*?([\d-]+)$' -Path "$PSScriptRoot\..\CHANGELOG.md"
2727
Write-Host $version.Matches.Groups[1].Value -ForegroundColor Cyan -NoNewline
@@ -31,9 +31,9 @@ switch ($subCommand) {
3131

3232
Get-LocalBucket | ForEach-Object {
3333
$bucketLoc = Find-BucketDirectory $_ -Root
34-
if (Test-GitAvailable -and (Test-Path "$bucketLoc\.git")) {
34+
if ((Test-GitAvailable) -and (Test-Path "$bucketLoc\.git")) {
3535
Write-Host "'$_' bucket:"
36-
Invoke-Git -Path $bucketLoc -ArgumentList @('log', 'HEAD', '-1', '--oneline')
36+
Invoke-Git -Path $bucketLoc -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
3737
Write-Host ''
3838
}
3939
}

bin/uninstall.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function do_uninstall($app, $global) {
4242
$architecture = $install.architecture
4343

4444
Write-Output "Uninstalling '$app'"
45-
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -Uninstall
45+
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -Global:$global -Uninstall
4646
rm_shims $app $manifest $global $architecture
4747

4848
# If a junction was used during install, that will have been used

0 commit comments

Comments
 (0)