diff --git a/CHANGELOG.md b/CHANGELOG.md index b8c8cd75..3065fa7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - **scoop-search:** Use SQLite for caching apps to speed up local search ([#5851](https://github.com/ScoopInstaller/Scoop/issues/5851), [#5918](https://github.com/ScoopInstaller/Scoop/issues/5918)) +- **core:** New cache filename format ([#5929](https://github.com/ScoopInstaller/Scoop/issues/5929) ### Bug Fixes diff --git a/lib/core.ps1 b/lib/core.ps1 index 2211a519..90184fd5 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -409,7 +409,22 @@ function currentdir($app, $global) { function persistdir($app, $global) { "$(basedir $global)\persist\$app" } function usermanifestsdir { "$(basedir)\workspace" } function usermanifest($app) { "$(usermanifestsdir)\$app.json" } -function cache_path($app, $version, $url) { "$cachedir\$app#$version#$($url -replace '[^\w\.\-]+', '_')" } +function cache_path($app, $version, $url) { + $underscoredUrl = $url -replace '[^\w\.\-]+', '_' + $filePath = "$cachedir\$app#$version#$underscoredUrl" + + # NOTE: Scoop cache files migration. Remove this 6 months after the feature ships. + if (Test-Path $filePath) { + return $filePath + } + + $urlStream = [System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($url)) + $sha = (Get-FileHash -Algorithm SHA256 -InputStream $urlStream).Hash.ToLower().Substring(0, 7) + $extension = [System.IO.Path]::GetExtension($url) + $filePath = $filePath -replace "$underscoredUrl", "$sha$extension" + + return $filePath +} # apps function sanitary_path($path) { return [regex]::replace($path, "[/\\?:*<>|]", "") } diff --git a/libexec/scoop-cache.ps1 b/libexec/scoop-cache.ps1 index 959c73fc..f390c258 100644 --- a/libexec/scoop-cache.ps1 +++ b/libexec/scoop-cache.ps1 @@ -16,7 +16,7 @@ param($cmd) function cacheinfo($file) { $app, $version, $url = $file.Name -split '#' - New-Object PSObject -Property @{ Name = $app; Version = $version; Length = $file.Length; URL = $url } + New-Object PSObject -Property @{ Name = $app; Version = $version; Length = $file.Length } } function cacheshow($app) { @@ -28,7 +28,7 @@ function cacheshow($app) { $files = @(Get-ChildItem $cachedir | Where-Object -Property Name -Value "^$app#" -Match) $totalLength = ($files | Measure-Object -Property Length -Sum).Sum - $files | ForEach-Object { cacheinfo $_ } | Select-Object Name, Version, Length, URL + $files | ForEach-Object { cacheinfo $_ } | Select-Object Name, Version, Length Write-Host "Total: $($files.Length) $(pluralize $files.Length 'file' 'files'), $(filesize $totalLength)" -ForegroundColor Yellow } diff --git a/test/Scoop-Core.Tests.ps1 b/test/Scoop-Core.Tests.ps1 index 3fb7fbd6..f6846e54 100644 --- a/test/Scoop-Core.Tests.ps1 +++ b/test/Scoop-Core.Tests.ps1 @@ -259,6 +259,23 @@ Describe 'get_app_name_from_shim' -Tag 'Scoop', 'Windows' { } } +Describe 'cache_path' -Tag 'Scoop' { + It 'returns the correct cache path for a given input' { + $url = 'https://example.com/git.zip' + $ret = cache_path 'git' '2.44.0' $url + $inputStream = [System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($url)) + $sha = (Get-FileHash -Algorithm SHA256 -InputStream $inputStream).Hash.ToLower().Substring(0, 7) + $ret | Should -Be "$cachedir\git#2.44.0#$sha.zip" + } + + # # NOTE: Remove this 6 months after the feature ships. + It 'returns the old format cache path for a given input' { + Mock Test-Path { $true } + $ret = cache_path 'git' '2.44.0' 'https://example.com/git.zip' + $ret | Should -Be "$cachedir\git#2.44.0#https_example.com_git.zip" + } +} + Describe 'sanitary_path' -Tag 'Scoop' { It 'removes invalid path characters from a string' { $path = 'test?.json'