Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(scoop-status): sanitize app names, import commands if missing #6252

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0f3bb31
fix(scoop-status): do not loop through empty array; do not pass empty…
BinToss Dec 20, 2024
da4b608
refactor(core): throw if app_status' $app parameter is null, empty, o…
BinToss Dec 20, 2024
16702e3
refactor(manifest): throw ArgumentException if manifest's $app is nul…
BinToss Dec 20, 2024
8415c95
style(manifest): use PascalCase to match definitions
BinToss Dec 20, 2024
d56fc1a
fix(manifest): if `Get-UserAgent` is undefined, import it from ./down…
BinToss Dec 20, 2024
50c2b1c
refactor(manifest): do not catch errors if they will be discarded or …
BinToss Dec 20, 2024
6c07782
test(scoop-status): add minimal test suite
BinToss Dec 22, 2024
cf2494d
refactor(scoop-status): replace incorrect 'return' statements with 'c…
BinToss Jan 11, 2025
4668956
style(scoop-status): adjust guard condition operators to improve logi…
BinToss Jan 11, 2025
57c614e
refactor(scoop-status): use null-coalesce assignment to ensure an arr…
BinToss Jan 11, 2025
c0d2341
refactor(manifest): fix function-check and import expressions
BinToss Jan 11, 2025
72c49a8
fix(download): if `get_config` not in-scope, import it
BinToss Jan 11, 2025
9283b41
refactor(scoop-status): `return` must be used in `ForEach-Object` scr…
BinToss Jan 11, 2025
82d4784
refactor(scoop-status): restore Windows PowerShell 5.1 compatibility
BinToss Jan 28, 2025
37a64b6
fix(scoop-status): import lib/buckets.ps1 for Get-LocalBucket
BinToss Jan 29, 2025
4aa288e
fix(buckets): run core.ps1 for `$scoopdir`
BinToss Jan 29, 2025
ba8322c
test(scoop-status): inline a variable
BinToss Jan 29, 2025
2767d0e
test(scoop-status): replace "Import-Module" calls with dot-sourced ex…
BinToss Jan 29, 2025
5ba8f6a
test(scoop-status): remove unnecessary imports
BinToss Jan 29, 2025
9b8f01a
test(scoop-status): trim whitespace
BinToss Jan 29, 2025
f8f8ed2
test(scoop-status): add Skip condition, todo comment
BinToss Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/buckets.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Imports
. "$PSScriptRoot/core.ps1" # "$scoopdir"

$bucketsdir = "$scoopdir\buckets"

