Skip to content

Commit 5b1221c

Browse files
committed
feat(search): Add search index cache infrastructure
Add init_search_cache() and build_search_cache() functions that create and validate a JSON-based binary index stored at $scoopdir/search-cache.json. The cache maps every app name to its file path and bucket, and every binary name (without extension) to the app(s) that expose it. Staleness is detected via timestamp (<24h) and file-count cross-check using the same recursive Get-ChildItem enumeration as the regex path.
1 parent b588a06 commit 5b1221c

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

libexec/scoop-search.ps1

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,83 @@ param($query)
1414

1515
$list = [System.Collections.Generic.List[PSCustomObject]]::new()
1616

17+
# === Search index cache (JSON-based, faster than SQLite) ===
18+
$searchCachePath = Join-Path $scoopdir 'search-cache.json'
19+
$searchIndexApps = $null
20+
$searchIndexBins = $null
21+
22+
function init_search_cache {
23+
if (-not (Test-Path $searchCachePath)) { return $false }
24+
try {
25+
$cache = Get-Content $searchCachePath -Raw | ConvertFrom-Json -ErrorAction Stop
26+
$cacheAge = (Get-Date) - [datetime]::Parse($cache.timestamp)
27+
if ($cacheAge.TotalHours -ge 24) { return $false }
28+
# Cross-check file count for staleness
29+
$currentCount = 0
30+
Get-LocalBucket | ForEach-Object {
31+
$dir = Find-BucketDirectory $_
32+
$currentCount += (Get-ChildItem $dir -Filter '*.json' -Recurse -ErrorAction SilentlyContinue).Count
33+
}
34+
if ($cache.fileCount -ne $currentCount) { return $false }
35+
$script:searchIndexApps = @{}
36+
foreach ($prop in $cache.apps.PSObject.Properties) {
37+
$script:searchIndexApps[$prop.Name] = @{ path = $prop.Value.path; bucket = $prop.Value.bucket }
38+
}
39+
$script:searchIndexBins = @{}
40+
foreach ($prop in $cache.bins.PSObject.Properties) {
41+
$script:searchIndexBins[$prop.Name] = @($prop.Value)
42+
}
43+
return $true
44+
} catch { return $false }
45+
}
46+
47+
function build_search_cache {
48+
$allPathsByBucket = @{}
49+
Get-LocalBucket | ForEach-Object {
50+
$dir = Find-BucketDirectory $_
51+
$paths = @(Get-ChildItem $dir -Filter '*.json' -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName })
52+
if ($paths.Count -gt 0) { $allPathsByBucket[$_] = $paths }
53+
}
54+
$totalCount = ($allPathsByBucket.Values | ForEach-Object { $_.Count } | Measure-Object -Sum).Sum
55+
$newApps = @{}
56+
$newBins = @{}
57+
58+
foreach ($bucket in $allPathsByBucket.Keys) {
59+
foreach ($filePath in $allPathsByBucket[$bucket]) {
60+
$appName = [System.IO.Path]::GetFileNameWithoutExtension($filePath)
61+
$newApps[$appName] = @{ path = $filePath; bucket = $bucket }
62+
try {
63+
$manifest = Get-Content -Path $filePath -Raw | ConvertFrom-Json -ErrorAction Stop
64+
if (-not $manifest.bin) { continue }
65+
foreach ($binEntry in $manifest.bin) {
66+
$exe = $null; $alias = $null
67+
if ($binEntry -is [System.Object[]]) {
68+
$exe = $binEntry[0]
69+
$alias = if ($binEntry.Count -gt 1) { $binEntry[1] } else { $null }
70+
} else { $exe = $binEntry }
71+
$exeName = [System.IO.Path]::GetFileNameWithoutExtension([string]$exe).ToLower()
72+
if ($exeName) {
73+
if (-not $newBins.ContainsKey($exeName)) { $newBins[$exeName] = @() }
74+
if ($appName -notin $newBins[$exeName]) { $newBins[$exeName] += $appName }
75+
}
76+
if ($alias) {
77+
$aliasName = $alias.ToLower()
78+
if ($aliasName) {
79+
if (-not $newBins.ContainsKey($aliasName)) { $newBins[$aliasName] = @() }
80+
if ($appName -notin $newBins[$aliasName]) { $newBins[$aliasName] += $appName }
81+
}
82+
}
83+
}
84+
} catch { }
85+
}
86+
}
87+
$cacheData = [PSCustomObject]@{ timestamp = (Get-Date).ToString('o'); fileCount = $totalCount; apps = [PSCustomObject]$newApps; bins = [PSCustomObject]$newBins }
88+
$cacheData | ConvertTo-Json -Compress -Depth 4 | Set-Content $searchCachePath -Encoding UTF8
89+
$script:searchIndexApps = $newApps
90+
$script:searchIndexBins = $newBins
91+
return $true
92+
}
93+
1794
function bin_match($manifest, $query) {
1895
if (!$manifest.bin) { return $false }
1996
$bins = foreach ($bin in $manifest.bin) {

0 commit comments

Comments
 (0)