Skip to content

Commit ae15c97

Browse files
committed
✨ [feat] Enhance cache metadata management and script inventory retrieval
- 📝 Add Write-CacheMetadataFile function to manage cache metadata files without purging cache entries. - 🔧 Update Initialize-CacheDirectory to refresh metadata marker based on cache entries' timestamps. - ⚡ Improve Get-ColorScriptInventory by introducing a new internal function to retrieve script files more reliably. - 🛠️ Modify Get-ColorScriptsConfigurationRoot to allow non-destructive validation and prevent cache directory creation if not needed. - 🔄 Update New-ColorScriptCache and Show-ColorScript to ensure cache metadata is updated after cache operations. - 🧪 Add tests to ensure cache entries are preserved during validation and that metadata files are correctly created and updated. - 🌍 Update localization help files for multiple languages to reflect the latest version. Signed-off-by: Nick2bad4u <20943337+Nick2bad4u@users.noreply.github.com>
1 parent 5f6bf95 commit ae15c97

23 files changed

Lines changed: 647 additions & 275 deletions

ColorScripts-Enhanced/ColorScripts-Enhanced.psd1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
#
44
# Generated by: Nick2bad4u
55
#
6-
# Generated on: 12/8/2025
6+
# Generated on: 12/15/2025
77
#
88

99
@{
1010
# Script module or binary module file associated with this manifest.
1111
RootModule = 'ColorScripts-Enhanced.psm1'
1212

1313
# Version number of this module.
14-
ModuleVersion = '2025.12.08.1711'
14+
ModuleVersion = '2025.12.15.0210'
1515

1616
# Supported PSEditions
1717
CompatiblePSEditions = @('Desktop', 'Core')
@@ -211,7 +211,7 @@ PERFECT FOR
211211

212212
# ReleaseNotes of this module
213213
ReleaseNotes = @'
214-
Version 2025.12.08.1711:
214+
Version 2025.12.15.0210:
215215
- Enhanced caching system with OS-wide cache in AppData
216216
- 6-19x performance improvement
217217
- Cache stored in centralized location

ColorScripts-Enhanced/ColorScripts-Enhanced.psm1

Lines changed: 76 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ $script:ModuleTraceUseDebug = $false
4949
$script:ModuleTraceUseFile = $false
5050
$script:ModuleTraceFile = $null
5151
$script:ModuleTraceWriteFailureNotified = $false
52+
$script:ModuleTraceStopwatch = $null
5253

5354
if (-not [string]::IsNullOrWhiteSpace($traceSetting)) {
5455
$script:ModuleTraceEnabled = $true
@@ -112,6 +113,8 @@ if ($script:ModuleTraceEnabled) {
112113
Write-Verbose ("Unable to prepare trace directory '{0}': {1}" -f $script:ModuleTraceFile, $_.Exception.Message)
113114
}
114115
}
116+
117+
$script:ModuleTraceStopwatch = [System.Diagnostics.Stopwatch]::StartNew()
115118
}
116119