function Find-BucketDirectory {
Expand Down
3 changes: 3 additions & 0 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,9 @@ function Test-HelperInstalled {
}

function app_status($app, $global) {
if ([string]::IsNullOrWhiteSpace($app)) {
throw 'The value of $app may not be null, empty, or whitespace!'
}
$status = @{}
$status.installed = installed $app $global
$status.version = Select-CurrentVersion -AppName $app -Global:$global
Expand Down
7 changes: 5 additions & 2 deletions lib/download.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,9 @@ function Invoke-CachedAria2Download ($app, $version, $manifest, $architecture, $
warn "Download failed! (Error $lastexitcode) $(aria_exit_code $lastexitcode)"
warn $urlstxt_content
warn $aria2
warn $(new_issue_msg $app $bucket "download via aria2 failed")
warn $(new_issue_msg $app $bucket 'download via aria2 failed')

Write-Host "Fallback to default downloader ..."
Write-Host 'Fallback to default downloader ...'

try {
foreach ($url in $urls) {
Expand Down Expand Up @@ -550,6 +550,9 @@ function Get-UserAgent() {

function setup_proxy() {
# note: '@' and ':' in password must be escaped, e.g. 'p@ssword' -> p\@ssword'
if (-not (Test-Path Function:/get_config)) {
. "$PSScriptRoot/core.ps1"
}
$proxy = get_config PROXY
if (!$proxy) {
return
Expand Down
12 changes: 8 additions & 4 deletions lib/manifest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ function parse_json($path) {
function url_manifest($url) {
$str = $null
try {
if (-not (Test-Path Function:/Get-UserAgent)) {
. "$PSScriptRoot/download.ps1"
}
$wc = New-Object Net.Webclient
$wc.Headers.Add('User-Agent', (Get-UserAgent))
$data = $wc.DownloadData($url)
$str = (Get-Encoding($wc)).GetString($data)
} catch [system.management.automation.methodinvocationexception] {
warn "error: $($_.exception.innerexception.message)"
} catch {
throw
} catch [System.Management.Automation.MethodInvocationException] {
warn "error: $($_.Exception.InnerException.Message)"
}
if (!$str) { return $null }
try {
Expand Down Expand Up @@ -68,6 +69,9 @@ function Get-Manifest($app) {
}

function manifest($app, $bucket, $url) {
if ([string]::IsNullOrWhiteSpace($app)) {
throw [System.ArgumentException]::new('The value of $app may not be null, empty, or whitespace!')
}
if ($url) { return url_manifest $url }
parse_json (manifest_path $app $bucket)
}
Expand Down
18 changes: 11 additions & 7 deletions libexec/scoop-status.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

. "$PSScriptRoot\..\lib\manifest.ps1" # 'manifest' 'parse_json' "install_info"
. "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion'
. "$PSScriptRoot\..\lib\buckets.ps1" # 'Get-LocalBucket'

# check if scoop needs updating
$currentdir = versiondir 'scoop' 'current'
Expand All @@ -23,7 +24,7 @@ function Test-UpdateStatus($repopath) {
if (Test-Path "$repopath\.git") {
Invoke-Git -Path $repopath -ArgumentList @('fetch', '-q', 'origin')
$script:network_failure = 128 -eq $LASTEXITCODE
$branch = Invoke-Git -Path $repopath -ArgumentList @('branch', '--show-current')
$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 }
Expand Down Expand Up @@ -55,19 +56,22 @@ $true, $false | ForEach-Object { # local and global apps
$dir = appsdir $global
if (!(Test-Path $dir)) { return }

Get-ChildItem $dir | Where-Object name -NE 'scoop' | ForEach-Object {
$app = $_.name
$appNames = @(Get-ChildItem $dir -Directory -Name -Exclude 'scoop' | Where-Object Length -GT 0)

if ($appNames.Length -eq 0) { return }

foreach ($app in $appNames) {
$status = app_status $app $global
if (!$status.outdated -and !$status.failed -and !$status.removed -and !$status.missing_deps) { return }
if (-not ($status.outdated -or $status.failed -or $status.removed -or $status.missing_deps)) { continue }

$item = [ordered]@{}
$item.Name = $app
$item.'Installed Version' = $status.version
$item.'Latest Version' = if ($status.outdated) { $status.latest_version } else { "" }
$item.'Latest Version' = if ($status.outdated) { $status.latest_version } else { '' }
$item.'Missing Dependencies' = $status.missing_deps -Split ' ' -Join ' | '
$info = @()
if ($status.failed) { $info += 'Install failed' }
if ($status.hold) { $info += 'Held package' }
if ($status.failed) { $info += 'Install failed' }
if ($status.hold) { $info += 'Held package' }
if ($status.removed) { $info += 'Manifest removed' }
$item.Info = $info -join ', '
$list += [PSCustomObject]$item
Expand Down
33 changes: 33 additions & 0 deletions test/Scoop-Status.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# todo
Describe -Skip 'Show status and check for new app versions' -Tag 'Scoop' {
# scoop-status.ps1 is not structured in a way that makes this easy to test
# todo: refactor scoop-status.ps1's loop bodies to functions for easier testing
It 'throws when Global or User appdir is empty or does not exist' -Skip { }
}

# todo: add bucket fixtures for CI tests
Describe 'Test-UpdateStatus' -Tag 'Scoop' -Skip:($env:CI -eq $true) {
BeforeAll {
. "$PSScriptRoot/../libexec/scoop-status.ps1"
}
# todo
It -Skip 'should return $true if $commits is falsy' {}
# todo
It -Skip 'should return $false if $commits is truthy' {}
It 'should return $true if "$repopath\.git`" does not exist' {
function makeTmpDir {
[OutputType([System.IO.DirectoryInfo])]
Param ()

[string] $tmpDirPath = Join-Path $env:TEMP $(New-Guid)

while (Test-Path $tmpDirPath) {
$tmpDirPath = Join-Path $env:TEMP $(New-Guid)
}

return (New-Item $tmpDirPath -ItemType Directory)
}
[System.IO.DirectoryInfo] $emptyDir = makeTmpDir
Test-UpdateStatus $emptyDir.FullName | Should -Be $true
}
}