diff --git a/CHANGELOG.md b/CHANGELOG.md index df6f77ce19..17116dee81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ +## [v0.2.3](https://github.com/ScoopInstaller/Scoop/compare/v0.2.2...v0.2.3) - 2022-07-07 + +### Features + +- **chore:** Add missing -a/--all param to all commands ([#5004](https://github.com/ScoopInstaller/Scoop/issues/5004)) +- **scoop-status:** Check bucket status, improve output ([#5011](https://github.com/ScoopInstaller/Scoop/issues/5011)) +- **scoop-info:** Show app installed/download size ([#4886](https://github.com/ScoopInstaller/Scoop/issues/4886)) +- **scoop-import:** Import a Scoop installation from JSON ([#5014](https://github.com/ScoopInstaller/Scoop/issues/5014), [#5034](https://github.com/ScoopInstaller/Scoop/issues/5034)) + +### Bug Fixes + +- **chore:** Update help documentation ([#5002](https://github.com/ScoopInstaller/Scoop/issues/5002), [#5029](https://github.com/ScoopInstaller/Scoop/issues/5029)) +- **decompress:** Handle split RAR archives ([#4994](https://github.com/ScoopInstaller/Scoop/issues/4994)) +- **shortcuts:** Fix network drive shortcut creation ([#4410](https://github.com/ScoopInstaller/Scoop/issues/4410), [#5006](https://github.com/ScoopInstaller/Scoop/issues/5006)) + +### Code Refactoring + +- **scoop-search:** Output PSObject, use API token ([#4997](https://github.com/ScoopInstaller/Scoop/issues/4997)) + +### Builds + +- **checkver,auto-pr:** Allow passing file path ([#5019](https://github.com/ScoopInstaller/Scoop/issues/5019)) +- **checkver:** Exit routine earlier if error ([#5025](https://github.com/ScoopInstaller/Scoop/issues/5025)) +- **json:** Update Newton.Json to 13.0.1 ([#5026](https://github.com/ScoopInstaller/Scoop/issues/5026)) + +### Tests + +- **typo:** Fix typo ('formated' -> 'formatted') ([#4217](https://github.com/ScoopInstaller/Scoop/issues/4217)) + ## [v0.2.2](https://github.com/ScoopInstaller/Scoop/compare/v0.2.1...v0.2.2) - 2022-06-21 ### Features diff --git a/bin/auto-pr.ps1 b/bin/auto-pr.ps1 index 147f635bfe..b44f760c4d 100644 --- a/bin/auto-pr.ps1 +++ b/bin/auto-pr.ps1 @@ -43,7 +43,6 @@ param( [String] $Upstream, [String] $OriginBranch = 'master', [String] $App = '*', - [Parameter(Mandatory = $true)] [ValidateScript( { if (!(Test-Path $_ -Type Container)) { throw "$_ is not a directory!" @@ -64,7 +63,13 @@ param( . "$PSScriptRoot\..\lib\json.ps1" . "$PSScriptRoot\..\lib\unix.ps1" -$Dir = Resolve-Path $Dir +if ($App -ne '*' -and (Test-Path $App -PathType Leaf)) { + $Dir = Split-Path $App +} elseif ($Dir) { + $Dir = Resolve-Path $Dir +} else { + throw "'-Dir' parameter required if '-App' is not a filepath!" +} if ((!$Push -and !$Request) -or $Help) { Write-Host @' diff --git a/bin/checkver.ps1 b/bin/checkver.ps1 index b477afc2d6..1b2fb2033e 100644 --- a/bin/checkver.ps1 +++ b/bin/checkver.ps1 @@ -52,7 +52,6 @@ #> param( [String] $App = '*', - [Parameter(Mandatory = $true)] [ValidateScript( { if (!(Test-Path $_ -Type Container)) { throw "$_ is not a directory!" @@ -77,8 +76,16 @@ param( . "$PSScriptRoot\..\lib\install.ps1" # needed for hash generation . "$PSScriptRoot\..\lib\unix.ps1" -$Dir = Resolve-Path $Dir -$Search = $App +if ($App -ne '*' -and (Test-Path $App -PathType Leaf)) { + $Dir = Split-Path $App + $files = Get-ChildItem $Dir (Split-Path $App -Leaf) +} elseif ($Dir) { + $Dir = Resolve-Path $Dir + $files = Get-ChildItem $Dir "$App.json" +} else { + throw "'-Dir' parameter required if '-App' is not a filepath!" +} + $GitHubToken = Get-GitHubToken # don't use $Version with $App = '*' @@ -89,7 +96,7 @@ if ($App -eq '*' -and $Version -ne '') { # get apps to check $Queue = @() $json = '' -Get-ChildItem $Dir "$App.json" | ForEach-Object { +$files | ForEach-Object { $json = parse_json "$Dir\$($_.Name)" if ($json.checkver) { $Queue += , @($_.Name, $json) @@ -97,9 +104,8 @@ Get-ChildItem $Dir "$App.json" | ForEach-Object { } # clear any existing events -Get-Event | ForEach-Object { - Remove-Event $_.SourceIdentifier -} +Get-Event | Remove-Event +Get-EventSubscriber | Unregister-Event # start all downloads $Queue | ForEach-Object { @@ -218,20 +224,20 @@ while ($in_progress -gt 0) { $ver = $Version if (!$ver) { - $page = (Get-Encoding($wc)).GetString($ev.SourceEventArgs.Result) - $err = $ev.SourceEventArgs.Error - if ($json.checkver.script) { - $page = Invoke-Command ([scriptblock]::Create($json.checkver.script -join "`r`n")) + if (!$regex -and $replace) { + next "'replace' requires 're' or 'regex'" + continue } - + $err = $ev.SourceEventArgs.Error if ($err) { next "$($err.message)`r`nURL $url is not valid" continue } - if (!$regex -and $replace) { - next "'replace' requires 're' or 'regex'" - continue + if ($json.checkver.script) { + $page = Invoke-Command ([scriptblock]::Create($json.checkver.script -join "`r`n")) + } else { + $page = (Get-Encoding($wc)).GetString($ev.SourceEventArgs.Result) } if ($jsonpath) { diff --git a/bin/scoop.ps1 b/bin/scoop.ps1 index b7a29c1c53..6d96c68b2f 100644 --- a/bin/scoop.ps1 +++ b/bin/scoop.ps1 @@ -47,7 +47,7 @@ switch ($subCommand) { } } default { - "scoop: '$subCommand' isn't a scoop command. See 'scoop help'." + warn "scoop: '$subCommand' isn't a scoop command. See 'scoop help'." exit 1 } } diff --git a/lib/buckets.ps1 b/lib/buckets.ps1 index fa3fc8d6c5..c22c291220 100644 --- a/lib/buckets.ps1 +++ b/lib/buckets.ps1 @@ -120,7 +120,7 @@ function add_bucket($name, $repo) { $dir = Find-BucketDirectory $name -Root if (Test-Path $dir) { - warn "The '$name' bucket already exists. Use 'scoop bucket rm $name' to remove it." + warn "The '$name' bucket already exists. To add this bucket again, first remove it by running 'scoop bucket rm $name'." return 2 } diff --git a/lib/decompress.ps1 b/lib/decompress.ps1 index 3c4f3a9ffb..e7bcfea6cf 100644 --- a/lib/decompress.ps1 +++ b/lib/decompress.ps1 @@ -67,6 +67,9 @@ function Expand-7zipArchive { if (($Path -replace '.*\.([^\.]*)$', '$1') -eq '001') { # Remove splited 7-zip archive parts Get-ChildItem "$($Path -replace '\.[^\.]*$', '').???" | Remove-Item -Force + } elseif (($Path -replace '.*\.part(\d+)\.rar$', '$1')[-1] -eq '1') { + # Remove splitted RAR archive parts + Get-ChildItem "$($Path -replace '\.part(\d+)\.rar$', '').part*.rar" | Remove-Item -Force } else { Remove-Item $Path -Force } diff --git a/lib/manifest.ps1 b/lib/manifest.ps1 index ffa76c7504..4a226f7c0a 100644 --- a/lib/manifest.ps1 +++ b/lib/manifest.ps1 @@ -3,8 +3,12 @@ function manifest_path($app, $bucket) { } function parse_json($path) { - if(!(test-path $path)) { return $null } - Get-Content $path -raw -Encoding UTF8 | convertfrom-json -ea stop + if (!(Test-Path $path)) { return $null } + try { + Get-Content $path -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop + } catch { + warn "Error parsing JSON at $path." + } } function url_manifest($url) { @@ -20,7 +24,11 @@ function url_manifest($url) { throw } if(!$str) { return $null } - $str | convertfrom-json + try { + $str | ConvertFrom-Json -ErrorAction Stop + } catch { + warn "Error parsing JSON at $url." + } } function Get-Manifest($app) { diff --git a/lib/shortcuts.ps1 b/lib/shortcuts.ps1 index 819a4ebd3c..e8ddec26bb 100644 --- a/lib/shortcuts.ps1 +++ b/lib/shortcuts.ps1 @@ -20,11 +20,12 @@ function create_startmenu_shortcuts($manifest, $dir, $global, $arch) { } function shortcut_folder($global) { - $directory = [System.IO.Path]::Combine([Environment]::GetFolderPath('startmenu'), 'Programs', 'Scoop Apps') - if($global) { - $directory = [System.IO.Path]::Combine([Environment]::GetFolderPath('commonstartmenu'), 'Programs', 'Scoop Apps') + if ($global) { + $startmenu = 'CommonStartMenu' + } else { + $startmenu = 'StartMenu' } - return $(ensure $directory) + return Convert-Path (ensure ([System.IO.Path]::Combine([Environment]::GetFolderPath($startmenu), 'Programs', 'Scoop Apps'))) } function startmenu_shortcut([System.IO.FileInfo] $target, $shortcutName, $arguments, [System.IO.FileInfo]$icon, $global) { @@ -67,18 +68,5 @@ function rm_startmenu_shortcuts($manifest, $global, $arch) { if(Test-Path -Path $shortcut) { Remove-Item $shortcut } - # Before issue 1514 Startmenu shortcut removal - # - # Shortcuts that should have been installed globally would - # have been installed locally up until 27 June 2017. - # - # TODO: Remove this 'if' block and comment after - # 27 June 2018. - if($global) { - $shortcut = "$(shortcut_folder $false)\$name.lnk" - if(Test-Path -Path $shortcut) { - Remove-Item $shortcut - } - } } } diff --git a/libexec/scoop-alias.ps1 b/libexec/scoop-alias.ps1 index e226548d50..d60884c351 100644 --- a/libexec/scoop-alias.ps1 +++ b/libexec/scoop-alias.ps1 @@ -52,10 +52,10 @@ function add_alias($name, $command) { # generate script $shimdir = shimdir $false $script = - @" -# Summary: $description -$command -"@ + @( + "# Summary: $description", + "$command" + ) -join "`r`n" $script | Out-UTF8File "$shimdir\$alias_file.ps1" # add alias to config diff --git a/libexec/scoop-cache.ps1 b/libexec/scoop-cache.ps1 index 96cd23763c..959c73fcde 100644 --- a/libexec/scoop-cache.ps1 +++ b/libexec/scoop-cache.ps1 @@ -10,6 +10,8 @@ # # To clear everything in your cache, use: # scoop cache rm * +# You can also use the `-a/--all` switch in place of `*` here + param($cmd) function cacheinfo($file) { @@ -36,7 +38,7 @@ function cacheremove($app) { 'ERROR: missing' my_usage exit 1 - } elseif ($app -eq '*') { + } elseif ($app -eq '*' -or $app -eq '-a' -or $app -eq '--all') { $files = @(Get-ChildItem $cachedir) } else { $app = '(' + ($app -join '|') + ')' diff --git a/libexec/scoop-depends.ps1 b/libexec/scoop-depends.ps1 index e6b501b468..33d2558089 100644 --- a/libexec/scoop-depends.ps1 +++ b/libexec/scoop-depends.ps1 @@ -1,5 +1,5 @@ # Usage: scoop depends -# Summary: List dependencies for an app +# Summary: List dependencies for an app, in the order they'll be installed . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\depends.ps1" # 'Get-Dependency' @@ -17,9 +17,12 @@ try { abort "ERROR: $_" } -$deps = @(Get-Dependency $app $architecture) -ne $app -if($deps) { - $deps[($deps.length - 1)..0] +$deps = @() +Get-Dependency $app $architecture | ForEach-Object { + $dep = [ordered]@{} + $dep.Source, $dep.Name = $_ -split '/' + $deps += [PSCustomObject]$dep } +$deps exit 0 diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1 index 846750eb97..05ba2fa052 100644 --- a/libexec/scoop-download.ps1 +++ b/libexec/scoop-download.ps1 @@ -3,6 +3,10 @@ # Help: e.g. The usual way to download an app, without installing it (uses your local 'buckets'): # scoop download git # +# To download a different version of the app +# (note that this will auto-generate the manifest using current version): +# scoop download gh@2.7.0 +# # To download an app from a manifest at a URL: # scoop download https://raw.githubusercontent.com/ScoopInstaller/Main/master/bucket/runat.json # diff --git a/libexec/scoop-export.ps1 b/libexec/scoop-export.ps1 index 78410dab73..5975e7eb7a 100644 --- a/libexec/scoop-export.ps1 +++ b/libexec/scoop-export.ps1 @@ -1,57 +1,23 @@ -# Usage: scoop export > filename -# Summary: Exports (an importable) list of installed apps -# Help: Lists all installed apps. +# Usage: scoop export > scoopfile.json +# Summary: Exports installed apps, buckets (and optionally configs) in JSON format +# Help: Options: +# -c, --config Export the Scoop configuration file too -. "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion' -. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'Select-CurrentVersion' (indirectly) +. "$PSScriptRoot\..\lib\json.ps1" # 'ConvertToPrettyJson' -$def_arch = default_architecture +$export = @{} -$local = installed_apps $false | ForEach-Object { @{ name = $_; global = $false } } -$global = installed_apps $true | ForEach-Object { @{ name = $_; global = $true } } - -$apps = @($local) + @($global) -$count = 0 - -# json -# echo "{[" - -if($apps) { - $apps | Sort-Object { $_.name } | Where-Object { !$query -or ($_.name -match $query) } | ForEach-Object { - $app = $_.name - $global = $_.global - $ver = Select-CurrentVersion -AppName $app -Global:$global - $global_display = $null; if($global) { $global_display = ' *global*'} - - $install_info = install_info $app $ver $global - $bucket = '' - if ($install_info.bucket) { - $bucket = ' [' + $install_info.bucket + ']' - } elseif ($install_info.url) { - $bucket = ' [' + $install_info.url + ']' - } - if ($install_info.architecture -and $def_arch -ne $install_info.architecture) { - $arch = ' {' + $install_info.architecture + '}' - } else { - $arch = '' - } - - # json - # $val = "{ 'name': '$app', 'version': '$ver', 'global': $($global.toString().tolower()) }" - # if($count -gt 0) { - # " ," + $val - # } else { - # " " + $val - # } - - # "$app (v:$ver) global:$($global.toString().tolower())" - "$app (v:$ver)$global_display$bucket$arch" - - $count++ +if ($args[0] -eq '-c' -or $args[0] -eq '--config') { + $export.config = $scoopConfig + # Remove machine-specific properties + foreach ($prop in 'lastUpdate', 'rootPath', 'globalPath', 'cachePath', 'alias') { + $export.config.PSObject.Properties.Remove($prop) } } -# json -# echo "]}" +$export.buckets = list_buckets +$export.apps = @(& "$PSScriptRoot\scoop-list.ps1" 6>$null) + +$export | ConvertToPrettyJSON exit 0 diff --git a/libexec/scoop-help.ps1 b/libexec/scoop-help.ps1 index 819800ece0..54ed8a9319 100644 --- a/libexec/scoop-help.ps1 +++ b/libexec/scoop-help.ps1 @@ -3,41 +3,42 @@ param($cmd) function print_help($cmd) { - $file = Get-Content (command_path $cmd) -raw + $file = Get-Content (command_path $cmd) -Raw $usage = usage $file - $summary = summary $file $help = scoop_help $file - if($usage) { "$usage`n" } - if($help) { $help } + if ($usage) { "$usage`n" } + if ($help) { $help } } function print_summaries { - $commands = @{} + $commands = @() command_files | ForEach-Object { - $command = command_name $_ - $summary = summary (Get-Content (command_path $command) -raw) - if(!($summary)) { $summary = '' } - $commands.add("$command ", $summary) # add padding + $command = [ordered]@{} + $command.Command = command_name $_ + $command.Summary = summary (Get-Content (command_path $command.Command)) + $commands += [PSCustomObject]$command } - $commands.getenumerator() | Sort-Object name | Format-Table -hidetablehead -autosize -wrap + $commands } $commands = commands if(!($cmd)) { - "Usage: scoop [] + Write-Host "Usage: scoop [] -Some useful commands are:" +Available commands are listed below. + +Type 'scoop help ' to get more help for a specific command." print_summaries - "Type 'scoop help ' to get help for a specific command." } elseif($commands -contains $cmd) { print_help $cmd } else { - "scoop help: no such command '$cmd'"; exit 1 + warn "scoop help: no such command '$cmd'" + exit 1 } exit 0 diff --git a/libexec/scoop-import.ps1 b/libexec/scoop-import.ps1 new file mode 100644 index 0000000000..b6a0ba5d6b --- /dev/null +++ b/libexec/scoop-import.ps1 @@ -0,0 +1,64 @@ +# Usage: scoop import +# Summary: Imports apps, buckets and configs from a Scoopfile in JSON format +# Help: To replicate a Scoop installation from a file stored on Desktop, run +# scoop import Desktop\scoopfile.json + +param( + [Parameter(Mandatory)] + [String] + $scoopfile +) + +. "$PSScriptRoot\..\lib\manifest.ps1" + +$import = $null +$bucket_names = @() +$def_arch = default_architecture + +if (Test-Path $scoopfile) { + $import = parse_json $scoopfile +} elseif ($scoopfile -match '^(ht|f)tps?://|\\\\') { + $import = url_manifest $scoopfile +} + +if (!$import) { abort 'Input file not a valid JSON.' } + +foreach ($item in $import.config.PSObject.Properties) { + set_config $item.Name $item.Value | Out-Null + Write-Host "'$($item.Name)' has been set to '$($item.Value)'" +} + +foreach ($item in $import.buckets) { + add_bucket $item.Name $item.Source | Out-Null + $bucket_names += $item.Name +} + +foreach ($item in $import.apps) { + $info = $item.Info -Split ', ' + $global = if ('Global install' -in $info) { + ' --global' + } else { + '' + } + $arch = if ('64bit' -in $info -and '32bit' -eq $def_arch) { + ' --arch 64bit' + } elseif ('32bit' -in $info -and '64bit' -eq $def_arch) { + ' --arch 32bit' + } else { + '' + } + + $app = if ($item.Source -in $bucket_names) { + "$($item.Source)/$($item.Name)" + } elseif ($item.Source -eq '') { + "$($item.Name)@$($item.Version)" + } else { + $item.Source + } + + & "$PSScriptRoot\scoop-install.ps1" $app$global$arch + + if ('Held package' -in $info) { + & "$PSScriptRoot\scoop-hold.ps1" $($item.Name)$global + } +} diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1 index d4e186136e..74f7aa931a 100644 --- a/libexec/scoop-info.ps1 +++ b/libexec/scoop-info.ps1 @@ -105,6 +105,85 @@ if ($status.installed) { $installed_output += if ($verbose) { versiondir $app $_ $global } else { "$_$(if ($global) { " *global*" })" } } $item.Installed = $installed_output -join "`n" + + if ($verbose) { + # Show size of installation + $appsdir = appsdir $global + + # Collect file list from each location + $appFiles = Get-ChildItem $appsdir -Filter $app + $currentFiles = Get-ChildItem $appFiles -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#*" + + # Get the sum of each file list + $fileTotals = @() + foreach ($fileType in ($appFiles, $currentFiles, $persistFiles, $cacheFiles)) { + if ($null -ne $fileType) { + $fileSum = (Get-ChildItem $fileType -Recurse | Measure-Object -Property Length -Sum).Sum + $fileTotals += coalesce $fileSum 0 + } else { + $fileTotals += 0 + } + } + + # Old versions = app total - current version size + $fileTotals += $fileTotals[0] - $fileTotals[1] + + if ($fileTotals[2] + $fileTotals[3] + $fileTotals[4] -eq 0) { + # Simple app size output if no old versions, persisted data, cached downloads + $item.'Installed size' = filesize $fileTotals[1] + } else { + $fileSizes = [ordered] @{ + 'Current version: ' = $fileTotals[1] + 'Old versions: ' = $fileTotals[4] + 'Persisted data: ' = $fileTotals[2] + 'Cached downloads: ' = $fileTotals[3] + 'Total: ' = $fileTotals[0] + $fileTotals[2] + $fileTotals[3] + } + + $fileSizeOutput = @() + + # Don't output empty categories + $fileSizes.GetEnumerator() | ForEach-Object { + if ($_.Value -ne 0) { + $fileSizeOutput += $_.Key + (filesize $_.Value) + } + } + + $item.'Installed size' = $fileSizeOutput -join "`n" + } + } +} else { + if ($verbose) { + # Get download size if app not installed + $totalPackage = 0 + foreach ($url in @(url $manifest (default_architecture))) { + try { + if (Test-Path (fullpath (cache_path $app $manifest.version $url))) { + $cached = " (latest version is cached)" + } else { + $cached = $null + } + + [int]$urlLength = (Invoke-WebRequest $url -Method Head).Headers.'Content-Length'[0] + $totalPackage += $urlLength + } catch [System.Management.Automation.RuntimeException] { + $totalPackage = 0 + $packageError = "the server at $(([System.Uri]$url).Host) did not send a Content-Length header" + break + } catch { + $totalPackage = 0 + $packageError = "the server at $(([System.Uri]$url).Host) is down" + break + } + } + if ($totalPackage -ne 0) { + $item.'Download size' = "$(filesize $totalPackage)$cached" + } else { + $item.'Download size' = "Unknown ($packageError)$cached" + } + } } $binaries = @(arch_specific 'bin' $manifest $install.architecture) diff --git a/libexec/scoop-install.ps1 b/libexec/scoop-install.ps1 index a0c856a502..4865ea2848 100644 --- a/libexec/scoop-install.ps1 +++ b/libexec/scoop-install.ps1 @@ -3,6 +3,10 @@ # Help: e.g. The usual way to install an app (uses your local 'buckets'): # scoop install git # +# To install a different version of the app +# (note that this will auto-generate the manifest using current version): +# scoop install gh@2.7.0 +# # To install an app from a manifest at a URL: # scoop install https://raw.githubusercontent.com/ScoopInstaller/Main/master/bucket/runat.json # diff --git a/libexec/scoop-reset.ps1 b/libexec/scoop-reset.ps1 index 05cefe47cc..f84328bcbe 100644 --- a/libexec/scoop-reset.ps1 +++ b/libexec/scoop-reset.ps1 @@ -3,6 +3,8 @@ # Help: Used to resolve conflicts in favor of a particular app. For example, # if you've installed 'python' and 'python27', you can use 'scoop reset' to switch between # using one or the other. +# +# You can use '*' in place of or `-a`/`--all` switch to reset all apps. . "$PSScriptRoot\..\lib\getopt.ps1" . "$PSScriptRoot\..\lib\manifest.ps1" # 'Select-CurrentVersion' (indirectly) @@ -10,12 +12,13 @@ . "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion' . "$PSScriptRoot\..\lib\shortcuts.ps1" -$opt, $apps, $err = getopt $args +$opt, $apps, $err = getopt $args 'a' 'all' if($err) { "scoop reset: $err"; exit 1 } +$all = $opt.a -or $opt.all -if(!$apps) { error ' missing'; my_usage; exit 1 } +if(!$apps -and !$all) { error ' missing'; my_usage; exit 1 } -if($apps -eq '*') { +if($apps -eq '*' -or $all) { $local = installed_apps $false | ForEach-Object { ,@($_, $false) } $global = installed_apps $true | ForEach-Object { ,@($_, $true) } $apps = @($local) + @($global) diff --git a/libexec/scoop-search.ps1 b/libexec/scoop-search.ps1 index d878e53309..adef8b1835 100644 --- a/libexec/scoop-search.ps1 +++ b/libexec/scoop-search.ps1 @@ -9,35 +9,43 @@ param($query) . "$PSScriptRoot\..\lib\manifest.ps1" # 'manifest' . "$PSScriptRoot\..\lib\versions.ps1" # 'Get-LatestVersion' +$list = @() + +try { + $query = New-Object Regex $query, 'IgnoreCase' +} catch { + abort "Invalid regular expression: $($_.Exception.InnerException.Message)" +} + +$githubtoken = Get-GitHubToken +$authheader = @{} +if ($githubtoken) { + $authheader = @{'Authorization' = "token $githubtoken"} +} + function bin_match($manifest, $query) { - if(!$manifest.bin) { return $false } - foreach($bin in $manifest.bin) { + if (!$manifest.bin) { return $false } + $bins = foreach ($bin in $manifest.bin) { $exe, $alias, $args = $bin - $fname = split-path $exe -leaf -ea stop + $fname = Split-Path $exe -Leaf -ErrorAction Stop - if((strip_ext $fname) -match $query) { return $fname } - if($alias -match $query) { return $alias } + if ((strip_ext $fname) -match $query) { $fname } + elseif ($alias -match $query) { $alias } } - $false + if ($bins) { return $bins } + else { return $false } } function search_bucket($bucket, $query) { - $apps = apps_in_bucket (Find-BucketDirectory $bucket) | ForEach-Object { - @{ name = $_ } - } - - if($query) { - try { - $query = new-object regex $query, 'IgnoreCase' - } catch { - abort "Invalid regular expression: $($_.exception.innerexception.message)" - } + $apps = apps_in_bucket (Find-BucketDirectory $bucket) | ForEach-Object { @{ name = $_ } } + if ($query) { $apps = $apps | Where-Object { - if($_.name -match $query) { return $true } + if ($_.name -match $query) { return $true } $bin = bin_match (manifest $_.name $bucket) $query - if($bin) { - $_.bin = $bin; return $true; + if ($bin) { + $_.bin = $bin + return $true } } } @@ -46,14 +54,19 @@ function search_bucket($bucket, $query) { function download_json($url) { $ProgressPreference = 'SilentlyContinue' - $result = Invoke-WebRequest $url -UseBasicParsing | Select-Object -ExpandProperty content | ConvertFrom-Json + $result = Invoke-WebRequest $url -UseBasicParsing -Headers $authheader | Select-Object -ExpandProperty content | ConvertFrom-Json $ProgressPreference = 'Continue' $result } function github_ratelimit_reached { $api_link = 'https://api.github.com/rate_limit' - (download_json $api_link).rate.remaining -eq 0 + $ret = (download_json $api_link).rate.remaining -eq 0 + if ($ret) { + Write-Host "GitHub API rate limit reached. +Please try again later or configure your API token using 'scoop config gh_token '." + } + $ret } function search_remote($bucket, $query) { @@ -72,44 +85,59 @@ function search_remote($bucket, $query) { function search_remotes($query) { $buckets = known_bucket_repos - $names = $buckets | get-member -m noteproperty | Select-Object -exp name + $names = $buckets | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty name - $results = $names | Where-Object { !(test-path $(Find-BucketDirectory $_)) } | ForEach-Object { - @{"bucket" = $_; "results" = (search_remote $_ $query)} + $results = $names | Where-Object { !(Test-Path $(Find-BucketDirectory $_)) } | ForEach-Object { + @{ "bucket" = $_; "results" = (search_remote $_ $query) } } | Where-Object { $_.results } if ($results.count -gt 0) { - "Results from other known buckets..." - "(add them using 'scoop bucket add ')" - "" + Write-Host "Results from other known buckets... +(add them using 'scoop bucket add ')" } $results | ForEach-Object { - "'$($_.bucket)' bucket (install using 'scoop install $($_.bucket)/'):" - $_.results | ForEach-Object { " $_" } - "" + $name = $_.bucket + $_.results | ForEach-Object { + $item = [ordered]@{} + $item.Name = $_ + $item.Source = $name + $list += [PSCustomObject]$item + } } + + $list } Get-LocalBucket | ForEach-Object { $res = search_bucket $_ $query $local_results = $local_results -or $res - if($res) { + if ($res) { $name = "$_" - Write-Host "'$name' bucket:" $res | ForEach-Object { - $item = " $($_.name) ($($_.version))" - if($_.bin) { $item += " --> includes '$($_.bin)'" } - $item + $item = [ordered]@{} + $item.Name = $_.name + $item.Version = $_.version + $item.Source = $name + $item.Binaries = "" + if ($_.bin) { $item.Binaries = $_.bin -join ' | ' } + $list += [PSCustomObject]$item } - "" } } +if ($list.Length -gt 0) { + Write-Host "Results from local buckets..." + $list +} + if (!$local_results -and !(github_ratelimit_reached)) { $remote_results = search_remotes $query - if(!$remote_results) { [console]::error.writeline("No matches found."); exit 1 } + if (!$remote_results) { + warn "No matches found." + exit 1 + } $remote_results } diff --git a/libexec/scoop-status.ps1 b/libexec/scoop-status.ps1 index 878656693c..da2b634f87 100644 --- a/libexec/scoop-status.ps1 +++ b/libexec/scoop-status.ps1 @@ -7,24 +7,40 @@ # check if scoop needs updating $currentdir = fullpath $(versiondir 'scoop' 'current') $needs_update = $false +$bucket_needs_update = $false +$script:network_failure = $false +$list = @() +if (!(Get-FormatData ScoopStatus)) { + Update-FormatData "$PSScriptRoot\..\supporting\formats\ScoopTypes.Format.ps1xml" +} -if (Test-Path "$currentdir\.git") { - git_cmd -C "`"$currentdir`"" fetch -q origin - $commits = $(git -C $currentdir log "HEAD..origin/$(get_config SCOOP_BRANCH)" --oneline) - if ($commits) { $needs_update = $true } -} else { - $needs_update = $true +function Test-UpdateStatus($repopath) { + if (Test-Path "$repopath\.git") { + git_cmd -C "`"$repopath`"" 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 + if ($commits) { return $true } + else { return $false } + } else { + return $true + } } -if ($needs_update) { - warn "Scoop is out of date. Run 'scoop update' to get the latest changes." -} else { success 'Scoop is up to date.' } +$needs_update = Test-UpdateStatus $currentdir +foreach ($bucket in Get-LocalBucket) { + if (Test-UpdateStatus (Find-BucketDirectory $bucket -Root)) { + $bucket_needs_update = $true + } +} -$failed = @() -$outdated = @() -$removed = @() -$missing_deps = @() -$onhold = @() +if ($needs_update) { + warn "Scoop out of date. Run 'scoop update' to get the latest changes." +} elseif ($bucket_needs_update) { + warn "Scoop bucket(s) out of date. Run 'scoop update' to get the latest changes." +} elseif (!$script:network_failure) { + success 'Scoop is up to date.' +} $true, $false | ForEach-Object { # local and global apps $global = $_ @@ -34,64 +50,26 @@ $true, $false | ForEach-Object { # local and global apps Get-ChildItem $dir | Where-Object name -NE 'scoop' | ForEach-Object { $app = $_.name $status = app_status $app $global - if ($status.failed) { - $failed += @{ $app = $status.version } - } - if ($status.removed) { - $removed += @{ $app = $status.version } - } - if ($status.outdated) { - $outdated += @{ $app = @($status.version, $status.latest_version) } - if ($status.hold) { - $onhold += @{ $app = @($status.version, $status.latest_version) } - } - } - if ($status.missing_deps) { - $missing_deps += , (@($app) + @($status.missing_deps)) - } - } -} - -if ($outdated) { - Write-Host -f DarkCyan 'Updates are available for:' - $outdated.keys | ForEach-Object { - $versions = $outdated.$_ - " $_`: $($versions[0]) -> $($versions[1])" - } -} - -if ($onhold) { - Write-Host -f DarkCyan 'These apps are outdated and on hold:' - $onhold.keys | ForEach-Object { - $versions = $onhold.$_ - " $_`: $($versions[0]) -> $($versions[1])" - } -} + if (!$status.outdated -and !$status.failed -and !$status.removed -and !$status.missing_deps) { return } -if ($removed) { - Write-Host -f DarkCyan 'These app manifests have been removed:' - $removed.keys | ForEach-Object { - " $_" + $item = [ordered]@{} + $item.Name = $app + $item.'Installed Version' = $status.version + $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.removed) { $info += 'Manifest removed' } + $item.Info = $info -join ', ' + $list += [PSCustomObject]$item } } -if ($failed) { - Write-Host -f DarkCyan 'These apps failed to install:' - $failed.keys | ForEach-Object { - " $_" - } -} - -if ($missing_deps) { - Write-Host -f DarkCyan 'Missing runtime dependencies:' - $missing_deps | ForEach-Object { - $app, $deps = $_ - " '$app' requires '$([string]::join("', '", $deps))'" - } -} - -if (!$old -and !$removed -and !$failed -and !$missing_deps -and !$needs_update) { +if ($list.Length -eq 0 -and !$needs_update -and !$bucket_needs_update -and !$script:network_failure) { success 'Everything is ok!' } +$list | Add-Member -TypeName ScoopStatus -PassThru + exit 0 diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 844127f82f..845ff635c1 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -336,7 +336,7 @@ if (-not ($apps -or $all)) { } else { warn "'$app' is held to version $($status.version)" } - } elseif ($apps_param -ne '*') { + } elseif ($apps_param -ne '*' -and !$all) { if ($status.installed) { ensure_none_failed $app Write-Host "$app`: $($status.version) (latest version)" -ForegroundColor Green diff --git a/libexec/scoop-virustotal.ps1 b/libexec/scoop-virustotal.ps1 index 37da80ce52..ef4b84e2f6 100644 --- a/libexec/scoop-virustotal.ps1 +++ b/libexec/scoop-virustotal.ps1 @@ -2,7 +2,7 @@ # Summary: Look for app's hash or url on virustotal.com # Help: Look for app's hash or url on virustotal.com # -# Use a single '*' for app to check all installed apps. +# Use a single '*' or the '-a/--all' switch to check all installed apps. # # To use this command, you have to sign up to VirusTotal's community, # and get an API key. Then, tell scoop about your API key with: @@ -20,7 +20,7 @@ # 2 & 4 combined # # Options: -# -a, --arch <32bit|64bit> Use the specified architecture, if the app supports it +# -a, --all Check for all installed apps # -s, --scan For packages where VirusTotal has no information, send download URL # for analysis (and future retrieval). This requires you to configure # your virustotal_api_key. @@ -34,10 +34,10 @@ . "$PSScriptRoot\..\lib\install.ps1" # 'hash_for_url' . "$PSScriptRoot\..\lib\depends.ps1" # 'Get-Dependency' -$opt, $apps, $err = getopt $args 'a:snup' @('arch=', 'scan', 'no-depends', 'no-update-scoop', 'passthru') +$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 ($opt.a + $opt.arch) +$architecture = ensure_architecture if (is_scoop_outdated) { if ($opt.u -or $opt.'no-update-scoop') { @@ -49,7 +49,7 @@ if (is_scoop_outdated) { $apps_param = $apps -if ($apps_param -eq '*') { +if ($apps_param -eq '*' -or $opt.a -or $opt.all) { $apps = installed_apps $false $apps += installed_apps $true } diff --git a/supporting/formats/ScoopTypes.Format.ps1xml b/supporting/formats/ScoopTypes.Format.ps1xml index b2dff49d84..ba423f9553 100644 --- a/supporting/formats/ScoopTypes.Format.ps1xml +++ b/supporting/formats/ScoopTypes.Format.ps1xml @@ -60,5 +60,34 @@ + + ScoopStatusType + + ScoopStatus + + + + + + + Name + + + Installed Version + + + Latest Version + + + Missing Dependencies + + + Info + + + + + + diff --git a/supporting/shimexe/packages.config b/supporting/shimexe/packages.config index 3abc7f9286..7d8e9deda3 100644 --- a/supporting/shimexe/packages.config +++ b/supporting/shimexe/packages.config @@ -1,4 +1,4 @@  - + diff --git a/supporting/shimexe/shim.csproj b/supporting/shimexe/shim.csproj index 4df0db7cfb..3324f0bb06 100644 --- a/supporting/shimexe/shim.csproj +++ b/supporting/shimexe/shim.csproj @@ -1,36 +1,36 @@ - - - - Debug - AnyCPU - {381F9D2E-2355-4F84-9206-06BB9175F97B} - Exe - Scoop.Shim - Scoop.Shim - v4.5.0 - 512 - true - - - - - - - - - - - - - - - - + + - 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}. + Debug + AnyCPU + {381F9D2E-2355-4F84-9206-06BB9175F97B} + Exe + Scoop.Shim + Scoop.Shim + v4.5.0 + 512 + true - - + + + + + + + + + + + + + + + + + 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.dll b/supporting/validator/bin/Newtonsoft.Json.dll index e4a63399d0..7af125a246 100644 Binary files a/supporting/validator/bin/Newtonsoft.Json.dll and b/supporting/validator/bin/Newtonsoft.Json.dll differ diff --git a/supporting/validator/bin/Scoop.Validator.dll b/supporting/validator/bin/Scoop.Validator.dll index 9290fadd0e..0b7cc50fcc 100644 Binary files a/supporting/validator/bin/Scoop.Validator.dll and b/supporting/validator/bin/Scoop.Validator.dll differ diff --git a/supporting/validator/bin/checksum.sha256 b/supporting/validator/bin/checksum.sha256 index 837aea2c8c..a1373ec9ac 100644 --- a/supporting/validator/bin/checksum.sha256 +++ b/supporting/validator/bin/checksum.sha256 @@ -1,4 +1,4 @@ -7f912b28a07c226e0be3acfb2f57f050538aba0100fa1f0bf2c39f1a1f1da814 *Newtonsoft.Json.dll +b624949df8b0e3a6153fdfb730a7c6f4990b6592ee0d922e1788433d276610f3 *Newtonsoft.Json.dll cff8fc4ce358d7daff84ab47129a776797a4ec819c1586a15bd5e63144f5b73f *Newtonsoft.Json.Schema.dll -0d6b228378cbabff23a30456d22f1a31337c466f90cf8b7997cc48bd171155f3 *Scoop.Validator.dll +0318c8221ce4d44806f8def619bcc02886be0902aab80080e6251c50c6ca53a9 *Scoop.Validator.dll 40a70bee96d108701f8f2e81392f9b79fd003f1cb4e1653ad2429753153fd7ee *validator.exe diff --git a/supporting/validator/bin/checksum.sha512 b/supporting/validator/bin/checksum.sha512 index 119e1bb480..f60b14229b 100644 --- a/supporting/validator/bin/checksum.sha512 +++ b/supporting/validator/bin/checksum.sha512 @@ -1,4 +1,4 @@ -3398094ce429ab5dcdecf2ad04803230669bb4accaef7083992e9b87afac55841ba8def2a5168358bd17e60799e55d076b0e5ca44c86b9e6c91150d3dc37c721 *Newtonsoft.Json.dll +2fdf035661f349206f58ea1feed8805b7f9517a21f9c113e7301c69de160f184c774350a12a710046e3ff6baa37345d319b6f47fd24fbba4e042d54014bee511 *Newtonsoft.Json.dll 298d3d0b656acbb1fe5ed0c3abb49a640c47889184ab7bd4b594e51a7d7f829d5c8685edbd10a286fd56bfd8d601b9f187da463a5a9c8509365eddaea280642f *Newtonsoft.Json.Schema.dll -afabe1df6ab837395a5da5ec8dd12bf3f36a8512b76e6f751c14045544246980e9d4061d437792836db792864b7db2761e84f1bf65bac688657a862b68fc7b45 *Scoop.Validator.dll +338793e6127330c0b05728291fcf18441127ffb56e1bd5c0f0588cd7436605f4b852f4bb622f655896a7eb7b1262add142b200fd5f37391b47d1401becb6b81c *Scoop.Validator.dll d497c27b48f44f4cff270d3c8801b0cecc74108f8786a4a7c40e57541308ae33a69f5456cfc43ae1ce4214038d20da9fbeac1bcf76cc58d972863b58dab18401 *validator.exe diff --git a/supporting/validator/packages.config b/supporting/validator/packages.config index 2655769d42..2f89a6b390 100644 --- a/supporting/validator/packages.config +++ b/supporting/validator/packages.config @@ -1,6 +1,6 @@  - - - + + + diff --git a/supporting/validator/validator.csproj b/supporting/validator/validator.csproj index 21c6f2e83c..693dbd045d 100644 --- a/supporting/validator/validator.csproj +++ b/supporting/validator/validator.csproj @@ -1,48 +1,48 @@ - - - - Debug - AnyCPU - {8EB9B38A-1BAB-4D89-B4CB-ACE5E7C1073B} - Exe - Scoop.Validator - Scoop.Validator - v4.5.0 - 512 - true - - - - packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - True - - - packages\Newtonsoft.Json.Schema.3.0.14\lib\net45\Newtonsoft.Json.Schema.dll - True - - - - - - - - - - - - - - - - - - - + + - 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}. + Debug + AnyCPU + {8EB9B38A-1BAB-4D89-B4CB-ACE5E7C1073B} + Exe + Scoop.Validator + Scoop.Validator + v4.5.0 + 512 + true - - + + + packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + True + + + packages\Newtonsoft.Json.Schema.3.0.14\lib\net45\Newtonsoft.Json.Schema.dll + True + + + + + + + + + + + + + + + + + + + + + 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/test/Import-File-Tests.ps1 b/test/Import-File-Tests.ps1 index a1ae343f10..0359e8069f 100644 --- a/test/Import-File-Tests.ps1 +++ b/test/Import-File-Tests.ps1 @@ -10,7 +10,7 @@ Describe 'Style constraints for non-binary project files' { $repo_files | Where-Object { $_.fullname -inotmatch $($project_file_exclusions -join '|') } | Where-Object { $_.fullname -inotmatch '(.exe|.zip|.dll)$' } | - Where-Object { $_.fullname -inotmatch '(unformated)' } + Where-Object { $_.fullname -inotmatch '(unformatted)' } ) $files_exist = ($files.Count -gt 0) diff --git a/test/Scoop-Decompress.Tests.ps1 b/test/Scoop-Decompress.Tests.ps1 index 0bdc20f363..b568ef8e56 100644 --- a/test/Scoop-Decompress.Tests.ps1 +++ b/test/Scoop-Decompress.Tests.ps1 @@ -22,7 +22,7 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' { It 'Decompression test cases should exist' { $testcases = "$working_dir\TestCases.zip" $testcases | Should -Exist - compute_hash $testcases 'sha256' | Should -Be '16507166814dbd02be80c14b737eb6b0245c47439ca3ed308b5625d64babecc8' + compute_hash $testcases 'sha256' | Should -Be '791bfce192917a2ff225dcdd87d23ae5f720b20178d85e68e4b1b56139cf8e6a' if (!$isUnix) { Microsoft.PowerShell.Archive\Expand-Archive $testcases $working_dir } @@ -44,6 +44,9 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' { $test5_1 = "$working_dir\7ZipTest5.7z.001" $test5_2 = "$working_dir\7ZipTest5.7z.002" $test5_3 = "$working_dir\7ZipTest5.7z.003" + $test6_1 = "$working_dir\7ZipTest6.part01.rar" + $test6_2 = "$working_dir\7ZipTest6.part02.rar" + $test6_3 = "$working_dir\7ZipTest6.part03.rar" } It 'extract normal compressed file' -Skip:$isUnix { @@ -81,6 +84,13 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' { (Get-ChildItem $to).Count | Should -Be 1 } + It 'extract splited RAR archives (.part01.rar, .part02.rar, ...)' -Skip:$isUnix { + $to = test_extract 'Expand-7zipArchive' $test6_1 + $to | Should -Exist + "$to\dummy" | Should -Exist + (Get-ChildItem $to).Count | Should -Be 1 + } + It 'works with "-Removal" switch ($removal param)' -Skip:$isUnix { $test1 | Should -Exist test_extract 'Expand-7zipArchive' $test1 $true @@ -92,6 +102,13 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' { $test5_1 | Should -Not -Exist $test5_2 | Should -Not -Exist $test5_3 | Should -Not -Exist + $test6_1 | Should -Exist + $test6_2 | Should -Exist + $test6_3 | Should -Exist + test_extract 'Expand-7zipArchive' $test6_1 $true + $test6_1 | Should -Not -Exist + $test6_2 | Should -Not -Exist + $test6_3 | Should -Not -Exist } } diff --git a/test/Scoop-Depends.Tests.ps1 b/test/Scoop-Depends.Tests.ps1 index 4a58db2443..03713c0c3e 100644 --- a/test/Scoop-Depends.Tests.ps1 +++ b/test/Scoop-Depends.Tests.ps1 @@ -32,7 +32,7 @@ Describe 'Package Dependencies' -Tag 'Scoop' { Context 'InstallationHelper function' { BeforeAll { - $working_dir = setup_working 'format/formated' + $working_dir = setup_working 'format/formatted' $manifest1 = parse_json (Join-Path $working_dir '3-array-with-single-and-multi.json') $manifest2 = parse_json (Join-Path $working_dir '4-script-block.json') Mock Test-HelperInstalled { $false } diff --git a/test/Scoop-Format-Manifest.Tests.ps1 b/test/Scoop-Format-Manifest.Tests.ps1 index e74f782bd0..25bc9730ce 100644 --- a/test/Scoop-Format-Manifest.Tests.ps1 +++ b/test/Scoop-Format-Manifest.Tests.ps1 @@ -5,7 +5,7 @@ Describe 'Pretty json formating' -Tag 'Scoop' { BeforeAll { $format = "$PSScriptRoot\fixtures\format" - $manifests = Get-ChildItem "$format\formated" -File -Filter '*.json' + $manifests = Get-ChildItem "$format\formatted" -File -Filter '*.json' } Context 'Beautify manifest' { @@ -13,8 +13,8 @@ Describe 'Pretty json formating' -Tag 'Scoop' { if ($PSVersionTable.PSVersion.Major -gt 5) { $_ = $_.Name } # Fix for pwsh It "$_" { - $pretty_json = (parse_json "$format\unformated\$_") | ConvertToPrettyJson - $correct = (Get-Content "$format\formated\$_") -join "`r`n" + $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/fixtures/decompress/TestCases.zip b/test/fixtures/decompress/TestCases.zip index fd5115405a..12a891eee9 100644 Binary files a/test/fixtures/decompress/TestCases.zip and b/test/fixtures/decompress/TestCases.zip differ diff --git a/test/fixtures/format/formated/1-easy.json b/test/fixtures/format/formatted/1-easy.json similarity index 100% rename from test/fixtures/format/formated/1-easy.json rename to test/fixtures/format/formatted/1-easy.json diff --git a/test/fixtures/format/formated/2-whitespaces-mess.json b/test/fixtures/format/formatted/2-whitespaces-mess.json similarity index 100% rename from test/fixtures/format/formated/2-whitespaces-mess.json rename to test/fixtures/format/formatted/2-whitespaces-mess.json diff --git a/test/fixtures/format/formated/3-array-with-single-and-multi.json b/test/fixtures/format/formatted/3-array-with-single-and-multi.json similarity index 100% rename from test/fixtures/format/formated/3-array-with-single-and-multi.json rename to test/fixtures/format/formatted/3-array-with-single-and-multi.json diff --git a/test/fixtures/format/formated/4-script-block.json b/test/fixtures/format/formatted/4-script-block.json similarity index 100% rename from test/fixtures/format/formated/4-script-block.json rename to test/fixtures/format/formatted/4-script-block.json diff --git a/test/fixtures/format/unformated/1-easy.json b/test/fixtures/format/unformatted/1-easy.json similarity index 100% rename from test/fixtures/format/unformated/1-easy.json rename to test/fixtures/format/unformatted/1-easy.json diff --git a/test/fixtures/format/unformated/2-whitespaces-mess.json b/test/fixtures/format/unformatted/2-whitespaces-mess.json similarity index 100% rename from test/fixtures/format/unformated/2-whitespaces-mess.json rename to test/fixtures/format/unformatted/2-whitespaces-mess.json diff --git a/test/fixtures/format/unformated/3-array-with-single-and-multi.json b/test/fixtures/format/unformatted/3-array-with-single-and-multi.json similarity index 100% rename from test/fixtures/format/unformated/3-array-with-single-and-multi.json rename to test/fixtures/format/unformatted/3-array-with-single-and-multi.json diff --git a/test/fixtures/format/unformated/4-script-block.json b/test/fixtures/format/unformatted/4-script-block.json similarity index 100% rename from test/fixtures/format/unformated/4-script-block.json rename to test/fixtures/format/unformatted/4-script-block.json