117120
function Write-ModuleTrace {
@@ -124,17 +127,22 @@ function Write-ModuleTrace {
124127
return
125128
}
126129

130+
$messageToWrite = $Message
131+
if ($script:ModuleTraceStopwatch) {
132+
$messageToWrite = ('{0,6}ms | {1}' -f $script:ModuleTraceStopwatch.ElapsedMilliseconds, $Message)
133+
}
134+
127135
if ($script:ModuleTraceUseDebug) {
128-
Write-Debug $Message
136+
Write-Debug $messageToWrite
129137
}
130138

131139
if ($script:ModuleTraceUseVerbose) {
132-
Write-Verbose $Message
140+
Write-Verbose $messageToWrite
133141
}
134142

135143
if ($script:ModuleTraceUseFile -and $script:ModuleTraceFile) {
136144
try {
137-
$Message | Out-File -FilePath $script:ModuleTraceFile -Encoding utf8 -Append
145+
$messageToWrite | Out-File -FilePath $script:ModuleTraceFile -Encoding utf8 -Append
138146
}
139147
catch {
140148
if (-not $script:ModuleTraceWriteFailureNotified) {
@@ -148,61 +156,79 @@ function Write-ModuleTrace {
148156
Write-ModuleTrace ('--- Import begin: {0} ---' -f (Get-Date -Format o))
149157

150158
$moduleInfo = $ExecutionContext.SessionState.Module
151-
$moduleRootCandidates = @()
159+
160+
$moduleRootCandidates = New-Object System.Collections.Generic.List[string]
161+
$environmentRoot = $env:COLOR_SCRIPTS_ENHANCED_MODULE_ROOT
162+
if (-not [string]::IsNullOrWhiteSpace($environmentRoot)) {
163+
$null = $moduleRootCandidates.Add($environmentRoot)
164+
}
165+
166+
if ($PSScriptRoot) {
167+
$null = $moduleRootCandidates.Add($PSScriptRoot)
168+
}
152169

153170
if ($moduleInfo) {
154171
if ($moduleInfo.ModuleBase) {
155-
$moduleRootCandidates += $moduleInfo.ModuleBase
172+
$null = $moduleRootCandidates.Add($moduleInfo.ModuleBase)
156173
}
157174

158175
if ($moduleInfo.Path) {
159-
$moduleRootCandidates += (Split-Path -Path $moduleInfo.Path -Parent)
176+
$null = $moduleRootCandidates.Add((Split-Path -Path $moduleInfo.Path -Parent))
160177
}
161178
}
162179

163-
if ($PSScriptRoot) {
164-
$moduleRootCandidates += $PSScriptRoot
165-
}
166-
167-
$availableModule = Get-Module -ListAvailable -Name 'ColorScripts-Enhanced' | Select-Object -First 1
168-
if ($availableModule -and $availableModule.ModuleBase) {
169-
$moduleRootCandidates += $availableModule.ModuleBase
170-
}
180+
$uniqueModuleRootCandidates = New-Object System.Collections.Generic.List[string]
181+
$moduleRootSeen = New-Object 'System.Collections.Generic.HashSet[string]' ([System.StringComparer]::OrdinalIgnoreCase)
182+
foreach ($candidate in $moduleRootCandidates) {
183+
if ([string]::IsNullOrWhiteSpace($candidate)) {
184+
continue
185+
}
171186

172-
$environmentRoot = $env:COLOR_SCRIPTS_ENHANCED_MODULE_ROOT
173-
if ($environmentRoot) {
174-
$moduleRootCandidates += $environmentRoot
187+
if ($moduleRootSeen.Add($candidate)) {
188+
$null = $uniqueModuleRootCandidates.Add($candidate)
189+
}
175190
}
176191

177-
Write-ModuleTrace ('Initial module root candidates: {0}' -f ($moduleRootCandidates -join ';'))
192+
$moduleRootCandidates = $uniqueModuleRootCandidates.ToArray()
193+
Write-ModuleTrace ('Module root candidates: {0}' -f ($moduleRootCandidates -join ';'))
178194

179-
$resolvedCandidates = @()
195+
$script:ModuleRoot = $null
180196
foreach ($candidate in $moduleRootCandidates) {
181-
if ([string]::IsNullOrWhiteSpace($candidate)) { continue }
197+
$resolvedCandidate = $candidate
182198
try {
183199
$resolvedCandidate = (Resolve-Path -LiteralPath $candidate -ErrorAction Stop).ProviderPath
184-
if ($resolvedCandidate -and ($resolvedCandidates -notcontains $resolvedCandidate)) {
185-
$resolvedCandidates += $resolvedCandidate
186-
}
187200
}
188201
catch {
189-
continue
202+
$resolvedCandidate = $candidate
190203
}
204+
205+
if ($resolvedCandidate -and (Test-Path -LiteralPath $resolvedCandidate -PathType Container)) {
206+
$script:ModuleRoot = $resolvedCandidate
207+
break
208+
}
209+
}
210+
211+
if (-not $script:ModuleRoot -and $PSScriptRoot) {
212+
$script:ModuleRoot = $PSScriptRoot
191213
}
192214

193-
$moduleRootCandidates = $resolvedCandidates
194-
Write-ModuleTrace ('Resolved module root candidates: {0}' -f ($moduleRootCandidates -join ';'))
215+
$selectedModuleRoot = if ($script:ModuleRoot) { $script:ModuleRoot } else { 'n/a' }
216+
Write-ModuleTrace ('Module root candidate selected: {0}' -f $selectedModuleRoot)
195217

196-
$cultureFallback = @()
218+
$cultureFallback = New-Object System.Collections.Generic.List[string]
219+
$cultureSeen = New-Object 'System.Collections.Generic.HashSet[string]' ([System.StringComparer]::OrdinalIgnoreCase)
197220
try {
198221
$currentCulture = [System.Globalization.CultureInfo]::CurrentUICulture
199222
}
200223
catch {
201224
$currentCulture = $null
202225
}
203226

204-
while ($currentCulture -and $currentCulture.Name -and -not ($cultureFallback -contains $currentCulture.Name)) {
205-
$cultureFallback += $currentCulture.Name
227+
while ($currentCulture -and $currentCulture.Name -and -not [string]::IsNullOrWhiteSpace($currentCulture.Name)) {
228+
if ($cultureSeen.Add($currentCulture.Name)) {
229+
$null = $cultureFallback.Add($currentCulture.Name)
230+
}
231+
206232
if ($currentCulture.Parent -and $currentCulture.Parent.Name -and $currentCulture.Parent.Name -ne $currentCulture.Name) {
207233
$currentCulture = $currentCulture.Parent
208234
}
@@ -211,9 +237,13 @@ while ($currentCulture -and $currentCulture.Name -and -not ($cultureFallback -co
211237
}
212238
}
213239

214-
$cultureFallback += 'en-US'
215-
$cultureFallback += 'en'
216-
$cultureFallback = $cultureFallback | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -Unique
240+
foreach ($fallbackCulture in @('en-US', 'en')) {
241+
if ($cultureSeen.Add($fallbackCulture)) {
242+
$null = $cultureFallback.Add($fallbackCulture)
243+
}
244+
}
245+
246+
$cultureFallback = $cultureFallback.ToArray()
217247

218248
$script:LocalizationMode = 'Auto'
219249
$localizationModeEnv = $env:COLOR_SCRIPTS_ENHANCED_LOCALIZATION_MODE
@@ -325,26 +355,24 @@ if (-not $script:DelegateSyncRoot) { $script:DelegateSyncRoot = New-Object Syste
325355

326356
$privateDirectory = Join-Path -Path $PSScriptRoot -ChildPath 'Private'
327357
if (Test-Path -LiteralPath $privateDirectory) {
328-
Get-ChildItem -Path $privateDirectory -Filter '*.ps1' -File | Sort-Object Name | ForEach-Object {
329-
Write-ModuleTrace ('Loading private script: {0}' -f $_.Name)
330-
. $_.FullName
358+
$privateScripts = [System.IO.Directory]::GetFiles($privateDirectory, '*.ps1')
359+
[System.Array]::Sort($privateScripts, [System.StringComparer]::OrdinalIgnoreCase)
360+
foreach ($scriptPath in $privateScripts) {
361+
Write-ModuleTrace ('Loading private script: {0}' -f ([System.IO.Path]::GetFileName($scriptPath)))
362+
. $scriptPath
331363
}
332364
}
333365
else {
334366
Write-ModuleTrace ("Private script directory '{0}' was not found." -f $privateDirectory)
335367
}
336368

337-
$localizationResult = Initialize-ColorScriptsLocalization -CandidateRoots ($moduleRootCandidates | Select-Object -Unique) -CultureFallbackOverride $cultureFallback -UseDefaultCandidates
369+
$localizationResult = Initialize-ColorScriptsLocalization -CultureFallbackOverride $cultureFallback -UseDefaultCandidates
338370
if ($localizationResult -and $localizationResult.ModuleRoot) {
339371
$script:ModuleRoot = $localizationResult.ModuleRoot
340372
}
341-
elseif (-not $script:ModuleRoot) {
342-
if ($PSScriptRoot) {
343-
$script:ModuleRoot = $PSScriptRoot
344-
}
345-
elseif ($moduleInfo -and $moduleInfo.ModuleBase) {
346-
$script:ModuleRoot = $moduleInfo.ModuleBase
347-
}
373+
374+
if (-not $script:ModuleRoot -and $PSScriptRoot) {
375+
$script:ModuleRoot = $PSScriptRoot
348376
}
349377

350378
if ($script:ModuleRoot) {
@@ -368,9 +396,11 @@ else {
368396

369397
$publicDirectory = Join-Path -Path $PSScriptRoot -ChildPath 'Public'
370398
if (Test-Path -LiteralPath $publicDirectory) {
371-
Get-ChildItem -Path $publicDirectory -Filter '*.ps1' -File | Sort-Object Name | ForEach-Object {
372-
Write-ModuleTrace ('Loading public script: {0}' -f $_.Name)
373-
. $_.FullName
399+
$publicScripts = [System.IO.Directory]::GetFiles($publicDirectory, '*.ps1')
400+
[System.Array]::Sort($publicScripts, [System.StringComparer]::OrdinalIgnoreCase)
401+
foreach ($scriptPath in $publicScripts) {
402+
Write-ModuleTrace ('Loading public script: {0}' -f ([System.IO.Path]::GetFileName($scriptPath)))
403+
. $scriptPath
374404
}
375405
}
376406
else {

0 commit comments

Comments
 (0)