diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 2ab39dcf2c..eec84250f6 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -31,9 +31,9 @@ labels: "bug" ### System details -**Windows version:** [e.g. 7, 8, 10] +**Windows version:** [e.g. 7, 8, 10, 11] -**OS architecture:** [e.g. 32bit, 64bit] +**OS architecture:** [e.g. 32bit, 64bit, arm64] **PowerShell version:** [output of `"$($PSVersionTable.PSVersion)"`] diff --git a/CHANGELOG.md b/CHANGELOG.md index 064d318eba..9d068d2cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- **install:** Add support for ARM64 architecture ([#5154](https://github.com/ScoopInstaller/Scoop/issues/5154)) - **getopt:** Support option terminator (`--`) ([#5121](https://github.com/ScoopInstaller/Scoop/issues/5121)) - **scoop-(un)hold:** Support `scoop (un)hold scoop` ([#5089](https://github.com/ScoopInstaller/Scoop/issues/5089)) - **scoop-config:** Allow 'hold_update_until' be set manually ([#5100](https://github.com/ScoopInstaller/Scoop/issues/5100)) diff --git a/bin/checkhashes.ps1 b/bin/checkhashes.ps1 index 6db668a320..b92850778c 100644 --- a/bin/checkhashes.ps1 +++ b/bin/checkhashes.ps1 @@ -79,6 +79,8 @@ foreach ($single in Get-ChildItem $Dir "$App.json") { hash $manifest '64bit' | ForEach-Object { $hashes += $_ } script:url $manifest '32bit' | ForEach-Object { $urls += $_ } hash $manifest '32bit' | ForEach-Object { $hashes += $_ } + script:url $manifest 'arm64' | ForEach-Object { $urls += $_ } + hash $manifest 'arm64' | ForEach-Object { $hashes += $_ } } else { err $name 'Manifest does not contain URL property.' continue @@ -158,16 +160,20 @@ foreach ($current in $MANIFESTS) { # Defaults to zero, don't know, which architecture is available $64bit_count = 0 $32bit_count = 0 + $arm64_count = 0 + # 64bit is get, donwloaded and added first if ($platforms.Contains('64bit')) { $64bit_count = $current.manifest.architecture.'64bit'.hash.Count - # 64bit is get, donwloaded and added first $current.manifest.architecture.'64bit'.hash = $actuals[0..($64bit_count - 1)] } if ($platforms.Contains('32bit')) { $32bit_count = $current.manifest.architecture.'32bit'.hash.Count - $max = $64bit_count + $32bit_count - 1 # Edge case if manifest contains 64bit and 32bit. - $current.manifest.architecture.'32bit'.hash = $actuals[($64bit_count)..$max] + $current.manifest.architecture.'32bit'.hash = $actuals[($64bit_count)..($64bit_count + $32bit_count - 1)] + } + if ($platforms.Contains('arm64')) { + $arm64_count = $current.manifest.architecture.'arm64'.hash.Count + $current.manifest.architecture.'arm64'.hash = $actuals[($64bit_count + $32bit_count)..($64bit_count + $32bit_count + $arm64_count - 1)] } } diff --git a/bin/checkurls.ps1 b/bin/checkurls.ps1 index e4ed666dec..06672529ff 100644 --- a/bin/checkurls.ps1 +++ b/bin/checkurls.ps1 @@ -98,6 +98,7 @@ foreach ($man in $Queue) { } else { script:url $manifest '64bit' | ForEach-Object { $urls += $_ } script:url $manifest '32bit' | ForEach-Object { $urls += $_ } + script:url $manifest 'arm64' | ForEach-Object { $urls += $_ } } $urls | ForEach-Object { diff --git a/lib/autoupdate.ps1 b/lib/autoupdate.ps1 index 090505585f..d4027ac2cc 100644 --- a/lib/autoupdate.ps1 +++ b/lib/autoupdate.ps1 @@ -457,7 +457,7 @@ function Invoke-AutoUpdate { $hasNote = $true } if ($Manifest.autoupdate.architecture) { - '64bit', '32bit' | ForEach-Object { + '64bit', '32bit', 'arm64' | ForEach-Object { if ($Manifest.autoupdate.architecture.$_.note) { $note += "`n$_-arch: $($Manifest.autoupdate.architecture.$_.note)" $hasNote = $true diff --git a/lib/core.ps1 b/lib/core.ps1 index f013c0ed92..db305b5e26 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -24,7 +24,7 @@ function Get-Encoding($wc) { } function Get-UserAgent() { - return "Scoop/1.0 (+http://scoop.sh/) PowerShell/$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor) (Windows NT $([System.Environment]::OSVersion.Version.Major).$([System.Environment]::OSVersion.Version.Minor); $(if($env:PROCESSOR_ARCHITECTURE -eq 'AMD64'){'Win64; x64; '})$(if($env:PROCESSOR_ARCHITEW6432 -eq 'AMD64'){'WOW64; '})$PSEdition)" + return "Scoop/1.0 (+http://scoop.sh/) PowerShell/$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor) (Windows NT $([System.Environment]::OSVersion.Version.Major).$([System.Environment]::OSVersion.Version.Minor); $(if(${env:ProgramFiles(Arm)}){'ARM64; '}elseif($env:PROCESSOR_ARCHITECTURE -eq 'AMD64'){'Win64; x64; '})$(if($env:PROCESSOR_ARCHITEW6432 -in 'AMD64','ARM64'){'WOW64; '})$PSEdition)" } function Show-DeprecatedWarning { @@ -857,15 +857,38 @@ function ensure_in_path($dir, $global) { } } -function ensure_architecture($architecture_opt) { - if(!$architecture_opt) { - return default_architecture +function Get-DefaultArchitecture { + $arch = get_config DEFAULT_ARCHITECTURE + $system = if (${env:ProgramFiles(Arm)}) { + 'arm64' + } elseif ([System.Environment]::Is64BitOperatingSystem) { + '64bit' + } else { + '32bit' + } + if ($null -eq $arch) { + $arch = $system + } else { + try { + $arch = Format-ArchitectureString $arch + } catch { + warn 'Invalid default architecture configured. Determining default system architecture' + $arch = $system + } } - $architecture_opt = $architecture_opt.ToString().ToLower() - switch($architecture_opt) { - { @('64bit', '64', 'x64', 'amd64', 'x86_64', 'x86-64') -contains $_ } { return '64bit' } - { @('32bit', '32', 'x86', 'i386', '386', 'i686') -contains $_ } { return '32bit' } - default { throw [System.ArgumentException] "Invalid architecture: '$architecture_opt'"} + return $arch +} + +function Format-ArchitectureString($Architecture) { + if (!$Architecture) { + return Get-DefaultArchitecture + } + $Architecture = $Architecture.ToString().ToLower() + switch ($Architecture) { + { @('64bit', '64', 'x64', 'amd64', 'x86_64', 'x86-64') -contains $_ } { return '64bit' } + { @('32bit', '32', 'x86', 'i386', '386', 'i686') -contains $_ } { return '32bit' } + { @('arm64', 'arm', 'aarch64') -contains $_ } { return 'arm64' } + default { throw [System.ArgumentException] "Invalid architecture: '$Architecture'" } } } @@ -1240,5 +1263,8 @@ $globaldir = $env:SCOOP_GLOBAL, (get_config GLOBAL_PATH), "$env:ProgramData\scoo # Use at your own risk. $cachedir = $env:SCOOP_CACHE, (get_config CACHE_PATH), "$scoopdir\cache" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 +# OS information +$WindowsBuild = [System.Environment]::OSVersion.Version.Build + # Setup proxy globally setup_proxy diff --git a/lib/install.ps1 b/lib/install.ps1 index 83ba63310e..fe5a99f00d 100644 --- a/lib/install.ps1 +++ b/lib/install.ps1 @@ -25,8 +25,9 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru $check_hash = $false } - if(!(supports_architecture $manifest $architecture)) { - write-host -f DarkRed "'$app' doesn't support $architecture architecture!" + $architecture = Get-SupportedArchitecture $manifest $architecture + if ($null -eq $architecture) { + error "'$app' doesn't support current architecture!" return } @@ -1046,7 +1047,7 @@ function Invoke-HookScript { [ValidateNotNullOrEmpty()] [PSCustomObject] $Manifest, [Parameter(Mandatory = $true)] - [ValidateSet('32bit', '64bit')] + [ValidateSet('32bit', '64bit', 'arm64')] [String] $Arch ) diff --git a/lib/manifest.ps1 b/lib/manifest.ps1 index 63fa00ce08..dbbc29ce2d 100644 --- a/lib/manifest.ps1 +++ b/lib/manifest.ps1 @@ -102,23 +102,6 @@ function install_info($app, $version, $global) { parse_json $path } -function default_architecture { - $arch = get_config DEFAULT_ARCHITECTURE - $system = if ([Environment]::Is64BitOperatingSystem) { '64bit' } else { '32bit' } - if ($null -eq $arch) { - $arch = $system - } else { - try { - $arch = ensure_architecture $arch - } catch { - warn 'Invalid default architecture configured. Determining default system architecture' - $arch = $system - } - } - - return $arch -} - function arch_specific($prop, $manifest, $architecture) { if ($manifest.architecture) { $val = $manifest.architecture.$architecture.$prop @@ -128,8 +111,22 @@ function arch_specific($prop, $manifest, $architecture) { if ($manifest.$prop) { return $manifest.$prop } } -function supports_architecture($manifest, $architecture) { - return -not [String]::IsNullOrEmpty((arch_specific 'url' $manifest $architecture)) +function Get-SupportedArchitecture($manifest, $architecture) { + if ($architecture -eq 'arm64' -and ($manifest | ConvertToPrettyJson) -notmatch '[''"]arm64["'']') { + # Windows 10 enables existing unmodified x86 apps to run on Arm devices. + # Windows 11 adds the ability to run unmodified x64 Windows apps on Arm devices! + # Ref: https://learn.microsoft.com/en-us/windows/arm/overview + if ($WindowsBuild -ge 22000) { + # Windows 11 + $architecture = '64bit' + } else { + # Windows 10 + $architecture = '32bit' + } + } + if (![String]::IsNullOrEmpty((arch_specific 'url' $manifest $architecture))) { + return $architecture + } } function generate_user_manifest($app, $bucket, $version) { diff --git a/libexec/scoop-config.ps1 b/libexec/scoop-config.ps1 index a6538c4d2c..2f347b27e4 100644 --- a/libexec/scoop-config.ps1 +++ b/libexec/scoop-config.ps1 @@ -51,7 +51,7 @@ # When a conflict is detected during updating, Scoop will auto-stash the uncommitted changes. # (Default is $false, which will abort the update) # -# default_architecture: 64bit|32bit +# default_architecture: 64bit|32bit|arm64 # Allow to configure preferred architecture for application installation. # If not specified, architecture is determined be system. # diff --git a/libexec/scoop-depends.ps1 b/libexec/scoop-depends.ps1 index 33d2558089..414d1b7113 100644 --- a/libexec/scoop-depends.ps1 +++ b/libexec/scoop-depends.ps1 @@ -3,16 +3,16 @@ . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\depends.ps1" # 'Get-Dependency' -. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' +. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest' (indirectly) $opt, $apps, $err = getopt $args 'a:' 'arch=' $app = $apps[0] if(!$app) { error ' missing'; my_usage; exit 1 } -$architecture = default_architecture +$architecture = Get-DefaultArchitecture try { - $architecture = ensure_architecture ($opt.a + $opt.arch) + $architecture = Format-ArchitectureString ($opt.a + $opt.arch) } catch { abort "ERROR: $_" } diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1 index e56626f10c..66c7632c92 100644 --- a/libexec/scoop-download.ps1 +++ b/libexec/scoop-download.ps1 @@ -14,15 +14,15 @@ # scoop download path\to\app.json # # Options: -# -f, --force Force download (overwrite cache) -# -h, --no-hash-check Skip hash verification (use with caution!) -# -u, --no-update-scoop Don't update Scoop before downloading if it's outdated -# -a, --arch <32bit|64bit> Use the specified architecture, if the app supports it +# -f, --force Force download (overwrite cache) +# -h, --no-hash-check Skip hash verification (use with caution!) +# -u, --no-update-scoop Don't update Scoop before downloading if it's outdated +# -a, --arch <32bit|64bit|arm64> Use the specified architecture, if the app supports it . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\json.ps1" # 'autoupdate.ps1' (indirectly) . "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly) -. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'generate_user_manifest' 'Get-Manifest' +. "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest' . "$PSScriptRoot\..\lib\install.ps1" $opt, $apps, $err = getopt $args 'fhua:' 'force', 'no-hash-check', 'no-update-scoop', 'arch=' @@ -30,9 +30,9 @@ if ($err) { error "scoop download: $err"; exit 1 } $check_hash = !($opt.h -or $opt.'no-hash-check') $use_cache = !($opt.f -or $opt.force) -$architecture = default_architecture +$architecture = Get-DefaultArchitecture try { - $architecture = ensure_architecture ($opt.a + $opt.arch) + $architecture = Format-ArchitectureString ($opt.a + $opt.arch) } catch { abort "ERROR: $_" } @@ -89,8 +89,9 @@ foreach ($curr_app in $apps) { $curr_check_hash = $false } - if(!(supports_architecture $manifest $architecture)) { - error "'$app' doesn't support $architecture architecture!" + $architecture = Get-SupportedArchitecture $manifest $architecture + if ($null -eq $architecture) { + error "'$app' doesn't support current architecture!" continue } diff --git a/libexec/scoop-import.ps1 b/libexec/scoop-import.ps1 index b6a0ba5d6b..7e3ec1c52c 100644 --- a/libexec/scoop-import.ps1 +++ b/libexec/scoop-import.ps1 @@ -13,7 +13,7 @@ param( $import = $null $bucket_names = @() -$def_arch = default_architecture +$def_arch = Get-DefaultArchitecture if (Test-Path $scoopfile) { $import = parse_json $scoopfile @@ -40,12 +40,12 @@ foreach ($item in $import.apps) { } else { '' } - $arch = if ('64bit' -in $info -and '32bit' -eq $def_arch) { + $arch = if ('64bit' -in $info) { ' --arch 64bit' - } elseif ('32bit' -in $info -and '64bit' -eq $def_arch) { + } elseif ('32bit' -in $info) { ' --arch 32bit' } else { - '' + ' --arch arm64' } $app = if ($item.Source -in $bucket_names) { diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1 index 74f7aa931a..f4346a6025 100644 --- a/libexec/scoop-info.ps1 +++ b/libexec/scoop-info.ps1 @@ -158,7 +158,7 @@ if ($status.installed) { if ($verbose) { # Get download size if app not installed $totalPackage = 0 - foreach ($url in @(url $manifest (default_architecture))) { + foreach ($url in @(url $manifest (Get-DefaultArchitecture))) { try { if (Test-Path (fullpath (cache_path $app $manifest.version $url))) { $cached = " (latest version is cached)" diff --git a/libexec/scoop-install.ps1 b/libexec/scoop-install.ps1 index 4865ea2848..994bb5b4cf 100644 --- a/libexec/scoop-install.ps1 +++ b/libexec/scoop-install.ps1 @@ -14,17 +14,17 @@ # scoop install \path\to\app.json # # Options: -# -g, --global Install the app globally -# -i, --independent Don't install dependencies automatically -# -k, --no-cache Don't use the download cache -# -u, --no-update-scoop Don't update Scoop before installing if it's outdated -# -s, --skip Skip hash validation (use with caution!) -# -a, --arch <32bit|64bit> Use the specified architecture, if the app supports it +# -g, --global Install the app globally +# -i, --independent Don't install dependencies automatically +# -k, --no-cache Don't use the download cache +# -u, --no-update-scoop Don't update Scoop before installing if it's outdated +# -s, --skip Skip hash validation (use with caution!) +# -a, --arch <32bit|64bit|arm64> Use the specified architecture, if the app supports it . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\json.ps1" # 'autoupdate.ps1' 'manifest.ps1' (indirectly) . "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly) -. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'generate_user_manifest' 'Get-Manifest' 'Select-CurrentVersion' (indirectly) +. "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest' 'Select-CurrentVersion' (indirectly) . "$PSScriptRoot\..\lib\install.ps1" . "$PSScriptRoot\..\lib\decompress.ps1" . "$PSScriptRoot\..\lib\shortcuts.ps1" @@ -39,9 +39,9 @@ $global = $opt.g -or $opt.global $check_hash = !($opt.s -or $opt.skip) $independent = $opt.i -or $opt.independent $use_cache = !($opt.k -or $opt.'no-cache') -$architecture = default_architecture +$architecture = Get-DefaultArchitecture try { - $architecture = ensure_architecture ($opt.a + $opt.arch) + $architecture = Format-ArchitectureString ($opt.a + $opt.arch) } catch { abort "ERROR: $_" } diff --git a/libexec/scoop-list.ps1 b/libexec/scoop-list.ps1 index 0d681d36d3..da44dd1410 100644 --- a/libexec/scoop-list.ps1 +++ b/libexec/scoop-list.ps1 @@ -6,7 +6,7 @@ param($query) . "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion' . "$PSScriptRoot\..\lib\manifest.ps1" # 'parse_json' 'Select-CurrentVersion' (indirectly) -$def_arch = default_architecture +$def_arch = Get-DefaultArchitecture if (-not (Get-FormatData ScoopApps)) { Update-FormatData "$PSScriptRoot\..\supporting\formats\ScoopTypes.Format.ps1xml" } diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 003dca5979..84bd448f78 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -191,7 +191,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c $install = install_info $app $old_version $global # re-use architecture, bucket and url from first install - $architecture = ensure_architecture $install.architecture + $architecture = Format-ArchitectureString $install.architecture $bucket = $install.bucket if ($null -eq $bucket) { $bucket = 'main' diff --git a/libexec/scoop-virustotal.ps1 b/libexec/scoop-virustotal.ps1 index 112b1398be..f22bbbf1c0 100644 --- a/libexec/scoop-virustotal.ps1 +++ b/libexec/scoop-virustotal.ps1 @@ -37,7 +37,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 } -$architecture = ensure_architecture +$architecture = Format-ArchitectureString if (is_scoop_outdated) { if ($opt.u -or $opt.'no-update-scoop') { diff --git a/schema.json b/schema.json index 25720e8eb5..a9c30d3b4e 100644 --- a/schema.json +++ b/schema.json @@ -227,6 +227,9 @@ }, "64bit": { "$ref": "#/definitions/autoupdateArch" + }, + "arm64": { + "$ref": "#/definitions/autoupdateArch" } } }, @@ -530,6 +533,9 @@ }, "64bit": { "$ref": "#/definitions/architecture" + }, + "arm64": { + "$ref": "#/definitions/architecture" } }, "type": "object" @@ -649,6 +655,11 @@ "properties": { "url": false } + }, + "arm64": { + "properties": { + "url": false + } } } } diff --git a/test/Scoop-Core.Tests.ps1 b/test/Scoop-Core.Tests.ps1 index 75d6b7d7df..398cbfaad2 100644 --- a/test/Scoop-Core.Tests.ps1 +++ b/test/Scoop-Core.Tests.ps1 @@ -397,3 +397,40 @@ Describe 'app' -Tag 'Scoop' { $version | Should -Be '1.8.0-rc2' } } + +Describe 'Format Architecture String' -Tag 'Scoop' { + It 'should keep correct architectures' { + Format-ArchitectureString '32bit' | Should -Be '32bit' + Format-ArchitectureString '32' | Should -Be '32bit' + Format-ArchitectureString 'x86' | Should -Be '32bit' + Format-ArchitectureString 'X86' | Should -Be '32bit' + Format-ArchitectureString 'i386' | Should -Be '32bit' + Format-ArchitectureString '386' | Should -Be '32bit' + Format-ArchitectureString 'i686' | Should -Be '32bit' + + Format-ArchitectureString '64bit' | Should -Be '64bit' + Format-ArchitectureString '64' | Should -Be '64bit' + Format-ArchitectureString 'x64' | Should -Be '64bit' + Format-ArchitectureString 'X64' | Should -Be '64bit' + Format-ArchitectureString 'amd64' | Should -Be '64bit' + Format-ArchitectureString 'AMD64' | Should -Be '64bit' + Format-ArchitectureString 'x86_64' | Should -Be '64bit' + Format-ArchitectureString 'x86-64' | Should -Be '64bit' + + Format-ArchitectureString 'arm64' | Should -Be 'arm64' + Format-ArchitectureString 'arm' | Should -Be 'arm64' + Format-ArchitectureString 'aarch64' | Should -Be 'arm64' + Format-ArchitectureString 'ARM64' | Should -Be 'arm64' + Format-ArchitectureString 'ARM' | Should -Be 'arm64' + Format-ArchitectureString 'AARCH64' | Should -Be 'arm64' + } + + It 'should fallback to the default architecture on empty input' { + Format-ArchitectureString '' | Should -Be $(Get-DefaultArchitecture) + Format-ArchitectureString $null | Should -Be $(Get-DefaultArchitecture) + } + + It 'should show an error with an invalid architecture' { + { Format-ArchitectureString 'PPC' } | Should -Throw "Invalid architecture: 'ppc'" + } +} diff --git a/test/Scoop-Format-Manifest.Tests.ps1 b/test/Scoop-Format-Manifest.Tests.ps1 deleted file mode 100644 index 25bc9730ce..0000000000 --- a/test/Scoop-Format-Manifest.Tests.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -. "$PSScriptRoot\Scoop-TestLib.ps1" -. "$PSScriptRoot\..\lib\json.ps1" -. "$PSScriptRoot\..\lib\manifest.ps1" - -Describe 'Pretty json formating' -Tag 'Scoop' { - BeforeAll { - $format = "$PSScriptRoot\fixtures\format" - $manifests = Get-ChildItem "$format\formatted" -File -Filter '*.json' - } - - Context 'Beautify manifest' { - $manifests | ForEach-Object { - if ($PSVersionTable.PSVersion.Major -gt 5) { $_ = $_.Name } # Fix for pwsh - - It "$_" { - $pretty_json = (parse_json "$format\unformatted\$_") | ConvertToPrettyJson - $correct = (Get-Content "$format\formatted\$_") -join "`r`n" - $correct.CompareTo($pretty_json) | Should -Be 0 - } - } - } -} diff --git a/test/Scoop-Install.Tests.ps1 b/test/Scoop-Install.Tests.ps1 index 8750feb506..3559ac89e8 100644 --- a/test/Scoop-Install.Tests.ps1 +++ b/test/Scoop-Install.Tests.ps1 @@ -6,37 +6,6 @@ $isUnix = is_unix -Describe 'ensure_architecture' -Tag 'Scoop' { - It 'should keep correct architectures' { - ensure_architecture '32bit' | Should -Be '32bit' - ensure_architecture '32' | Should -Be '32bit' - ensure_architecture 'x86' | Should -Be '32bit' - ensure_architecture 'X86' | Should -Be '32bit' - ensure_architecture 'i386' | Should -Be '32bit' - ensure_architecture '386' | Should -Be '32bit' - ensure_architecture 'i686' | Should -Be '32bit' - - ensure_architecture '64bit' | Should -Be '64bit' - ensure_architecture '64' | Should -Be '64bit' - ensure_architecture 'x64' | Should -Be '64bit' - ensure_architecture 'X64' | Should -Be '64bit' - ensure_architecture 'amd64' | Should -Be '64bit' - ensure_architecture 'AMD64' | Should -Be '64bit' - ensure_architecture 'x86_64' | Should -Be '64bit' - ensure_architecture 'x86-64' | Should -Be '64bit' - } - - It 'should fallback to the default architecture on empty input' { - ensure_architecture '' | Should -Be $(default_architecture) - ensure_architecture $null | Should -Be $(default_architecture) - } - - It 'should show an error with an invalid architecture' { - { ensure_architecture 'PPC' } | Should -Throw - { ensure_architecture 'PPC' } | Should -Throw "Invalid architecture: 'ppc'" - } -} - Describe 'appname_from_url' -Tag 'Scoop' { It 'should extract the correct name' { appname_from_url 'https://example.org/directory/foobar.json' | Should -Be 'foobar' diff --git a/test/Scoop-Manifest.Tests.ps1 b/test/Scoop-Manifest.Tests.ps1 new file mode 100644 index 0000000000..02a24162ab --- /dev/null +++ b/test/Scoop-Manifest.Tests.ps1 @@ -0,0 +1,49 @@ +. "$PSScriptRoot\Scoop-TestLib.ps1" +. "$PSScriptRoot\..\lib\json.ps1" +. "$PSScriptRoot\..\lib\manifest.ps1" + +Describe 'Pretty json formating' -Tag 'Scoop' { + BeforeAll { + $format = "$PSScriptRoot\fixtures\format" + $manifests = Get-ChildItem "$format\formatted" -File -Filter '*.json' + } + + Context 'Beautify manifest' { + $manifests | ForEach-Object { + if ($PSVersionTable.PSVersion.Major -gt 5) { $_ = $_.Name } # Fix for pwsh + + It "$_" { + $pretty_json = (parse_json "$format\unformatted\$_") | ConvertToPrettyJson + $correct = (Get-Content "$format\formatted\$_") -join "`r`n" + $correct.CompareTo($pretty_json) | Should -Be 0 + } + } + } +} + +Describe 'Handle ARM64 and correctly fallback' -Tag 'Scoop' { + It 'Should return "arm64" if supported' { + $manifest1 = @{ url = 'test'; architecture = @{ 'arm64' = @{ pre_install = 'test' } } } + $manifest2 = @{ url = 'test'; pre_install = "'arm64'" } + $manifest3 = @{ architecture = @{ 'arm64' = @{ url = 'test' } } } + Get-SupportedArchitecture $manifest1 'arm64' | Should -Be 'arm64' + Get-SupportedArchitecture $manifest2 'arm64' | Should -Be 'arm64' + Get-SupportedArchitecture $manifest3 'arm64' | Should -Be 'arm64' + } + It 'Should return "64bit" if unsupported on Windows 11' { + $WindowsBuild = 22000 + $manifest1 = @{ url = 'test' } + $manifest2 = @{ architecture = @{ '64bit' = @{ url = 'test' } } } + Get-SupportedArchitecture $manifest1 'arm64' | Should -Be '64bit' + Get-SupportedArchitecture $manifest2 'arm64' | Should -Be '64bit' + } + It 'Should return "32bit" if unsupported on Windows 10' { + $WindowsBuild = 19044 + $manifest2 = @{ url = 'test' } + $manifest1 = @{ url = 'test'; architecture = @{ '64bit' = @{ pre_install = 'test' } } } + $manifest3 = @{ architecture = @{ '64bit' = @{ url = 'test' } } } + Get-SupportedArchitecture $manifest1 'arm64' | Should -Be '32bit' + Get-SupportedArchitecture $manifest2 'arm64' | Should -Be '32bit' + Get-SupportedArchitecture $manifest3 'arm64' | Should -BeNullOrEmpty + } +}