From a32a74f50c664523e9458bf7d52c78e66f863d9b Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 27 Mar 2024 13:32:54 +0800 Subject: [PATCH 01/14] feat(sqlite): Use SQLite for caching apps --- .gitignore | 1 + lib/database.ps1 | 359 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 360 insertions(+) create mode 100644 lib/database.ps1 diff --git a/.gitignore b/.gitignore index fdc96d2a52..67ecc85d82 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ test/installer/tmp/* test/tmp/* *~ TestResults.xml +supporting/sqlite/* diff --git a/lib/database.ps1 b/lib/database.ps1 new file mode 100644 index 0000000000..8bc683058f --- /dev/null +++ b/lib/database.ps1 @@ -0,0 +1,359 @@ +# Description: Functions for interacting with the Scoop database cache + +<# +.SYNOPSIS + Get SQLite .NET driver +.DESCRIPTION + Download and extract the SQLite .NET driver from NuGet. +.PARAMETER Version + System.String + The version of the SQLite .NET driver to download. +.INPUTS + None +.OUTPUTS + System.Boolean + True if the SQLite .NET driver was successfully downloaded and extracted, otherwise false. +#> +function Get-SQLite { + param ( + [string]$Version = '1.0.118' + ) + # Install SQLite + try { + Write-Host "Downloading SQLite $Version..." -ForegroundColor DarkYellow + $sqlitePkgPath = "$env:TEMP\sqlite.nupkg" + $sqliteTempPath = "$env:TEMP\sqlite" + $sqlitePath = "$PSScriptRoot\..\supporting\sqlite" + Invoke-WebRequest -Uri "https://api.nuget.org/v3-flatcontainer/stub.system.data.sqlite.core.netframework/$version/stub.system.data.sqlite.core.netframework.$version.nupkg" -OutFile $sqlitePkgPath + Write-Host "Extracting SQLite $Version..." -ForegroundColor DarkYellow -NoNewline + Expand-Archive -Path $sqlitePkgPath -DestinationPath $sqliteTempPath -Force + New-Item -Path $sqlitePath -ItemType Directory -Force | Out-Null + Move-Item -Path "$sqliteTempPath\build\net45\*" -Destination $sqlitePath -Exclude '*.targets' -Force + Move-Item -Path "$sqliteTempPath\lib\net45\System.Data.SQLite.dll" -Destination $sqlitePath -Force + Remove-Item -Path $sqlitePkgPath, $sqliteTempPath -Recurse -Force + Write-Host ' Done' -ForegroundColor DarkYellow + return $true + } catch { + return $false + } +} + +<# +.SYNOPSIS + Close a SQLite database. +.DESCRIPTION + Close a SQLite database connection. +.PARAMETER InputObject + System.Data.SQLite.SQLiteConnection + The SQLite database connection to close. +.INPUTS + System.Data.SQLite.SQLiteConnection +.OUTPUTS + None +#> +function Close-ScoopDB { + [CmdletBinding()] + param ( + [Parameter(Mandatory, ValueFromPipeline)] + [System.Data.SQLite.SQLiteConnection] + $InputObject + ) + process { + $InputObject.Dispose() + } +} + +<# +.SYNOPSIS + Create a new SQLite database. +.DESCRIPTION + Create a new SQLite database connection and create the necessary tables. +.PARAMETER PassThru + System.Management.Automation.SwitchParameter + Return the SQLite database connection. +.INPUTS + None +.OUTPUTS + None + Default + + System.Data.SQLite.SQLiteConnection + The SQLite database connection if **PassThru** is used. +#> +function New-ScoopDB ([switch]$PassThru) { + # Load System.Data.SQLite + try { + [Void][System.Data.SQLite.SQLiteConnection] + } catch { + try { + if (!(Test-Path -Path "$PSScriptRoot\..\supporting\sqlite\System.Data.SQLite.dll")) { + Get-SQLite + } + Add-Type -Path "$PSScriptRoot\..\supporting\sqlite\System.Data.SQLite.dll" + } catch { + throw "Scoop's Database cache requires the ADO.NET driver:`n`thttp://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki" + } + } + $dbPath = Join-Path $scoopdir 'scoop.db' + $db = New-Object -TypeName System.Data.SQLite.SQLiteConnection + $db.ConnectionString = "Data Source=$dbPath" + $db.ParseViaFramework = $true # Allow UNC path + $db.Open() + $tableCommand = $db.CreateCommand() + $tableCommand.CommandText = "CREATE TABLE IF NOT EXISTS 'app' ( + name TEXT NOT NULL COLLATE NOCASE, + description TEXT NOT NULL, + version TEXT NOT NULL, + bucket VARCHAR NOT NULL, + manifest JSON NOT NULL, + binary TEXT, + shortcut TEXT, + dependency TEXT, + suggest TEXT, + PRIMARY KEY (name, version, bucket) + )" + $tableCommand.ExecuteNonQuery() | Out-Null + $tableCommand.Dispose() + if ($PassThru) { + $db + } else { + $db.Dispose() + } +} + +<# +.SYNOPSIS + Set Scoop database item(s). +.DESCRIPTION + Insert or replace Scoop database item(s) into the database. +.PARAMETER InputObject + System.Object[] + The database item(s) to insert or replace. +.INPUTS + System.Object[] +.OUTPUTS + None +#> +function Set-ScoopDBItem { + [CmdletBinding()] + param ( + [Parameter(Mandatory, Position = 0, ValueFromPipeline)] + [psobject[]] + $InputObject + ) + + begin { + $db = New-ScoopDB -PassThru + $dbTrans = $db.BeginTransaction() + # TODO Support [hashtable]$InputObject + $colName = @($InputObject | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name) + $dbQuery = "INSERT OR REPLACE INTO app ($($colName -join ', ')) VALUES ($('@' + ($colName -join ', @')))" + $dbCommand = $db.CreateCommand() + $dbCommand.CommandText = $dbQuery + } + process { + foreach ($item in $InputObject) { + $item.PSObject.Properties | ForEach-Object { + $dbCommand.Parameters.AddWithValue("@$($_.Name)", $_.Value) | Out-Null + } + $dbCommand.ExecuteNonQuery() | Out-Null + } + } + end { + try { + $dbTrans.Commit() + } catch { + $dbTrans.Rollback() + throw $_ + } finally { + $db.Dispose() + } + } +} + +<# +.SYNOPSIS + Set Scoop app database item(s). +.DESCRIPTION + Insert or replace Scoop app(s) into the database. +.PARAMETER Path + System.String + The path to the bucket. +.PARAMETER CommitHash + System.String + The commit hash to compare with the HEAD. +.INPUTS + None +.OUTPUTS + None +#> +function Set-ScoopDB { + [CmdletBinding()] + param ( + [Parameter(Position = 0, ValueFromPipeline)] + [string[]] + $Path + ) + + begin { + $list = [System.Collections.Generic.List[PSCustomObject]]::new() + $arch = Get-DefaultArchitecture + } + process { + if ($Path.Count -eq 0) { + $bucketPath = Get-LocalBucket | ForEach-Object { Join-Path $bucketsdir $_ } + $Path = (Get-ChildItem $bucketPath -Filter '*.json' -Recurse | Where-Object { $_.FullName -notmatch '[\\/]\.' }).FullName + } + $Path | ForEach-Object { + $manifestRaw = [System.IO.File]::ReadAllText($_) + $manifest = $manifestRaw | ConvertFrom-Json -ErrorAction Continue + $list.Add([pscustomobject]@{ + name = $($_ -replace '.*[\\/]([^\\/]+)\.json$', '$1') + description = if ($manifest.description) { $manifest.description } else { '' } + version = $manifest.version + bucket = $($_ -replace '.*buckets[\\/]([^\\/]+)(?:[\\/].*)', '$1') + manifest = $manifestRaw + binary = $( + $result = @() + @(arch_specific 'bin' $manifest $arch) | ForEach-Object { + if ($_ -is [System.Array]) { + $result += "$($_[1]).$($_[0].Split('.')[-1])" + } else { + $result += $_ + } + } + $result -replace '.*?([^\\/]+)?(\.(exe|bat|cmd|ps1|jar|py))$', '$1' -join ' | ' + ) + shortcut = $( + $result = @() + @(arch_specific 'shortcuts' $manifest $arch) | ForEach-Object { + $result += $_[1] + } + $result -replace '.*?([^\\/]+$)', '$1' -join ' | ' + ) + dependency = $manifest.depends -join ' | ' + suggest = $( + $suggest_output = @() + $manifest.suggest.PSObject.Properties | ForEach-Object { + $suggest_output += $_.Value -join ' | ' + } + $suggest_output -join ' | ' + ) + }) + } + } + end { + if ($list.Count -ne 0) { + Set-ScoopDBItem $list + } + } +} + +<# +.SYNOPSIS + Select Scoop database item(s). +.DESCRIPTION + Select Scoop database item(s) from the database. + The pattern is matched against the name, binaries, and shortcuts columns for apps. +.PARAMETER Pattern + System.String + The pattern to search for. If is an empty string, all items will be returned. +.INPUTS + System.String +.OUTPUTS + System.Data.DataTable + The selected database item(s). +#> +function Select-ScoopDBItem { + [CmdletBinding()] + param ( + [Parameter(Mandatory, Position = 0, ValueFromPipeline)] + [AllowEmptyString()] + [string] + $Pattern, + [Parameter(Mandatory, Position = 1)] + [string[]] + $From + ) + + begin { + $db = New-ScoopDB -PassThru + $dbAdapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter + $result = New-Object System.Data.DataTable + $dbQuery = "SELECT * FROM app WHERE $(($From -join ' LIKE @Pattern OR ') + ' LIKE @Pattern')" + $dbQuery = "SELECT * FROM ($($dbQuery + ' ORDER BY version DESC')) GROUP BY name, bucket" + $dbCommand = $db.CreateCommand() + $dbCommand.CommandText = $dbQuery + $dbCommand.CommandType = [System.Data.CommandType]::Text + } + process { + $dbCommand.Parameters.AddWithValue('@Pattern', $(if ($Pattern -eq '') { '%' } else { '%' + $Pattern + '%' })) | Out-Null + $dbAdapter.SelectCommand = $dbCommand + [void]$dbAdapter.Fill($result) + } + end { + $db.Dispose() + return $result + } +} + +<# +.SYNOPSIS + Get Scoop database item. +.DESCRIPTION + Get Scoop database item from the database. +.PARAMETER Name + System.String + The name of the item to get. +.PARAMETER Bucket + System.String + The bucket of the item to get. +.PARAMETER Version + System.String + The version of the item to get. If not provided, the latest version will be returned. +.INPUTS + System.String +.OUTPUTS + System.Data.DataTable + The selected database item. +#> +function Get-ScoopDBItem { + [CmdletBinding()] + param ( + [Parameter(Mandatory, Position = 0, ValueFromPipeline)] + [string] + $Name, + [Parameter(Mandatory, Position = 1)] + [string] + $Bucket, + [Parameter(Position = 2)] + [string] + $Version + ) + + begin { + $db = New-ScoopDB -PassThru + $dbAdapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter + $result = New-Object System.Data.DataTable + $dbQuery = 'SELECT * FROM app WHERE name = @Name AND bucket = @Bucket' + if ($Version) { + $dbQuery += ' AND version = @Version' + } else { + $dbQuery += ' ORDER BY version DESC LIMIT 1' + } + $dbCommand = $db.CreateCommand() + $dbCommand.CommandText = $dbQuery + $dbCommand.CommandType = [System.Data.CommandType]::Text + } + process { + $dbCommand.Parameters.AddWithValue('@Name', $Name) | Out-Null + $dbCommand.Parameters.AddWithValue('@Bucket', $Bucket) | Out-Null + $dbCommand.Parameters.AddWithValue('@Version', $Version) | Out-Null + $dbAdapter.SelectCommand = $dbCommand + [void]$dbAdapter.Fill($result) + } + end { + $db.Dispose() + return $result + } +} From 757c851a0306a19d73fd94918b0528c597355187 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Tue, 26 Mar 2024 01:42:56 +0800 Subject: [PATCH 02/14] Format `scoop-search.ps1`/`scoop-update.ps1` --- libexec/scoop-search.ps1 | 60 ++++++++++++++++++++-------------------- libexec/scoop-update.ps1 | 34 +++++++++++------------ 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/libexec/scoop-search.ps1 b/libexec/scoop-search.ps1 index a9013afd02..0af59074fa 100644 --- a/libexec/scoop-search.ps1 +++ b/libexec/scoop-search.ps1 @@ -20,7 +20,7 @@ try { $githubtoken = Get-GitHubToken $authheader = @{} if ($githubtoken) { - $authheader = @{'Authorization' = "token $githubtoken"} + $authheader = @{'Authorization' = "token $githubtoken" } } function bin_match($manifest, $query) { @@ -39,16 +39,16 @@ function bin_match($manifest, $query) { function bin_match_json($json, $query) { [System.Text.Json.JsonElement]$bin = [System.Text.Json.JsonElement]::new() - if (!$json.RootElement.TryGetProperty("bin", [ref] $bin)) { return $false } + if (!$json.RootElement.TryGetProperty('bin', [ref] $bin)) { return $false } $bins = @() - if($bin.ValueKind -eq [System.Text.Json.JsonValueKind]::String -and [System.IO.Path]::GetFileNameWithoutExtension($bin) -match $query) { + if ($bin.ValueKind -eq [System.Text.Json.JsonValueKind]::String -and [System.IO.Path]::GetFileNameWithoutExtension($bin) -match $query) { $bins += [System.IO.Path]::GetFileName($bin) } elseif ($bin.ValueKind -eq [System.Text.Json.JsonValueKind]::Array) { - foreach($subbin in $bin.EnumerateArray()) { - if($subbin.ValueKind -eq [System.Text.Json.JsonValueKind]::String -and [System.IO.Path]::GetFileNameWithoutExtension($subbin) -match $query) { + foreach ($subbin in $bin.EnumerateArray()) { + if ($subbin.ValueKind -eq [System.Text.Json.JsonValueKind]::String -and [System.IO.Path]::GetFileNameWithoutExtension($subbin) -match $query) { $bins += [System.IO.Path]::GetFileName($subbin) } elseif ($subbin.ValueKind -eq [System.Text.Json.JsonValueKind]::Array) { - if([System.IO.Path]::GetFileNameWithoutExtension($subbin[0]) -match $query) { + if ([System.IO.Path]::GetFileNameWithoutExtension($subbin[0]) -match $query) { $bins += [System.IO.Path]::GetFileName($subbin[0]) } elseif ($subbin.GetArrayLength() -ge 2 -and $subbin[1] -match $query) { $bins += $subbin[1] @@ -70,20 +70,20 @@ function search_bucket($bucket, $query) { if ($name -match $query) { $list.Add([PSCustomObject]@{ - Name = $name - Version = $json.RootElement.GetProperty("version") - Source = $bucket - Binaries = "" - }) + Name = $name + Version = $json.RootElement.GetProperty('version') + Source = $bucket + Binaries = '' + }) } else { $bin = bin_match_json $json $query if ($bin) { $list.Add([PSCustomObject]@{ - Name = $name - Version = $json.RootElement.GetProperty("version") - Source = $bucket - Binaries = $bin -join ' | ' - }) + Name = $name + Version = $json.RootElement.GetProperty('version') + Source = $bucket + Binaries = $bin -join ' | ' + }) } } } @@ -99,20 +99,20 @@ function search_bucket_legacy($bucket, $query) { if ($name -match $query) { $list.Add([PSCustomObject]@{ - Name = $name - Version = $manifest.Version - Source = $bucket - Binaries = "" - }) + Name = $name + Version = $manifest.Version + Source = $bucket + Binaries = '' + }) } else { $bin = bin_match $manifest $query if ($bin) { $list.Add([PSCustomObject]@{ - Name = $name - Version = $manifest.Version - Source = $bucket - Binaries = $bin -join ' | ' - }) + Name = $name + Version = $manifest.Version + Source = $bucket + Binaries = $bin -join ' | ' + }) } } } @@ -154,7 +154,7 @@ function search_remotes($query) { $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) } + @{ 'bucket' = $_; 'results' = (search_remote $_ $query) } } | Where-Object { $_.results } if ($results.count -gt 0) { @@ -175,7 +175,7 @@ function search_remotes($query) { $remote_list } -$jsonTextAvailable = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-object { [System.IO.Path]::GetFileNameWithoutExtension($_.Location) -eq "System.Text.Json" } +$jsonTextAvailable = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { [System.IO.Path]::GetFileNameWithoutExtension($_.Location) -eq 'System.Text.Json' } Get-LocalBucket | ForEach-Object { if ($jsonTextAvailable) { @@ -186,14 +186,14 @@ Get-LocalBucket | ForEach-Object { } if ($list.Count -gt 0) { - Write-Host "Results from local buckets..." + Write-Host 'Results from local buckets...' $list } if ($list.Count -eq 0 -and !(github_ratelimit_reached)) { $remote_results = search_remotes $query if (!$remote_results) { - warn "No matches found." + warn 'No matches found.' exit 1 } $remote_results diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index e632be72fb..0fce6c8064 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -37,21 +37,21 @@ $all = $opt.a -or $opt.all # load config $configRepo = get_config SCOOP_REPO if (!$configRepo) { - $configRepo = "https://github.com/ScoopInstaller/Scoop" + $configRepo = 'https://github.com/ScoopInstaller/Scoop' set_config SCOOP_REPO $configRepo | Out-Null } # Find current update channel from config $configBranch = get_config SCOOP_BRANCH if (!$configBranch) { - $configBranch = "master" + $configBranch = 'master' set_config SCOOP_BRANCH $configBranch | Out-Null } -if(($PSVersionTable.PSVersion.Major) -lt 5) { +if (($PSVersionTable.PSVersion.Major) -lt 5) { # check powershell version - Write-Output "PowerShell 5 or later is required to run Scoop." - Write-Output "Upgrade PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows" + Write-Output 'PowerShell 5 or later is required to run Scoop.' + Write-Output 'Upgrade PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows' break } $show_update_log = get_config SHOW_UPDATE_LOG $true @@ -62,14 +62,14 @@ function Sync-Scoop { [Switch]$Log ) # Test if Scoop Core is hold - if(Test-ScoopCoreOnHold) { + if (Test-ScoopCoreOnHold) { return } # check for git if (!(Test-GitAvailable)) { abort "Scoop uses Git to update itself. Run 'scoop install git' and try again." } - Write-Host "Updating Scoop..." + Write-Host 'Updating Scoop...' $currentdir = fullpath $(versiondir 'scoop' 'current') if (!(Test-Path "$currentdir\.git")) { $newdir = "$currentdir\..\new" @@ -107,10 +107,10 @@ function Sync-Scoop { # Stash uncommitted changes if (Invoke-Git -Path $currentdir -ArgumentList @('diff', 'HEAD', '--name-only')) { if (get_config AUTOSTASH_ON_CONFLICT) { - warn "Uncommitted changes detected. Stashing..." + warn 'Uncommitted changes detected. Stashing...' Invoke-Git -Path $currentdir -ArgumentList @('stash', 'push', '-m', "WIP at $([System.DateTime]::Now.ToString('o'))", '-u', '-q') } else { - warn "Uncommitted changes detected. Update aborted." + warn 'Uncommitted changes detected. Update aborted.' return } } @@ -151,7 +151,7 @@ function Sync-Bucket { Param ( [Switch]$Log ) - Write-Host "Updating Buckets..." + Write-Host 'Updating Buckets...' if (!(Test-Path (Join-Path (Find-BucketDirectory 'main' -Root) '.git'))) { info "Converting 'main' bucket to git repo..." @@ -169,9 +169,9 @@ function Sync-Bucket { $buckets = Get-LocalBucket | ForEach-Object { $path = Find-BucketDirectory $_ -Root return @{ - name = $_ + name = $_ valid = Test-Path (Join-Path $path '.git') - path = $path + path = $path } } @@ -243,7 +243,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c # region Workaround # Workaround for https://github.com/ScoopInstaller/Scoop/issues/2220 until install is refactored # Remove and replace whole region after proper fix - Write-Host "Downloading new version" + Write-Host 'Downloading new version' if (Test-Aria2Enabled) { Invoke-CachedAria2Download $app $version $manifest $architecture $cachedir $manifest.cookie $true $check_hash } else { @@ -261,12 +261,12 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c error $err if (Test-Path $source) { # rm cached file - Remove-Item -force $source + Remove-Item -Force $source } if ($url.Contains('sourceforge.net')) { Write-Host -f yellow 'SourceForge.net is known for causing hash validation fails. Please try again before opening a ticket.' } - abort $(new_issue_msg $app $bucket "hash check failed") + abort $(new_issue_msg $app $bucket 'hash check failed') } } } @@ -402,11 +402,11 @@ if (-not ($apps -or $all)) { } elseif ($outdated.Length -eq 0) { Write-Host -f Green "Latest versions for all apps are installed! For more information try 'scoop status'" } else { - Write-Host -f DarkCyan "Updating one outdated app:" + Write-Host -f DarkCyan 'Updating one outdated app:' } } - $suggested = @{}; + $suggested = @{} # $outdated is a list of ($app, $global) tuples $outdated | ForEach-Object { update @_ $quiet $independent $suggested $use_cache $check_hash } } From 6a93623bced98a0db31fc239b2d1ff5254ead6f9 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 27 Mar 2024 13:32:58 +0800 Subject: [PATCH 03/14] Support cache in `scoop-search.ps1` --- lib/core.ps1 | 25 +++++++++++++++++++++++++ libexec/scoop-config.ps1 | 3 +++ libexec/scoop-search.ps1 | 38 ++++++++++++++++++++++++++------------ libexec/scoop-update.ps1 | 22 ++++++++++++++++++++++ 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index 525a4951e4..d7efd82ec6 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -142,11 +142,36 @@ function set_config { $scoopConfig.PSObject.Properties.Remove($name) } + # Initialize config's change + Complete-ConfigChange -Name $name -Value $value + # Save config with UTF8NoBOM encoding ConvertTo-Json $scoopConfig | Out-UTF8File -FilePath $configFile return $scoopConfig } +function Complete-ConfigChange { + [CmdletBinding()] + param ( + [Parameter(Mandatory, Position = 0)] + [string] + $Name, + [Parameter(Mandatory, Position = 1)] + [AllowNull()] + [string] + $Value + ) + + if ($Name -eq 'use_sqlite_cache' -and $Value) { + . "$PSScriptRoot\..\lib\database.ps1" + . "$PSScriptRoot\..\lib\manifest.ps1" + info 'SQLite cache is enabled.' + New-ScoopDB + info 'Initializing cache in progress... This may take a while, please wait.' + Set-ScoopDB + } +} + function setup_proxy() { # note: '@' and ':' in password must be escaped, e.g. 'p@ssword' -> p\@ssword' $proxy = get_config PROXY diff --git a/libexec/scoop-config.ps1 b/libexec/scoop-config.ps1 index dbc1925305..1dd28502b6 100644 --- a/libexec/scoop-config.ps1 +++ b/libexec/scoop-config.ps1 @@ -27,6 +27,9 @@ # use_lessmsi: $true|$false # Prefer lessmsi utility over native msiexec. # +# use_sqlite_cache: $true|$false +# Use SQLite database for caching. This is useful for speeding up 'scoop search' and 'scoop shim' commands. +# # no_junction: $true|$false # The 'current' version alias will not be used. Shims and shortcuts will point to specific version instead. # diff --git a/libexec/scoop-search.ps1 b/libexec/scoop-search.ps1 index 0af59074fa..7955de8847 100644 --- a/libexec/scoop-search.ps1 +++ b/libexec/scoop-search.ps1 @@ -11,12 +11,6 @@ param($query) $list = [System.Collections.Generic.List[PSCustomObject]]::new() -try { - $query = New-Object Regex $query, 'IgnoreCase' -} catch { - abort "Invalid regular expression: $($_.Exception.InnerException.Message)" -} - $githubtoken = Get-GitHubToken $authheader = @{} if ($githubtoken) { @@ -175,13 +169,33 @@ function search_remotes($query) { $remote_list } -$jsonTextAvailable = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { [System.IO.Path]::GetFileNameWithoutExtension($_.Location) -eq 'System.Text.Json' } +if (get_config USE_SQLITE_CACHE $false) { + . "$PSScriptRoot\..\lib\database.ps1" + Select-ScoopDBItem $query -From @('name', 'binary', 'shortcut') | + Select-Object -Property name, version, bucket, binary | + ForEach-Object { + $list.Add([PSCustomObject]@{ + Name = $_.name + Version = $_.version + Source = $_.bucket + Binaries = $_.binary + }) + } +} else { + try { + $query = New-Object Regex $query, 'IgnoreCase' + } catch { + abort "Invalid regular expression: $($_.Exception.InnerException.Message)" + } + + $jsonTextAvailable = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { [System.IO.Path]::GetFileNameWithoutExtension($_.Location) -eq 'System.Text.Json' } -Get-LocalBucket | ForEach-Object { - if ($jsonTextAvailable) { - search_bucket $_ $query - } else { - search_bucket_legacy $_ $query + Get-LocalBucket | ForEach-Object { + if ($jsonTextAvailable) { + search_bucket $_ $query + } else { + search_bucket_legacy $_ $query + } } } diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 0fce6c8064..fefbbe5324 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -23,6 +23,9 @@ . "$PSScriptRoot\..\lib\versions.ps1" . "$PSScriptRoot\..\lib\depends.ps1" . "$PSScriptRoot\..\lib\install.ps1" +if (get_config USE_SQLITE_CACHE $false) { + . "$PSScriptRoot\..\lib\database.ps1" +} $opt, $apps, $err = getopt $args 'gfiksqa' 'global', 'force', 'independent', 'no-cache', 'skip', 'quiet', 'all' if ($err) { "scoop update: $err"; exit 1 } @@ -177,6 +180,7 @@ function Sync-Bucket { $buckets | Where-Object { !$_.valid } | ForEach-Object { Write-Host "'$($_.name)' is not a git repository. Skipped." } + $updatedFiles = [System.Collections.ArrayList]::Synchronized([System.Collections.ArrayList]::new()) if ($PSVersionTable.PSVersion.Major -ge 7) { # Parallel parameter is available since PowerShell 7 $buckets | Where-Object { $_.valid } | ForEach-Object -ThrottleLimit 5 -Parallel { @@ -190,6 +194,13 @@ function Sync-Bucket { if ($using:Log) { Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit } + if (get_config USE_SQLITE_CACHE $false) { + Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', "$previousCommit..HEAD") | Where-Object { + $_ -match '^[^.].*\.json$' + } | ForEach-Object { + [void]($using:updatedFiles).Add($(Join-Path $bucketLoc $_)) + } + } } } else { $buckets | Where-Object { $_.valid } | ForEach-Object { @@ -201,8 +212,19 @@ function Sync-Bucket { if ($Log) { Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit } + if (get_config USE_SQLITE_CACHE $false) { + Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', "$previousCommit..HEAD") | Where-Object { + $_ -match '^[^.].*\.json$' + } | ForEach-Object { + [void]($updatedFiles).Add($(Join-Path $bucketLoc $_)) + } + } } } + if ((get_config USE_SQLITE_CACHE $false) -and ($updatedFiles.Count -gt 0)) { + info 'Updating cache...' + Set-ScoopDB -Path $updatedFiles + } } function update($app, $global, $quiet = $false, $independent, $suggested, $use_cache = $true, $check_hash = $true) { From e05cfcbc6fae836f610adca0f0d0e1c99db9078f Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Tue, 26 Mar 2024 17:33:18 +0800 Subject: [PATCH 04/14] Support installing old version from cache --- lib/manifest.ps1 | 16 +++++++++++++--- libexec/scoop-download.ps1 | 3 +++ libexec/scoop-install.ps1 | 3 +++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/manifest.ps1 b/lib/manifest.ps1 index f66755c6f4..4907740ec6 100644 --- a/lib/manifest.ps1 +++ b/lib/manifest.ps1 @@ -137,14 +137,24 @@ function generate_user_manifest($app, $bucket, $version) { warn "Given version ($version) does not match manifest ($($manifest.version))" warn "Attempting to generate manifest for '$app' ($version)" + ensure (usermanifestsdir) | Out-Null + $manifest_path = fullpath "$(usermanifestsdir)\$app.json" + + if (get_config USE_SQLITE_CACHE $false) { + $cached_manifest = (Get-ScoopDBItem -Name $app -Bucket $bucket -Version $version).manifest + if ($cached_manifest) { + $cached_manifest | Out-UTF8File $manifest_path + return $manifest_path + } + } + if (!($manifest.autoupdate)) { abort "'$app' does not have autoupdate capability`r`ncouldn't find manifest for '$app@$version'" } - ensure (usermanifestsdir) | out-null try { - Invoke-AutoUpdate $app "$(Convert-Path (usermanifestsdir))\$app.json" $manifest $version $(@{ }) - return Convert-Path (usermanifest $app) + Invoke-AutoUpdate $app $manifest_path $manifest $version $(@{ }) + return $manifest_path } catch { write-host -f darkred "Could not install $app@$version" } diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1 index ef43f8f41d..6c1232fbd9 100644 --- a/libexec/scoop-download.ps1 +++ b/libexec/scoop-download.ps1 @@ -24,6 +24,9 @@ . "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly) . "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest' . "$PSScriptRoot\..\lib\install.ps1" +if (get_config USE_SQLITE_CACHE $false) { + . "$PSScriptRoot\..\lib\database.ps1" +} $opt, $apps, $err = getopt $args 'fhua:' 'force', 'no-hash-check', 'no-update-scoop', 'arch=' if ($err) { error "scoop download: $err"; exit 1 } diff --git a/libexec/scoop-install.ps1 b/libexec/scoop-install.ps1 index 61cad28883..4b331d16be 100644 --- a/libexec/scoop-install.ps1 +++ b/libexec/scoop-install.ps1 @@ -31,6 +31,9 @@ . "$PSScriptRoot\..\lib\psmodules.ps1" . "$PSScriptRoot\..\lib\versions.ps1" . "$PSScriptRoot\..\lib\depends.ps1" +if (get_config USE_SQLITE_CACHE $false) { + . "$PSScriptRoot\..\lib\database.ps1" +} $opt, $apps, $err = getopt $args 'gikusa:' 'global', 'independent', 'no-cache', 'no-update-scoop', 'skip', 'arch=' if ($err) { "scoop install: $err"; exit 1 } From bba3ea9f3e03501299366571ef940e2e00a66a5a Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 27 Mar 2024 13:57:30 +0800 Subject: [PATCH 05/14] update chglog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70904eb80c..16da4fed61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ - **decompress:** Disable progress bar to improve `Expand-Archive` performance ([#5410](https://github.com/ScoopInstaller/Scoop/issues/5410)) - **scoop-search:** Improve performance for local search ([#5324](https://github.com/ScoopInstaller/Scoop/issues/5324)) - **shim:** Update kiennq-shim to v3.1.1 ([#5841](https://github.com/ScoopInstaller/Scoop/issues/5841), ([#5847](https://github.com/ScoopInstaller/Scoop/issues/5847))) +- **scoop-search:** Use SQLite for caching apps to speed up local search ([#5851](https://github.com/ScoopInstaller/Scoop/issues/5851)) ### Code Refactoring From f11a90aad48f262d53e3535e2d32b7caaa51930f Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 27 Mar 2024 17:13:08 +0800 Subject: [PATCH 06/14] fix test --- lib/core.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index d7efd82ec6..60760493ed 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -157,7 +157,7 @@ function Complete-ConfigChange { [string] $Name, [Parameter(Mandatory, Position = 1)] - [AllowNull()] + [AllowEmptyString()] [string] $Value ) From d5bde565db6e0ca25a09803a64ecb4affee2b438 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 27 Mar 2024 17:49:23 +0800 Subject: [PATCH 07/14] Remove `$false` in `get_config()` --- lib/manifest.ps1 | 2 +- libexec/scoop-download.ps1 | 2 +- libexec/scoop-install.ps1 | 2 +- libexec/scoop-search.ps1 | 2 +- libexec/scoop-update.ps1 | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/manifest.ps1 b/lib/manifest.ps1 index 4907740ec6..937c53f8df 100644 --- a/lib/manifest.ps1 +++ b/lib/manifest.ps1 @@ -140,7 +140,7 @@ function generate_user_manifest($app, $bucket, $version) { ensure (usermanifestsdir) | Out-Null $manifest_path = fullpath "$(usermanifestsdir)\$app.json" - if (get_config USE_SQLITE_CACHE $false) { + if (get_config USE_SQLITE_CACHE) { $cached_manifest = (Get-ScoopDBItem -Name $app -Bucket $bucket -Version $version).manifest if ($cached_manifest) { $cached_manifest | Out-UTF8File $manifest_path diff --git a/libexec/scoop-download.ps1 b/libexec/scoop-download.ps1 index 6c1232fbd9..a4ba10d36e 100644 --- a/libexec/scoop-download.ps1 +++ b/libexec/scoop-download.ps1 @@ -24,7 +24,7 @@ . "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly) . "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest' . "$PSScriptRoot\..\lib\install.ps1" -if (get_config USE_SQLITE_CACHE $false) { +if (get_config USE_SQLITE_CACHE) { . "$PSScriptRoot\..\lib\database.ps1" } diff --git a/libexec/scoop-install.ps1 b/libexec/scoop-install.ps1 index 4b331d16be..ab3c67055b 100644 --- a/libexec/scoop-install.ps1 +++ b/libexec/scoop-install.ps1 @@ -31,7 +31,7 @@ . "$PSScriptRoot\..\lib\psmodules.ps1" . "$PSScriptRoot\..\lib\versions.ps1" . "$PSScriptRoot\..\lib\depends.ps1" -if (get_config USE_SQLITE_CACHE $false) { +if (get_config USE_SQLITE_CACHE) { . "$PSScriptRoot\..\lib\database.ps1" } diff --git a/libexec/scoop-search.ps1 b/libexec/scoop-search.ps1 index 7955de8847..dfa225584d 100644 --- a/libexec/scoop-search.ps1 +++ b/libexec/scoop-search.ps1 @@ -169,7 +169,7 @@ function search_remotes($query) { $remote_list } -if (get_config USE_SQLITE_CACHE $false) { +if (get_config USE_SQLITE_CACHE) { . "$PSScriptRoot\..\lib\database.ps1" Select-ScoopDBItem $query -From @('name', 'binary', 'shortcut') | Select-Object -Property name, version, bucket, binary | diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index fefbbe5324..4037f44114 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -23,7 +23,7 @@ . "$PSScriptRoot\..\lib\versions.ps1" . "$PSScriptRoot\..\lib\depends.ps1" . "$PSScriptRoot\..\lib\install.ps1" -if (get_config USE_SQLITE_CACHE $false) { +if (get_config USE_SQLITE_CACHE) { . "$PSScriptRoot\..\lib\database.ps1" } @@ -194,7 +194,7 @@ function Sync-Bucket { if ($using:Log) { Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit } - if (get_config USE_SQLITE_CACHE $false) { + if (get_config USE_SQLITE_CACHE) { Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', "$previousCommit..HEAD") | Where-Object { $_ -match '^[^.].*\.json$' } | ForEach-Object { @@ -212,7 +212,7 @@ function Sync-Bucket { if ($Log) { Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit } - if (get_config USE_SQLITE_CACHE $false) { + if (get_config USE_SQLITE_CACHE) { Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', "$previousCommit..HEAD") | Where-Object { $_ -match '^[^.].*\.json$' } | ForEach-Object { @@ -221,7 +221,7 @@ function Sync-Bucket { } } } - if ((get_config USE_SQLITE_CACHE $false) -and ($updatedFiles.Count -gt 0)) { + if ((get_config USE_SQLITE_CACHE) -and ($updatedFiles.Count -gt 0)) { info 'Updating cache...' Set-ScoopDB -Path $updatedFiles } From 4fc76f7a73831cae8abb88dd1789aebc05e23270 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Mon, 1 Apr 2024 13:41:09 +0800 Subject: [PATCH 08/14] Fix bug if JSON file is not a manifest --- lib/database.ps1 | 68 +++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/lib/database.ps1 b/lib/database.ps1 index 8bc683058f..9ec70efaf0 100644 --- a/lib/database.ps1 +++ b/lib/database.ps1 @@ -202,44 +202,46 @@ function Set-ScoopDB { process { if ($Path.Count -eq 0) { $bucketPath = Get-LocalBucket | ForEach-Object { Join-Path $bucketsdir $_ } - $Path = (Get-ChildItem $bucketPath -Filter '*.json' -Recurse | Where-Object { $_.FullName -notmatch '[\\/]\.' }).FullName + $Path = (Get-ChildItem $bucketPath -Filter '*.json' -Recurse).FullName } $Path | ForEach-Object { $manifestRaw = [System.IO.File]::ReadAllText($_) $manifest = $manifestRaw | ConvertFrom-Json -ErrorAction Continue - $list.Add([pscustomobject]@{ - name = $($_ -replace '.*[\\/]([^\\/]+)\.json$', '$1') - description = if ($manifest.description) { $manifest.description } else { '' } - version = $manifest.version - bucket = $($_ -replace '.*buckets[\\/]([^\\/]+)(?:[\\/].*)', '$1') - manifest = $manifestRaw - binary = $( - $result = @() - @(arch_specific 'bin' $manifest $arch) | ForEach-Object { - if ($_ -is [System.Array]) { - $result += "$($_[1]).$($_[0].Split('.')[-1])" - } else { - $result += $_ + if ($null -ne $manifest.version) { + $list.Add([pscustomobject]@{ + name = $($_ -replace '.*[\\/]([^\\/]+)\.json$', '$1') + description = if ($manifest.description) { $manifest.description } else { '' } + version = $manifest.version + bucket = $($_ -replace '.*buckets[\\/]([^\\/]+)(?:[\\/].*)', '$1') + manifest = $manifestRaw + binary = $( + $result = @() + @(arch_specific 'bin' $manifest $arch) | ForEach-Object { + if ($_ -is [System.Array]) { + $result += "$($_[1]).$($_[0].Split('.')[-1])" + } else { + $result += $_ + } } - } - $result -replace '.*?([^\\/]+)?(\.(exe|bat|cmd|ps1|jar|py))$', '$1' -join ' | ' - ) - shortcut = $( - $result = @() - @(arch_specific 'shortcuts' $manifest $arch) | ForEach-Object { - $result += $_[1] - } - $result -replace '.*?([^\\/]+$)', '$1' -join ' | ' - ) - dependency = $manifest.depends -join ' | ' - suggest = $( - $suggest_output = @() - $manifest.suggest.PSObject.Properties | ForEach-Object { - $suggest_output += $_.Value -join ' | ' - } - $suggest_output -join ' | ' - ) - }) + $result -replace '.*?([^\\/]+)?(\.(exe|bat|cmd|ps1|jar|py))$', '$1' -join ' | ' + ) + shortcut = $( + $result = @() + @(arch_specific 'shortcuts' $manifest $arch) | ForEach-Object { + $result += $_[1] + } + $result -replace '.*?([^\\/]+$)', '$1' -join ' | ' + ) + dependency = $manifest.depends -join ' | ' + suggest = $( + $suggest_output = @() + $manifest.suggest.PSObject.Properties | ForEach-Object { + $suggest_output += $_.Value -join ' | ' + } + $suggest_output -join ' | ' + ) + }) + } } } end { From 35108c159819f84f702f5a433e40fe72740f8c78 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Mon, 1 Apr 2024 13:49:49 +0800 Subject: [PATCH 09/14] Add help message for `[query]` param --- libexec/scoop-search.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libexec/scoop-search.ps1 b/libexec/scoop-search.ps1 index dfa225584d..be044513c1 100644 --- a/libexec/scoop-search.ps1 +++ b/libexec/scoop-search.ps1 @@ -3,6 +3,8 @@ # Help: Searches for apps that are available to install. # # If used with [query], shows app names that match the query. +# - With 'use_sqlite_cache' enabled, [query] is partially matched against app names, binaries, and shortcuts. +# - Without 'use_sqlite_cache', [query] can be a regular expression to match against app names and binaries. # Without [query], shows all the available apps. param($query) From ae3722621c9e74fdc3ef25f9be8c158a13b22c73 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Mon, 1 Apr 2024 18:17:33 +0800 Subject: [PATCH 10/14] Fix param in switch function --- lib/core.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index 60760493ed..9be03e3510 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -162,7 +162,7 @@ function Complete-ConfigChange { $Value ) - if ($Name -eq 'use_sqlite_cache' -and $Value) { + if ($Name -eq 'use_sqlite_cache' -and $Value -eq $true) { . "$PSScriptRoot\..\lib\database.ps1" . "$PSScriptRoot\..\lib\manifest.ps1" info 'SQLite cache is enabled.' From 2b6957ff970df05c4ac02e45df34506ed61d4f94 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 3 Apr 2024 16:13:21 +0800 Subject: [PATCH 11/14] Fix bugs while supporting/sqlite is removed by accident --- lib/core.ps1 | 4 +--- lib/database.ps1 | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/core.ps1 b/lib/core.ps1 index 9be03e3510..1d7c5e3685 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -165,9 +165,7 @@ function Complete-ConfigChange { if ($Name -eq 'use_sqlite_cache' -and $Value -eq $true) { . "$PSScriptRoot\..\lib\database.ps1" . "$PSScriptRoot\..\lib\manifest.ps1" - info 'SQLite cache is enabled.' - New-ScoopDB - info 'Initializing cache in progress... This may take a while, please wait.' + info 'Initializing SQLite cache in progress... This may take a while, please wait.' Set-ScoopDB } } diff --git a/lib/database.ps1 b/lib/database.ps1 index 9ec70efaf0..d098210296 100644 --- a/lib/database.ps1 +++ b/lib/database.ps1 @@ -82,12 +82,10 @@ function Close-ScoopDB { #> function New-ScoopDB ([switch]$PassThru) { # Load System.Data.SQLite - try { - [Void][System.Data.SQLite.SQLiteConnection] - } catch { + if (!('System.Data.SQLite.SQLiteConnection' -as [Type])) { try { if (!(Test-Path -Path "$PSScriptRoot\..\supporting\sqlite\System.Data.SQLite.dll")) { - Get-SQLite + Get-SQLite | Out-Null } Add-Type -Path "$PSScriptRoot\..\supporting\sqlite\System.Data.SQLite.dll" } catch { From 27687dc5cfe5c297732ee4ea00285827acb1e44a Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Mon, 8 Apr 2024 10:34:04 +0800 Subject: [PATCH 12/14] Omit deleted files --- libexec/scoop-update.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 4037f44114..cda4f08896 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -195,7 +195,7 @@ function Sync-Bucket { Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit } if (get_config USE_SQLITE_CACHE) { - Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', "$previousCommit..HEAD") | Where-Object { + Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', '--diff-filter=d', $previousCommit) | Where-Object { $_ -match '^[^.].*\.json$' } | ForEach-Object { [void]($using:updatedFiles).Add($(Join-Path $bucketLoc $_)) @@ -213,7 +213,7 @@ function Sync-Bucket { Invoke-GitLog -Path $bucketLoc -Name $name -CommitHash $previousCommit } if (get_config USE_SQLITE_CACHE) { - Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', "$previousCommit..HEAD") | Where-Object { + Invoke-Git -Path $bucketLoc -ArgumentList @('diff', '--name-only', '--diff-filter=d', $previousCommit) | Where-Object { $_ -match '^[^.].*\.json$' } | ForEach-Object { [void]($updatedFiles).Add($(Join-Path $bucketLoc $_)) From 32d941e277d85208b80ba9ae6cf284f9c11002c9 Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Wed, 10 Apr 2024 13:51:07 +0800 Subject: [PATCH 13/14] Use 'return' explicitly --- lib/database.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/database.ps1 b/lib/database.ps1 index d098210296..059e36d9aa 100644 --- a/lib/database.ps1 +++ b/lib/database.ps1 @@ -113,7 +113,7 @@ function New-ScoopDB ([switch]$PassThru) { $tableCommand.ExecuteNonQuery() | Out-Null $tableCommand.Dispose() if ($PassThru) { - $db + return $db } else { $db.Dispose() } From 867ed69fd2dc6cbbaefa9c20eb1301f86c81850f Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Fri, 19 Apr 2024 00:41:30 +0800 Subject: [PATCH 14/14] Sync develop --- CHANGELOG.md | 1 - lib/core.ps1 | 3 --- lib/manifest.ps1 | 10 +++++----- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82264e6377..8b6c2957d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,6 @@ - **scoop-update:** Check for running process before wasting time on download ([#5799](https://github.com/ScoopInstaller/Scoop/issues/5799)) - **decompress:** Disable progress bar to improve `Expand-Archive` performance ([#5410](https://github.com/ScoopInstaller/Scoop/issues/5410)) - **shim:** Update kiennq-shim to v3.1.1 ([#5841](https://github.com/ScoopInstaller/Scoop/issues/5841), [#5847](https://github.com/ScoopInstaller/Scoop/issues/5847)) -- **scoop-search:** Use SQLite for caching apps to speed up local search ([#5851](https://github.com/ScoopInstaller/Scoop/issues/5851)) ### Code Refactoring diff --git a/lib/core.ps1 b/lib/core.ps1 index 330583fdeb..f86f9956c9 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -145,9 +145,6 @@ function set_config { $scoopConfig.PSObject.Properties.Remove($name) } - # Initialize config's change - Complete-ConfigChange -Name $name -Value $value - # Save config with UTF8NoBOM encoding ConvertTo-Json $scoopConfig | Out-UTF8File -FilePath $configFile return $scoopConfig diff --git a/lib/manifest.ps1 b/lib/manifest.ps1 index 937c53f8df..9ca618158b 100644 --- a/lib/manifest.ps1 +++ b/lib/manifest.ps1 @@ -23,7 +23,7 @@ function url_manifest($url) { } catch { throw } - if(!$str) { return $null } + if (!$str) { return $null } try { $str | ConvertFrom-Json -ErrorAction Stop } catch { @@ -138,7 +138,7 @@ function generate_user_manifest($app, $bucket, $version) { warn "Attempting to generate manifest for '$app' ($version)" ensure (usermanifestsdir) | Out-Null - $manifest_path = fullpath "$(usermanifestsdir)\$app.json" + $manifest_path = "$(usermanifestsdir)\$app.json" if (get_config USE_SQLITE_CACHE) { $cached_manifest = (Get-ScoopDBItem -Name $app -Bucket $bucket -Version $version).manifest @@ -156,7 +156,7 @@ function generate_user_manifest($app, $bucket, $version) { Invoke-AutoUpdate $app $manifest_path $manifest $version $(@{ }) return $manifest_path } catch { - write-host -f darkred "Could not install $app@$version" + Write-Host -ForegroundColor DarkRed "Could not install $app@$version" } return $null @@ -166,5 +166,5 @@ function url($manifest, $arch) { arch_specific 'url' $manifest $arch } function installer($manifest, $arch) { arch_specific 'installer' $manifest $arch } function uninstaller($manifest, $arch) { arch_specific 'uninstaller' $manifest $arch } function hash($manifest, $arch) { arch_specific 'hash' $manifest $arch } -function extract_dir($manifest, $arch) { arch_specific 'extract_dir' $manifest $arch} -function extract_to($manifest, $arch) { arch_specific 'extract_to' $manifest $arch} +function extract_dir($manifest, $arch) { arch_specific 'extract_dir' $manifest $arch } +function extract_to($manifest, $arch) { arch_specific 'extract_to' $manifest $arch }