Skip to content

Commit

Permalink
Merge branch 'develop' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
niheaven authored May 14, 2024
2 parents ea9faac + f6f46f6 commit cf642b8
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 138 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@

### 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), [#5946](https://github.com/ScoopInstaller/Scoop/issues/5946), [#5948](https://github.com/ScoopInstaller/Scoop/issues/5948))
- **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), [#5946](https://github.com/ScoopInstaller/Scoop/issues/5946), [#5949](https://github.com/ScoopInstaller/Scoop/issues/5949), [#5955](https://github.com/ScoopInstaller/Scoop/issues/5955), [#5966](https://github.com/ScoopInstaller/Scoop/issues/5966))
- **core:** New cache filename format ([#5929](https://github.com/ScoopInstaller/Scoop/issues/5929))

### Bug Fixes

- **json:** Serialize jsonpath return ([#5921](https://github.com/ScoopInstaller/Scoop/issues/5921))
- **scoop-search:** Catch error of parsing invalid manifest ([#5930](https://github.com/ScoopInstaller/Scoop/issues/5930))
- **autoupdate:** Copy `PSCustomObject`-type properties within `autoupdate` to prevent reference changes ([#5934](https://github.com/ScoopInstaller/Scoop/issues/5934))
- **autoupdate:** Copy `PSCustomObject`-type properties within `substitute()` to prevent reference changes ([#5934](https://github.com/ScoopInstaller/Scoop/issues/5934), [#5962](https://github.com/ScoopInstaller/Scoop/issues/5962))
- **system:** Fix argument passing to `Split-PathLikeEnvVar()` in deprecated `strip_path()` ([#5937](https://github.com/ScoopInstaller/Scoop/issues/5937))
- **scoop-cache:** Fix regression in 36026f18 ([#5944](https://github.com/ScoopInstaller/Scoop/issues/5944))
- **scoop-download|install|update:** Use consistent options ([#5956](https://github.com/ScoopInstaller/Scoop/issues/5956))
- **core:** Fix "Invoke-ExternalCommand" quoting rules ([#5945](https://github.com/ScoopInstaller/Scoop/issues/5945))
- **scoop-info:** Fix download size estimating ([#5958](https://github.com/ScoopInstaller/Scoop/issues/5958))

### Code Refactoring

- **install:** Separate archive extraction from downloader ([#5951](https://github.com/ScoopInstaller/Scoop/issues/5951))

## [v0.4.1](https://github.com/ScoopInstaller/Scoop/compare/v0.4.0...v0.4.1) - 2024-04-25

Expand Down
2 changes: 1 addition & 1 deletion lib/autoupdate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ function Update-ManifestProperty {
}
} elseif ($Manifest.$currentProperty -and $Manifest.autoupdate.$currentProperty) {
# Update other property (global)
$autoupdateProperty = $Manifest.autoupdate.$currentProperty.PSObject.Copy()
$autoupdateProperty = $Manifest.autoupdate.$currentProperty
$newValue = substitute $autoupdateProperty $Substitutions
if (($autoupdateProperty.GetType().Name -eq 'Object[]') -and ($autoupdateProperty.Length -eq 1)) {
# Make sure it's an array
Expand Down
2 changes: 1 addition & 1 deletion lib/buckets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function add_bucket($name, $repo) {
Write-Host 'OK'
if (get_config USE_SQLITE_CACHE) {
info 'Updating cache...'
Set-ScoopDB -Path (Get-ChildItem -Path $dir -Filter '*.json' -Recurse).FullName
Set-ScoopDB -Path (Get-ChildItem (Find-BucketDirectory $name) -Filter '*.json' -Recurse).FullName
}
success "The $name bucket was added successfully."
return 0
Expand Down
46 changes: 25 additions & 21 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -771,31 +771,35 @@ function Invoke-ExternalCommand {
$Process.StartInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
}
if ($ArgumentList.Length -gt 0) {
$ArgumentList = $ArgumentList | ForEach-Object { [regex]::Split($_.Replace('"', ''), '(?<=(?<![:\w])[/-]\w+) | (?=[/-])') }
# Use legacy argument escaping for commands having non-standard behavior
# with regard to argument passing. `msiexec` requires some args like
# `TARGETDIR="C:\Program Files"`, which is non-standard, therefore we
# treat it as a legacy command.
# Remove existing double quotes and split arguments
# '(?<=(?<![:\w])[/-]\w+) ' matches a space after a command line switch starting with a slash ('/') or a hyphen ('-')
# The inner item '(?<![:\w])[/-]' matches a slash ('/') or a hyphen ('-') not preceded by a colon (':') or a word character ('\w')
# so that it must be a command line switch, otherwise, it would be a path (e.g. 'C:/Program Files') or other word (e.g. 'some-arg')
# ' (?=[/-])' matches a space followed by a slash ('/') or a hyphen ('-'), i.e. the space before a command line switch
$ArgumentList = $ArgumentList.ForEach({ $_ -replace '"' -split '(?<=(?<![:\w])[/-]\w+) | (?=[/-])' })
# Use legacy argument escaping for commands having non-standard behavior with regard to argument passing.
# `msiexec` requires some args like `TARGETDIR="C:\Program Files"`, which is non-standard, therefore we treat it as a legacy command.
# NSIS installer's '/D' param may not work with the ArgumentList property, so we need to escape arguments manually.
# ref-1: https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features?view=powershell-7.4#psnativecommandargumentpassing
$LegacyCommand = $FilePath -match '^((cmd|cscript|find|sqlcmd|wscript|msiexec)(\.exe)?|.*\.(bat|cmd|js|vbs|wsf))$'
# ref-2: https://nsis.sourceforge.io/Docs/Chapter3.html
$LegacyCommand = $FilePath -match '^((cmd|cscript|find|sqlcmd|wscript|msiexec)(\.exe)?|.*\.(bat|cmd|js|vbs|wsf))$' -or
($ArgumentList -match '^/S$|^/D=[A-Z]:[\\/].*$').Length -eq 2
$SupportArgumentList = $Process.StartInfo.PSObject.Properties.Name -contains 'ArgumentList'
if ((-not $LegacyCommand) -and $SupportArgumentList) {
# ArgumentList is supported in PowerShell 6.1 and later (built on .NET Core 2.1+)
# ref-1: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.argumentlist?view=net-6.0
# ref-2: https://docs.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.2#net-framework-vs-net-core
$ArgumentList | ForEach-Object { $Process.StartInfo.ArgumentList.Add($_) }
$ArgumentList.ForEach({ $Process.StartInfo.ArgumentList.Add($_) })
} else {
# escape arguments manually in lower versions, refer to https://docs.microsoft.com/en-us/previous-versions/17w5ykft(v=vs.85)
$escapedArgs = $ArgumentList | ForEach-Object {
# escape N consecutive backslash(es), which are followed by a double quote or at the end of the string, to 2N consecutive ones
$s = $_ -replace '(\\+)(""|$)', '$1$1$2'
# quote the path if it contains spaces and is not NSIS's '/D' argument
# ref: https://nsis.sourceforge.io/Docs/Chapter3.html
if ($s -match ' ' -and $s -notmatch '/D=[A-Z]:[\\/].*') {
$s -replace '([A-Z]:[\\/].*)', '"$1"'
} else {
$s
}
# Escape arguments manually in lower versions
$escapedArgs = switch -regex ($ArgumentList) {
# Quote paths starting with a drive letter
'(?<!/D=)[A-Z]:[\\/].*' { $_ -replace '([A-Z]:[\\/].*)', '"$1"'; continue }
# Do not quote paths if it is NSIS's '/D' argument
'/D=[A-Z]:[\\/].*' { $_; continue }
# Quote args with spaces
' ' { "`"$_`""; continue }
default { $_; continue }
}
$Process.StartInfo.Arguments = $escapedArgs -join ' '
}
Expand Down Expand Up @@ -1246,8 +1250,8 @@ function Test-ScoopCoreOnHold() {
}

function substitute($entity, [Hashtable] $params, [Bool]$regexEscape = $false) {
$newentity = $entity
if ($null -ne $newentity) {
if ($null -ne $entity) {
$newentity = $entity.PSObject.Copy()
switch ($entity.GetType().Name) {
'String' {
$params.GetEnumerator() | ForEach-Object {
Expand All @@ -1259,7 +1263,7 @@ function substitute($entity, [Hashtable] $params, [Bool]$regexEscape = $false) {
}
}
'Object[]' {
$newentity = $entity | ForEach-Object { ,(substitute $_ $params $regexEscape) }
$newentity = $entity | ForEach-Object { , (substitute $_ $params $regexEscape) }
}
'PSCustomObject' {
$newentity.PSObject.Properties | ForEach-Object { $_.Value = substitute $_.Value $params $regexEscape }
Expand Down
57 changes: 13 additions & 44 deletions lib/database.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,47 +40,16 @@ function Get-SQLite {

<#
.SYNOPSIS
Close a SQLite database.
Open Scoop 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.
Open Scoop SQLite database connection and create the necessary tables if not exists.
.INPUTS
None
.OUTPUTS
None
Default
System.Data.SQLite.SQLiteConnection
The SQLite database connection if **PassThru** is used.
#>
function New-ScoopDB ([switch]$PassThru) {
function Open-ScoopDB {
# Load System.Data.SQLite
if (!('System.Data.SQLite.SQLiteConnection' -as [Type])) {
try {
Expand Down Expand Up @@ -112,11 +81,7 @@ function New-ScoopDB ([switch]$PassThru) {
)"
$tableCommand.ExecuteNonQuery() | Out-Null
$tableCommand.Dispose()
if ($PassThru) {
return $db
} else {
$db.Dispose()
}
return $db
}

<#
Expand All @@ -141,7 +106,7 @@ function Set-ScoopDBItem {
)

begin {
$db = New-ScoopDB -PassThru
$db = Open-ScoopDB
$dbTrans = $db.BeginTransaction()
# TODO Support [hashtable]$InputObject
$colName = @($InputObject | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name)
Expand All @@ -164,6 +129,8 @@ function Set-ScoopDBItem {
$dbTrans.Rollback()
throw $_
} finally {
$dbCommand.Dispose()
$dbTrans.Dispose()
$db.Dispose()
}
}
Expand Down Expand Up @@ -199,10 +166,10 @@ function Set-ScoopDB {
}
process {
if ($Path.Count -eq 0) {
$bucketPath = Get-LocalBucket | ForEach-Object { Join-Path $bucketsdir $_ }
$bucketPath = Get-LocalBucket | ForEach-Object { Find-BucketDirectory $_ }
$Path = (Get-ChildItem $bucketPath -Filter '*.json' -Recurse).FullName
}
$Path | Where-Object { $_ -notmatch '[\\/]\.|[\\/]deprecated[\\/]' } | ForEach-Object {
$Path | ForEach-Object {
$manifestRaw = [System.IO.File]::ReadAllText($_)
$manifest = ConvertFrom-Json $manifestRaw -ErrorAction SilentlyContinue
if ($null -ne $manifest.version) {
Expand Down Expand Up @@ -277,7 +244,7 @@ function Select-ScoopDBItem {
)

begin {
$db = New-ScoopDB -PassThru
$db = Open-ScoopDB
$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')"
Expand All @@ -292,6 +259,7 @@ function Select-ScoopDBItem {
[void]$dbAdapter.Fill($result)
}
end {
$dbAdapter.Dispose()
$db.Dispose()
return $result
}
Expand Down Expand Up @@ -332,7 +300,7 @@ function Get-ScoopDBItem {
)

begin {
$db = New-ScoopDB -PassThru
$db = Open-ScoopDB
$dbAdapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter
$result = New-Object System.Data.DataTable
$dbQuery = 'SELECT * FROM app WHERE name = @Name AND bucket = @Bucket'
Expand All @@ -353,6 +321,7 @@ function Get-ScoopDBItem {
[void]$dbAdapter.Fill($result)
}
end {
$dbAdapter.Dispose()
$db.Dispose()
return $result
}
Expand Down
70 changes: 69 additions & 1 deletion lib/decompress.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,71 @@
# Description: Functions for decompressing archives or installers

function Invoke-Extraction {
param (
[string]
$Path,
[string[]]
$Name,
[psobject]
$Manifest,
[Alias('Arch', 'Architecture')]
[string]
$ProcessorArchitecture
)

# 'url', 'extract_dir' and 'extract_to' are paired
$uri = @(url $Manifest $ProcessorArchitecture)
$extractDir = @(extract_dir $Manifest $ProcessorArchitecture)
$extractTo = @(extract_to $Manifest $ProcessorArchitecture)

for ($i = 0; $i -lt $Name.Length; $i++) {
$fnArgs = @{
Path = Join-Path $Path $Name[$i]
DestinationPath = Join-Path $Path $extractTo[$i]
ExtractDir = $extractDir[$i]
}
# work out extraction method, if applicable
$extractFn = $null
switch -regex ($fnArgs.Path) {
'\.zip$' {
if ((Test-HelperInstalled -Helper 7zip) -or ((get_config 7ZIPEXTRACT_USE_EXTERNAL) -and (Test-CommandAvailable 7z))) {
$extractFn = 'Expand-7zipArchive'
} else {
$extractFn = 'Expand-ZipArchive'
}
continue
}
'\.msi$' {
$extractFn = 'Expand-MsiArchive'
continue
}
'\.exe$' {
if ($Manifest.innosetup) {
$extractFn = 'Expand-InnoArchive'
}
continue
}
{ Test-ZstdRequirement -Uri $_ } {
# Check Zstd first
$extractFn = 'Expand-ZstdArchive'
continue
}
{ Test-7zipRequirement -Uri $_ } {
# Then check 7zip
$extractFn = 'Expand-7zipArchive'
continue
}
}
if ($extractFn) {
Write-Host 'Extracting ' -NoNewline
Write-Host $(url_remote_filename $uri[$i]) -ForegroundColor Cyan -NoNewline
Write-Host ' ... ' -NoNewline
& $extractFn @fnArgs -Removal
Write-Host 'done.' -ForegroundColor Green
}
}
}

function Expand-7zipArchive {
[CmdletBinding()]
param (
Expand Down Expand Up @@ -156,7 +224,7 @@ function Expand-MsiArchive {
$ArgList = @('x', $Path, "$DestinationPath\")
} else {
$MsiPath = 'msiexec.exe'
$ArgList = @('/a', "`"$Path`"", '/qn', "TARGETDIR=`"$DestinationPath\SourceDir`"")
$ArgList = @('/a', $Path, '/qn', "TARGETDIR=$DestinationPath\SourceDir")
}
$LogPath = "$(Split-Path $Path)\msi.log"
if ($Switches) {
Expand Down
Loading

0 comments on commit cf642b8

Please sign in to comment.