Skip to content

Commit f1f21a1

Browse files
committed
fix(windows): harden visual lookups in logger
1 parent 4a41d56 commit f1f21a1

File tree

4 files changed

+132
-49
lines changed

4 files changed

+132
-49
lines changed

lib/core/base.ps1

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,48 @@ $script:MOLE_BASE_LOADED = $true
1212
# ============================================================================
1313
# Color Definitions (ANSI escape codes for modern terminals)
1414
# ============================================================================
15-
$script:ESC = [char]27
16-
$script:DefaultColors = @{
17-
Green = "$ESC[0;32m"
18-
Blue = "$ESC[0;34m"
19-
Cyan = "$ESC[0;36m"
20-
Yellow = "$ESC[0;33m"
21-
Purple = "$ESC[0;35m"
22-
PurpleBold = "$ESC[1;35m"
23-
Red = "$ESC[0;31m"
24-
Gray = "$ESC[0;90m"
25-
White = "$ESC[0;37m"
26-
NC = "$ESC[0m" # No Color / Reset
15+
function Get-MoleDefaultColors {
16+
$esc = [char]27
17+
return @{
18+
Green = "$esc[0;32m"
19+
Blue = "$esc[0;34m"
20+
Cyan = "$esc[0;36m"
21+
Yellow = "$esc[0;33m"
22+
Purple = "$esc[0;35m"
23+
PurpleBold = "$esc[1;35m"
24+
Red = "$esc[0;31m"
25+
Gray = "$esc[0;90m"
26+
White = "$esc[0;37m"
27+
NC = "$esc[0m" # No Color / Reset
28+
}
2729
}
2830

2931
# ============================================================================
3032
# Icon Definitions
3133
# ============================================================================
32-
$script:DefaultIcons = @{
33-
Confirm = [char]0x25CE #
34-
Admin = [char]0x2699 #
35-
Success = [char]0x2713 #
36-
Error = [char]0x263B #
37-
Warning = [char]0x25CF #
38-
Empty = [char]0x25CB #
39-
Solid = [char]0x25CF #
40-
List = [char]0x2022 #
41-
Arrow = [char]0x27A4 #
42-
DryRun = [char]0x2192 #
43-
NavUp = [char]0x2191 #
44-
NavDown = [char]0x2193 #
45-
Folder = [char]0x25A0 # ■ (folder substitute)
46-
File = [char]0x25A1 # □ (file substitute)
47-
Trash = [char]0x2718 # ✘ (trash substitute)
34+
function Get-MoleDefaultIcons {
35+
return @{
36+
Confirm = [char]0x25CE #
37+
Admin = [char]0x2699 #
38+
Success = [char]0x2713 #
39+
Error = [char]0x263B #
40+
Warning = [char]0x25CF #
41+
Empty = [char]0x25CB #
42+
Solid = [char]0x25CF #
43+
List = [char]0x2022 #
44+
Arrow = [char]0x27A4 #
45+
DryRun = [char]0x2192 #
46+
NavUp = [char]0x2191 #
47+
NavDown = [char]0x2193 #
48+
Folder = [char]0x25A0 # ■ (folder substitute)
49+
File = [char]0x25A1 # □ (file substitute)
50+
Trash = [char]0x2718 # ✘ (trash substitute)
51+
}
4852
}
4953

54+
$script:DefaultColors = Get-MoleDefaultColors
55+
$script:DefaultIcons = Get-MoleDefaultIcons
56+
5057
function Get-OrCreateScriptHashtable {
5158
param(
5259
[Parameter(Mandatory)]
@@ -63,24 +70,79 @@ function Get-OrCreateScriptHashtable {
6370
return $table
6471
}
6572

73+
function Get-MoleDefaultHashtable {
74+
param(
75+
[Parameter(Mandatory)]
76+
[ValidateSet('Colors', 'Icons')]
77+
[string]$Name
78+
)
79+
80+
$defaultVariable = Get-Variable -Name "Default$Name" -Scope Script -ErrorAction SilentlyContinue
81+
if ($defaultVariable -and $defaultVariable.Value -is [hashtable]) {
82+
return $defaultVariable.Value
83+
}
84+
85+
switch ($Name) {
86+
'Colors' { return Get-MoleDefaultColors }
87+
'Icons' { return Get-MoleDefaultIcons }
88+
}
89+
}
90+
6691
function Initialize-MoleVisualDefaults {
92+
$defaultColors = Get-MoleDefaultHashtable -Name "Colors"
6793
$colors = Get-OrCreateScriptHashtable -Name "Colors"
6894

69-
foreach ($entry in $script:DefaultColors.GetEnumerator()) {
95+
foreach ($entry in $defaultColors.GetEnumerator()) {
7096
if (-not $colors.ContainsKey($entry.Key)) {
7197
$colors[$entry.Key] = $entry.Value
7298
}
7399
}
74100

101+
$defaultIcons = Get-MoleDefaultHashtable -Name "Icons"
75102
$icons = Get-OrCreateScriptHashtable -Name "Icons"
76103

77-
foreach ($entry in $script:DefaultIcons.GetEnumerator()) {
104+
foreach ($entry in $defaultIcons.GetEnumerator()) {
78105
if (-not $icons.ContainsKey($entry.Key)) {
79106
$icons[$entry.Key] = $entry.Value
80107
}
81108
}
82109
}
83110

111+
function Get-MoleVisualValue {
112+
param(
113+
[Parameter(Mandatory)]
114+
[ValidateSet('Colors', 'Icons')]
115+
[string]$TableName,
116+
117+
[Parameter(Mandatory)]
118+
[string]$Key
119+
)
120+
121+
$table = Get-OrCreateScriptHashtable -Name $TableName
122+
if (-not $table.ContainsKey($Key)) {
123+
$defaults = Get-MoleDefaultHashtable -Name $TableName
124+
if ($defaults.ContainsKey($Key)) {
125+
$table[$Key] = $defaults[$Key]
126+
}
127+
}
128+
129+
if ($table.ContainsKey($Key)) {
130+
return $table[$Key]
131+
}
132+
133+
return $null
134+
}
135+
136+
function Get-MoleColor {
137+
param([Parameter(Mandatory)][string]$Name)
138+
return Get-MoleVisualValue -TableName "Colors" -Key $Name
139+
}
140+
141+
function Get-MoleIcon {
142+
param([Parameter(Mandatory)][string]$Name)
143+
return Get-MoleVisualValue -TableName "Icons" -Key $Name
144+
}
145+
84146
Initialize-MoleVisualDefaults
85147

86148
# ============================================================================

lib/core/log.ps1

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ function Write-LogMessage {
4040
)
4141

4242
$timestamp = Get-Date -Format "HH:mm:ss"
43-
$colorCode = $script:Colors[$Color]
44-
$nc = $script:Colors.NC
43+
$colorCode = Get-MoleColor -Name $Color
44+
$nc = Get-MoleColor -Name "NC"
4545

4646
$formattedIcon = if ($Icon) { "$Icon " } else { "" }
4747
$output = " ${colorCode}${formattedIcon}${nc}${Message}"
@@ -60,7 +60,7 @@ function Write-Info {
6060
Write an informational message
6161
#>
6262
param([string]$Message)
63-
Write-LogMessage -Message $Message -Level "INFO" -Color "Cyan" -Icon $script:Icons.List
63+
Write-LogMessage -Message $Message -Level "INFO" -Color "Cyan" -Icon (Get-MoleIcon -Name "List")
6464
}
6565

6666
function Write-Success {
@@ -69,7 +69,7 @@ function Write-Success {
6969
Write a success message
7070
#>
7171
param([string]$Message)
72-
Write-LogMessage -Message $Message -Level "SUCCESS" -Color "Green" -Icon $script:Icons.Success
72+
Write-LogMessage -Message $Message -Level "SUCCESS" -Color "Green" -Icon (Get-MoleIcon -Name "Success")
7373
}
7474

7575

@@ -79,7 +79,7 @@ function Write-MoleWarning {
7979
Write a warning message
8080
#>
8181
param([string]$Message)
82-
Write-LogMessage -Message $Message -Level "WARN" -Color "Yellow" -Icon $script:Icons.Warning
82+
Write-LogMessage -Message $Message -Level "WARN" -Color "Yellow" -Icon (Get-MoleIcon -Name "Warning")
8383
}
8484

8585
function Write-MoleError {
@@ -88,7 +88,7 @@ function Write-MoleError {
8888
Write an error message
8989
#>
9090
param([string]$Message)
91-
Write-LogMessage -Message $Message -Level "ERROR" -Color "Red" -Icon $script:Icons.Error
91+
Write-LogMessage -Message $Message -Level "ERROR" -Color "Red" -Icon (Get-MoleIcon -Name "Error")
9292
}
9393

9494

@@ -100,8 +100,8 @@ function Write-Debug {
100100
param([string]$Message)
101101

102102
if ($script:LogConfig.DebugEnabled) {
103-
$gray = $script:Colors.Gray
104-
$nc = $script:Colors.NC
103+
$gray = Get-MoleColor -Name "Gray"
104+
$nc = Get-MoleColor -Name "NC"
105105
Write-Host " ${gray}[DEBUG] $Message${nc}"
106106
}
107107
}
@@ -112,7 +112,7 @@ function Write-DryRun {
112112
Write a dry-run message (action that would be taken)
113113
#>
114114
param([string]$Message)
115-
Write-LogMessage -Message $Message -Level "DRYRUN" -Color "Yellow" -Icon $script:Icons.DryRun
115+
Write-LogMessage -Message $Message -Level "DRYRUN" -Color "Yellow" -Icon (Get-MoleIcon -Name "DryRun")
116116
}
117117

118118
# ============================================================================
@@ -136,9 +136,9 @@ function Start-Section {
136136
$script:CurrentSection.Activity = $false
137137
$script:CurrentSection.Name = $Title
138138

139-
$purple = $script:Colors.PurpleBold
140-
$nc = $script:Colors.NC
141-
$arrow = $script:Icons.Arrow
139+
$purple = Get-MoleColor -Name "PurpleBold"
140+
$nc = Get-MoleColor -Name "NC"
141+
$arrow = Get-MoleIcon -Name "Arrow"
142142

143143
Write-Host ""
144144
Write-Host "${purple}${arrow} ${Title}${nc}"
@@ -181,8 +181,8 @@ function Start-Spinner {
181181
param([string]$Message = "Working...")
182182

183183
$script:SpinnerIndex = 0
184-
$gray = $script:Colors.Gray
185-
$nc = $script:Colors.NC
184+
$gray = Get-MoleColor -Name "Gray"
185+
$nc = Get-MoleColor -Name "NC"
186186

187187
Write-Host -NoNewline " ${gray}$($script:SpinnerFrames[0]) $Message${nc}"
188188
}
@@ -196,8 +196,8 @@ function Update-Spinner {
196196

197197
$script:SpinnerIndex = ($script:SpinnerIndex + 1) % $script:SpinnerFrames.Count
198198
$frame = $script:SpinnerFrames[$script:SpinnerIndex]
199-
$gray = $script:Colors.Gray
200-
$nc = $script:Colors.NC
199+
$gray = Get-MoleColor -Name "Gray"
200+
$nc = Get-MoleColor -Name "NC"
201201

202202
# Move cursor to beginning of line and clear
203203
Write-Host -NoNewline "`r ${gray}$frame $Message${nc} "
@@ -232,8 +232,8 @@ function Write-Progress {
232232
$empty = $Width - $filled
233233

234234
$bar = ("[" + ("=" * $filled) + (" " * $empty) + "]")
235-
$cyan = $script:Colors.Cyan
236-
$nc = $script:Colors.NC
235+
$cyan = Get-MoleColor -Name "Cyan"
236+
$nc = Get-MoleColor -Name "NC"
237237

238238
Write-Host -NoNewline "`r ${cyan}$bar${nc} ${percent}% $Message "
239239
}

tests/Commands.Tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ BeforeAll {
66
$script:WindowsDir = Split-Path -Parent $PSScriptRoot
77
$script:BinDir = Join-Path $script:WindowsDir "bin"
88
$script:InstallScript = Join-Path $script:WindowsDir "install.ps1"
9-
$script:VisualDefaultsErrorPattern = 'property ''Solid'' cannot be found|找不到属性.?Solid|VariableIsUndefined|\$script:Colors'
9+
$script:VisualDefaultsErrorPattern = 'property ''(Solid|Error)'' cannot be found|找不到属性.?(Solid|Error)|VariableIsUndefined|\$script:Colors'
1010
}
1111

1212
Describe "Clean Command" {

tests/Core.Tests.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ Describe "Base Module" {
7070
$script:Icons.Solid | Should -Be "*"
7171
$script:Icons.Admin | Should -Not -BeNullOrEmpty
7272
}
73+
74+
It "Should restore missing icon entries on demand" {
75+
$script:Icons = @{ Solid = "*" }
76+
77+
(Get-MoleIcon -Name "Error") | Should -Not -BeNullOrEmpty
78+
$script:Icons.Error | Should -Not -BeNullOrEmpty
79+
$script:Icons.Solid | Should -Be "*"
80+
}
7381
}
7482

7583
Context "Test-IsAdmin" {
@@ -242,6 +250,19 @@ Describe "Logging Module" {
242250
# Note: The actual function is Write-MoleError
243251
{ Write-MoleError "Test message" } | Should -Not -Throw
244252
}
253+
254+
It "Should log errors even when the icon table is partial" {
255+
$originalIcons = $script:Icons.Clone()
256+
257+
try {
258+
$script:Icons = @{ Solid = "*" }
259+
{ Write-MoleError "Test message" } | Should -Not -Throw
260+
$script:Icons.Error | Should -Not -BeNullOrEmpty
261+
}
262+
finally {
263+
$script:Icons = $originalIcons
264+
}
265+
}
245266
}
246267

247268
Context "Section Functions" {

0 commit comments

Comments
 (0)