@@ -42,8 +42,14 @@ $moduleInfo = $ExecutionContext.SessionState.Module
4242$moduleRootCandidates = @ ()
4343$moduleRootDebugPath = Join-Path - Path ([System.IO.Path ]::GetTempPath()) - ChildPath ' cs-module-root-debug.log'
4444" --- Import begin: $ ( Get-Date - Format o) ---" | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
45- " ModuleInfo.ModuleBase = $ ( $moduleInfo ?.ModuleBase) " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
46- " ModuleInfo.Path = $ ( $moduleInfo ?.Path) " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
45+ if ($moduleInfo ) {
46+ " ModuleInfo.ModuleBase = $ ( $moduleInfo.ModuleBase ) " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
47+ " ModuleInfo.Path = $ ( $moduleInfo.Path ) " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
48+ }
49+ else {
50+ " ModuleInfo.ModuleBase = <null>" | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
51+ " ModuleInfo.Path = <null>" | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
52+ }
4753" PSScriptRoot = $PSScriptRoot " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
4854
4955if ($moduleInfo ) {
@@ -131,54 +137,315 @@ foreach ($cultureName in $cultureFallback) {
131137
132138$cultureFallback = $cultureFallbackClean
133139
134- $script :Messages = $null
135- $localizedDataLoaded = $false
136- $searchedPaths = @ ()
140+ $script :EmbeddedDefaultMessages = ConvertFrom-StringData @'
141+ # ColorScripts-Enhanced Localized Messages
142+ # English (en-US) - Default Language
143+
144+ # Error Messages
145+ UnableToPrepareCacheDirectory = Unable to prepare cache directory '{0}': {1}
146+ FailedToParseConfigurationFile = Failed to parse configuration file at '{0}': {1}. Using defaults.
147+ UnableToResolveCachePath = Unable to resolve cache path '{0}'.
148+ ConfiguredCachePathInvalid = Configured cache path '{0}' could not be resolved. Falling back to default locations.
149+ UnableToResolveOutputPath = Unable to resolve output path '{0}'.
150+ UnableToDetermineConfigurationDirectory = Unable to determine configuration directory for ColorScripts-Enhanced.
151+ ConfigurationRootCouldNotBeResolved = Configuration root could not be resolved.
152+ UnableToResolveProfilePath = Unable to resolve profile path '{0}'.
153+ FailedToExecuteColorscript = Failed to execute colorscript '{0}': {1}
154+ FailedToBuildCacheForScript = Failed to build cache for $($selection.Name).
155+ CacheBuildFailedForScript = Cache build failed for {0}: {1}
156+ ScriptAlreadyExists = Script '{0}' already exists. Use -Force to overwrite.
157+ ProfilePathNotDefinedForScope = Profile path for scope '{0}' is not defined.
158+ ScriptPathNotFound = Script path not found.
159+ ScriptExitedWithCode = Script exited with code {0}.
160+ CacheFileNotFound = Cache file not found.
161+ NoChangesApplied = No changes applied.
162+ UnableToRetrieveFileInfo = Unable to retrieve file info for '{0}': {1}
163+ UnableToReadCacheInfo = Unable to read cache info for '{0}': {1}
164+
165+ # Warning Messages
166+ NoColorscriptsFoundMatchingCriteria = No colorscripts found matching the specified criteria.
167+ NoScriptsMatchedSpecifiedFilters = No scripts matched the specified filters.
168+ NoColorscriptsAvailableWithFilters = No colorscripts available with the specified filters.
169+ NoColorscriptsFoundInScriptsPath = No colorscripts found in $script:ScriptsPath
170+ NoScriptsSelectedForCacheBuild = No scripts selected for cache build.
171+ ScriptNotFound = Script not found: {0}
172+ ColorscriptNotFoundWithFilters = Colorscript '{0}' not found with the specified filters.
173+ CachePathNotFound = Cache path not found: {0}
174+ NoCacheFilesFound = No cache files found at {0}.
175+ ProfileUpdatesNotSupportedInRemote = Profile updates are not supported in remote sessions.
176+ ScriptSkippedByFilter = Script '{0}' does not satisfy the specified filters and will be skipped.
177+
178+ # Status Messages
179+ DisplayingColorscripts = `nDisplaying $totalCount colorscripts...
180+ CacheBuildSummary = `nCache Build Summary:
181+ FailedScripts = `nFailed scripts:
182+ TotalScriptsProcessed = `nTotal scripts processed: $totalCount
183+ DisplayingContinuously = Displaying continuously (Ctrl+C to stop)`n
184+ FinishedDisplayingAll = Finished displaying all $totalCount colorscripts!
185+ Quitting = `nQuitting...
186+ CurrentIndexOfTotal = [$currentIndex/$totalCount]
187+ FailedScriptDetails = - $($failure.Name): $($failure.StdErr)
188+ MultipleColorscriptsMatched = Multiple colorscripts matched the provided name pattern(s): {0}. Displaying '{1}'.
189+ StatusCached = Cached
190+ StatusSkippedUpToDate = Skipped (up-to-date)
191+ StatusSkippedByUser = Skipped by user
192+ StatusFailed = Failed
193+ StatusUpToDateSkipped = Up-to-date (skipped)
194+
195+ # Interactive Messages
196+ PressSpacebarToContinue = Press [Spacebar] to continue to next, [Q] to quit`n
197+ PressSpacebarForNext = Press [Spacebar] for next, [Q] to quit...
198+
199+ # Success Messages
200+ ProfileSnippetAdded = [OK] Added ColorScripts-Enhanced startup snippet to $profilePath
201+ ProfileAlreadyContainsSnippet = Profile already contains ColorScripts-Enhanced snippet.
202+ ProfileAlreadyImportsModule = Profile already imports ColorScripts-Enhanced.
203+ ModuleLoadedSuccessfully = ColorScripts-Enhanced module loaded successfully.
204+ RemoteSessionDetected = Remote session detected.
205+ ProfileAlreadyConfigured = Profile already configured.
206+ ProfileSnippetAddedMessage = ColorScripts-Enhanced profile snippet added.
207+
208+ # Help/Instruction Messages
209+ SpecifyNameToSelectScripts = Specify -Name to select scripts when -All is explicitly disabled.
210+ SpecifyAllOrNameToClearCache = Specify -All or -Name to clear cache entries.
211+ UsePassThruForDetailedResults = Use -PassThru to see detailed results`n
212+
213+ # UI Elements
214+
215+ # Miscellaneous
216+ '@
217+
218+ function Resolve-LocalizedMessagesFile {
219+ param (
220+ [Parameter (Mandatory )][string ]$BaseDirectory ,
221+ [Parameter (Mandatory )][string []]$CultureFallback
222+ )
223+
224+ $messagesFileName = ' Messages.psd1'
137225
138- foreach ($candidatePath in $moduleRootCandidates ) {
139- $searchedPaths += $candidatePath
140- " Evaluating candidate: ${candidatePath} " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
226+ $directoryEntries = Get-ChildItem - LiteralPath $BaseDirectory - Directory - ErrorAction SilentlyContinue
227+ if (-not $directoryEntries ) {
228+ $directoryEntries = @ ()
229+ }
141230
142- $hasLocalizedFile = $false
143- foreach ($cultureName in $cultureFallback ) {
144- $localizedFile = Join-Path - Path $candidatePath - ChildPath (Join-Path - Path $cultureName - ChildPath ' Messages.psd1' )
145- if (Test-Path - LiteralPath $localizedFile ) {
146- $hasLocalizedFile = $true
147- break
231+ foreach ($cultureName in $CultureFallback ) {
232+ if ([string ]::IsNullOrWhiteSpace($cultureName )) {
233+ continue
234+ }
235+
236+ $resolvedDirectory = $null
237+ $directCulturePath = Join-Path - Path $BaseDirectory - ChildPath $cultureName
238+
239+ if (Test-Path - LiteralPath $directCulturePath - PathType Container) {
240+ $resolvedResult = Resolve-Path - LiteralPath $directCulturePath - ErrorAction SilentlyContinue
241+ if ($resolvedResult ) {
242+ $resolvedDirectory = $resolvedResult.ProviderPath
243+ }
244+ else {
245+ $resolvedDirectory = $directCulturePath
246+ }
247+ }
248+
249+ if (-not $resolvedDirectory ) {
250+ $matchingDirectory = $null
251+ foreach ($entry in $directoryEntries ) {
252+ if ($entry.Name.Equals ($cultureName , [System.StringComparison ]::OrdinalIgnoreCase)) {
253+ $matchingDirectory = $entry.FullName
254+ break
255+ }
256+ }
257+
258+ if ($matchingDirectory ) {
259+ $resolvedDirectory = $matchingDirectory
260+ }
261+ }
262+
263+ if (-not $resolvedDirectory ) {
264+ continue
265+ }
266+
267+ $candidateFile = Join-Path - Path $resolvedDirectory - ChildPath $messagesFileName
268+
269+ if (-not (Test-Path - LiteralPath $candidateFile - PathType Leaf)) {
270+ $filesInDirectory = Get-ChildItem - LiteralPath $resolvedDirectory - File - ErrorAction SilentlyContinue
271+ if (-not $filesInDirectory ) {
272+ $filesInDirectory = @ ()
273+ }
274+
275+ $candidateFile = $null
276+ foreach ($fileEntry in $filesInDirectory ) {
277+ if ($fileEntry.Name.Equals ($messagesFileName , [System.StringComparison ]::OrdinalIgnoreCase)) {
278+ $candidateFile = $fileEntry.FullName
279+ break
280+ }
281+ }
282+ }
283+
284+ if ($candidateFile -and (Test-Path - LiteralPath $candidateFile - PathType Leaf)) {
285+ $resolvedFile = $candidateFile
286+ $resolvedFilePath = Resolve-Path - LiteralPath $candidateFile - ErrorAction SilentlyContinue
287+ if ($resolvedFilePath ) {
288+ $resolvedFile = $resolvedFilePath.ProviderPath
289+ }
290+
291+ return [pscustomobject ]@ {
292+ FilePath = $resolvedFile
293+ CultureName = $cultureName
294+ }
148295 }
149296 }
150297
151- if (-not $hasLocalizedFile ) {
152- $rootFallback = Join-Path - Path $candidatePath - ChildPath ' Messages.psd1'
153- if (Test-Path - LiteralPath $rootFallback ) {
154- $hasLocalizedFile = $true
155- " Found root fallback at ${rootFallback} " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
298+ $rootFile = Join-Path - Path $BaseDirectory - ChildPath $messagesFileName
299+
300+ if (-not (Test-Path - LiteralPath $rootFile - PathType Leaf)) {
301+ $rootFiles = Get-ChildItem - LiteralPath $BaseDirectory - File - ErrorAction SilentlyContinue
302+ if (-not $rootFiles ) {
303+ $rootFiles = @ ()
304+ }
305+
306+ $rootFile = $null
307+ foreach ($fileEntry in $rootFiles ) {
308+ if ($fileEntry.Name.Equals ($messagesFileName , [System.StringComparison ]::OrdinalIgnoreCase)) {
309+ $rootFile = $fileEntry.FullName
310+ break
311+ }
156312 }
157313 }
158314
159- if (-not $hasLocalizedFile ) {
160- " No localized data found under ${candidatePath} " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
161- continue
315+ if ($rootFile -and (Test-Path - LiteralPath $rootFile - PathType Leaf)) {
316+ $resolvedRootFile = $rootFile
317+ $resolvedRootResult = Resolve-Path - LiteralPath $rootFile - ErrorAction SilentlyContinue
318+ if ($resolvedRootResult ) {
319+ $resolvedRootFile = $resolvedRootResult.ProviderPath
320+ }
321+
322+ return [pscustomobject ]@ {
323+ FilePath = $resolvedRootFile
324+ CultureName = $null
325+ }
162326 }
163327
164- try {
165- Import-LocalizedData - BindingVariable " script:Messages" - FileName " Messages" - BaseDirectory $candidatePath - ErrorAction Stop
328+ return $null
329+ }
330+
331+ function Import-LocalizedMessagesFromFile {
332+ param (
333+ [Parameter (Mandatory )][string ]$FilePath
334+ )
335+
336+ if (-not (Test-Path - LiteralPath $FilePath - PathType Leaf)) {
337+ throw [System.IO.FileNotFoundException ]::new(" Localization file '$FilePath ' was not found." )
338+ }
339+
340+ $rawContent = Get-Content - LiteralPath $FilePath - Raw - Encoding UTF8 - ErrorAction Stop
341+
342+ $messagesBody = $null
343+ $match = [System.Text.RegularExpressions.Regex ]::Match(
344+ $rawContent ,
345+ " ConvertFrom-StringData\s*@'(?<body>.*)'@" ,
346+ [System.Text.RegularExpressions.RegexOptions ]::Singleline
347+ )
348+
349+ if ($match.Success ) {
350+ $messagesBody = $match.Groups [' body' ].Value
351+ }
352+
353+ if ($messagesBody ) {
354+ $script :Messages = ConvertFrom-StringData - StringData $messagesBody
355+ return
356+ }
357+
358+ $data = Import-PowerShellDataFile - Path $FilePath
359+ if ($data -isnot [hashtable ]) {
360+ throw [System.InvalidOperationException ]::new(" Localization file '$FilePath ' did not return a hashtable." )
361+ }
362+
363+ $script :Messages = $data
364+ }
365+
366+ function Initialize-ColorScriptsLocalization {
367+ param (
368+ [Parameter ()][string []]$CandidateRoots ,
369+ [Parameter ()][string []]$CultureFallbackOverride
370+ )
371+
372+ $pathsToEvaluate = @ ()
373+ if ($CandidateRoots ) {
374+ $pathsToEvaluate = $CandidateRoots
375+ }
376+
377+ $fallbackCultures = if ($CultureFallbackOverride ) { $CultureFallbackOverride } else { $cultureFallback }
378+
379+ $script :Messages = $null
380+ $localizedDataLoaded = $false
381+ $searchedPaths = @ ()
382+
383+ foreach ($candidatePath in $pathsToEvaluate ) {
384+ $searchedPaths += $candidatePath
385+ " Evaluating candidate: ${candidatePath} " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
386+
387+ $resolvedLocalization = Resolve-LocalizedMessagesFile - BaseDirectory $candidatePath - CultureFallback $fallbackCultures
388+
389+ if (-not $resolvedLocalization ) {
390+ " No localized data found under ${candidatePath} " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
391+ continue
392+ }
393+
394+ $importSucceeded = $true
395+ try {
396+ Import-LocalizedMessagesFromFile - FilePath $resolvedLocalization.FilePath
397+ }
398+ catch {
399+ $importSucceeded = $false
400+ " Localization import failed for ${candidatePath} : $ ( $_.Exception.Message ) " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
401+ }
402+
403+ if (-not $importSucceeded ) {
404+ continue
405+ }
406+
166407 $script :ModuleRoot = $candidatePath
167408 $localizedDataLoaded = $true
168- " Localization loaded from ${candidatePath} " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
409+
410+ $logMessage = " Resolved localization using file: $ ( $resolvedLocalization.FilePath ) "
411+ if ($resolvedLocalization.CultureName ) {
412+ $logMessage += " (culture: $ ( $resolvedLocalization.CultureName ) )"
413+ }
414+
415+ $logMessage | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
416+ " Localization loaded from ${candidatePath} (method: direct-file)" | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
169417 break
170418 }
171- catch {
172- " Import-LocalizedData failed for ${candidatePath} : $ ( $_.Exception.Message ) " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
173- continue
419+
420+ if (-not $localizedDataLoaded ) {
421+ $searchedDescription = if ($searchedPaths ) { ($searchedPaths -join ' , ' ) } else { ' <none>' }
422+ " Localization fallback engaged. Searched paths: $searchedDescription " | Out-File - FilePath $moduleRootDebugPath - Encoding utf8 - Append
423+
424+ $fallbackRoot = $searchedPaths | Where-Object { Test-Path - LiteralPath $_ - PathType Container } | Select-Object - First 1
425+ if (-not $fallbackRoot ) {
426+ $resolvedRoot = Resolve-Path - LiteralPath $PSScriptRoot - ErrorAction SilentlyContinue
427+ if ($resolvedRoot ) {
428+ $fallbackRoot = $resolvedRoot.ProviderPath
429+ }
430+ else {
431+ $fallbackRoot = $PSScriptRoot
432+ }
433+ }
434+
435+ $script :ModuleRoot = $fallbackRoot
436+ $script :Messages = $script :EmbeddedDefaultMessages.Clone ()
437+ Write-Warning " Localization resources were not found. Falling back to built-in English messages."
174438 }
175- }
176439
177- if (-not $localizedDataLoaded ) {
178- $searchedDescription = if ($searchedPaths ) { ($searchedPaths -join ' , ' ) } else { ' <none>' }
179- throw [System.IO.FileNotFoundException ]::new(" Cannot find the PowerShell data file 'Messages.psd1'. Searched paths: $searchedDescription " )
440+ [pscustomobject ]@ {
441+ LocalizedDataLoaded = $localizedDataLoaded
442+ SearchedPaths = $searchedPaths
443+ ModuleRoot = $script :ModuleRoot
444+ }
180445}
181446
447+ $null = Initialize-ColorScriptsLocalization - CandidateRoots ($moduleRootCandidates | Select-Object - Unique)
448+
182449$script :ScriptsPath = Join-Path - Path $script :ModuleRoot - ChildPath " Scripts"
183450$script :MetadataPath = Join-Path - Path $script :ModuleRoot - ChildPath " ScriptMetadata.psd1"
184451
0 commit comments