mirror of
https://github.com/tw93/Mole.git
synced 2026-03-23 18:10:07 +00:00
fix(windows): harden visual lookups in logger
This commit is contained in:
@@ -12,41 +12,48 @@ $script:MOLE_BASE_LOADED = $true
|
||||
# ============================================================================
|
||||
# Color Definitions (ANSI escape codes for modern terminals)
|
||||
# ============================================================================
|
||||
$script:ESC = [char]27
|
||||
$script:DefaultColors = @{
|
||||
Green = "$ESC[0;32m"
|
||||
Blue = "$ESC[0;34m"
|
||||
Cyan = "$ESC[0;36m"
|
||||
Yellow = "$ESC[0;33m"
|
||||
Purple = "$ESC[0;35m"
|
||||
PurpleBold = "$ESC[1;35m"
|
||||
Red = "$ESC[0;31m"
|
||||
Gray = "$ESC[0;90m"
|
||||
White = "$ESC[0;37m"
|
||||
NC = "$ESC[0m" # No Color / Reset
|
||||
function Get-MoleDefaultColors {
|
||||
$esc = [char]27
|
||||
return @{
|
||||
Green = "$esc[0;32m"
|
||||
Blue = "$esc[0;34m"
|
||||
Cyan = "$esc[0;36m"
|
||||
Yellow = "$esc[0;33m"
|
||||
Purple = "$esc[0;35m"
|
||||
PurpleBold = "$esc[1;35m"
|
||||
Red = "$esc[0;31m"
|
||||
Gray = "$esc[0;90m"
|
||||
White = "$esc[0;37m"
|
||||
NC = "$esc[0m" # No Color / Reset
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Icon Definitions
|
||||
# ============================================================================
|
||||
$script:DefaultIcons = @{
|
||||
Confirm = [char]0x25CE # ◎
|
||||
Admin = [char]0x2699 # ⚙
|
||||
Success = [char]0x2713 # ✓
|
||||
Error = [char]0x263B # ☻
|
||||
Warning = [char]0x25CF # ●
|
||||
Empty = [char]0x25CB # ○
|
||||
Solid = [char]0x25CF # ●
|
||||
List = [char]0x2022 # •
|
||||
Arrow = [char]0x27A4 # ➤
|
||||
DryRun = [char]0x2192 # →
|
||||
NavUp = [char]0x2191 # ↑
|
||||
NavDown = [char]0x2193 # ↓
|
||||
Folder = [char]0x25A0 # ■ (folder substitute)
|
||||
File = [char]0x25A1 # □ (file substitute)
|
||||
Trash = [char]0x2718 # ✘ (trash substitute)
|
||||
function Get-MoleDefaultIcons {
|
||||
return @{
|
||||
Confirm = [char]0x25CE # ◎
|
||||
Admin = [char]0x2699 # ⚙
|
||||
Success = [char]0x2713 # ✓
|
||||
Error = [char]0x263B # ☻
|
||||
Warning = [char]0x25CF # ●
|
||||
Empty = [char]0x25CB # ○
|
||||
Solid = [char]0x25CF # ●
|
||||
List = [char]0x2022 # •
|
||||
Arrow = [char]0x27A4 # ➤
|
||||
DryRun = [char]0x2192 # →
|
||||
NavUp = [char]0x2191 # ↑
|
||||
NavDown = [char]0x2193 # ↓
|
||||
Folder = [char]0x25A0 # ■ (folder substitute)
|
||||
File = [char]0x25A1 # □ (file substitute)
|
||||
Trash = [char]0x2718 # ✘ (trash substitute)
|
||||
}
|
||||
}
|
||||
|
||||
$script:DefaultColors = Get-MoleDefaultColors
|
||||
$script:DefaultIcons = Get-MoleDefaultIcons
|
||||
|
||||
function Get-OrCreateScriptHashtable {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -63,24 +70,79 @@ function Get-OrCreateScriptHashtable {
|
||||
return $table
|
||||
}
|
||||
|
||||
function Get-MoleDefaultHashtable {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateSet('Colors', 'Icons')]
|
||||
[string]$Name
|
||||
)
|
||||
|
||||
$defaultVariable = Get-Variable -Name "Default$Name" -Scope Script -ErrorAction SilentlyContinue
|
||||
if ($defaultVariable -and $defaultVariable.Value -is [hashtable]) {
|
||||
return $defaultVariable.Value
|
||||
}
|
||||
|
||||
switch ($Name) {
|
||||
'Colors' { return Get-MoleDefaultColors }
|
||||
'Icons' { return Get-MoleDefaultIcons }
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize-MoleVisualDefaults {
|
||||
$defaultColors = Get-MoleDefaultHashtable -Name "Colors"
|
||||
$colors = Get-OrCreateScriptHashtable -Name "Colors"
|
||||
|
||||
foreach ($entry in $script:DefaultColors.GetEnumerator()) {
|
||||
foreach ($entry in $defaultColors.GetEnumerator()) {
|
||||
if (-not $colors.ContainsKey($entry.Key)) {
|
||||
$colors[$entry.Key] = $entry.Value
|
||||
}
|
||||
}
|
||||
|
||||
$defaultIcons = Get-MoleDefaultHashtable -Name "Icons"
|
||||
$icons = Get-OrCreateScriptHashtable -Name "Icons"
|
||||
|
||||
foreach ($entry in $script:DefaultIcons.GetEnumerator()) {
|
||||
foreach ($entry in $defaultIcons.GetEnumerator()) {
|
||||
if (-not $icons.ContainsKey($entry.Key)) {
|
||||
$icons[$entry.Key] = $entry.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-MoleVisualValue {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateSet('Colors', 'Icons')]
|
||||
[string]$TableName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Key
|
||||
)
|
||||
|
||||
$table = Get-OrCreateScriptHashtable -Name $TableName
|
||||
if (-not $table.ContainsKey($Key)) {
|
||||
$defaults = Get-MoleDefaultHashtable -Name $TableName
|
||||
if ($defaults.ContainsKey($Key)) {
|
||||
$table[$Key] = $defaults[$Key]
|
||||
}
|
||||
}
|
||||
|
||||
if ($table.ContainsKey($Key)) {
|
||||
return $table[$Key]
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
function Get-MoleColor {
|
||||
param([Parameter(Mandatory)][string]$Name)
|
||||
return Get-MoleVisualValue -TableName "Colors" -Key $Name
|
||||
}
|
||||
|
||||
function Get-MoleIcon {
|
||||
param([Parameter(Mandatory)][string]$Name)
|
||||
return Get-MoleVisualValue -TableName "Icons" -Key $Name
|
||||
}
|
||||
|
||||
Initialize-MoleVisualDefaults
|
||||
|
||||
# ============================================================================
|
||||
|
||||
@@ -40,8 +40,8 @@ function Write-LogMessage {
|
||||
)
|
||||
|
||||
$timestamp = Get-Date -Format "HH:mm:ss"
|
||||
$colorCode = $script:Colors[$Color]
|
||||
$nc = $script:Colors.NC
|
||||
$colorCode = Get-MoleColor -Name $Color
|
||||
$nc = Get-MoleColor -Name "NC"
|
||||
|
||||
$formattedIcon = if ($Icon) { "$Icon " } else { "" }
|
||||
$output = " ${colorCode}${formattedIcon}${nc}${Message}"
|
||||
@@ -60,7 +60,7 @@ function Write-Info {
|
||||
Write an informational message
|
||||
#>
|
||||
param([string]$Message)
|
||||
Write-LogMessage -Message $Message -Level "INFO" -Color "Cyan" -Icon $script:Icons.List
|
||||
Write-LogMessage -Message $Message -Level "INFO" -Color "Cyan" -Icon (Get-MoleIcon -Name "List")
|
||||
}
|
||||
|
||||
function Write-Success {
|
||||
@@ -69,7 +69,7 @@ function Write-Success {
|
||||
Write a success message
|
||||
#>
|
||||
param([string]$Message)
|
||||
Write-LogMessage -Message $Message -Level "SUCCESS" -Color "Green" -Icon $script:Icons.Success
|
||||
Write-LogMessage -Message $Message -Level "SUCCESS" -Color "Green" -Icon (Get-MoleIcon -Name "Success")
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ function Write-MoleWarning {
|
||||
Write a warning message
|
||||
#>
|
||||
param([string]$Message)
|
||||
Write-LogMessage -Message $Message -Level "WARN" -Color "Yellow" -Icon $script:Icons.Warning
|
||||
Write-LogMessage -Message $Message -Level "WARN" -Color "Yellow" -Icon (Get-MoleIcon -Name "Warning")
|
||||
}
|
||||
|
||||
function Write-MoleError {
|
||||
@@ -88,7 +88,7 @@ function Write-MoleError {
|
||||
Write an error message
|
||||
#>
|
||||
param([string]$Message)
|
||||
Write-LogMessage -Message $Message -Level "ERROR" -Color "Red" -Icon $script:Icons.Error
|
||||
Write-LogMessage -Message $Message -Level "ERROR" -Color "Red" -Icon (Get-MoleIcon -Name "Error")
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ function Write-Debug {
|
||||
param([string]$Message)
|
||||
|
||||
if ($script:LogConfig.DebugEnabled) {
|
||||
$gray = $script:Colors.Gray
|
||||
$nc = $script:Colors.NC
|
||||
$gray = Get-MoleColor -Name "Gray"
|
||||
$nc = Get-MoleColor -Name "NC"
|
||||
Write-Host " ${gray}[DEBUG] $Message${nc}"
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ function Write-DryRun {
|
||||
Write a dry-run message (action that would be taken)
|
||||
#>
|
||||
param([string]$Message)
|
||||
Write-LogMessage -Message $Message -Level "DRYRUN" -Color "Yellow" -Icon $script:Icons.DryRun
|
||||
Write-LogMessage -Message $Message -Level "DRYRUN" -Color "Yellow" -Icon (Get-MoleIcon -Name "DryRun")
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
@@ -136,9 +136,9 @@ function Start-Section {
|
||||
$script:CurrentSection.Activity = $false
|
||||
$script:CurrentSection.Name = $Title
|
||||
|
||||
$purple = $script:Colors.PurpleBold
|
||||
$nc = $script:Colors.NC
|
||||
$arrow = $script:Icons.Arrow
|
||||
$purple = Get-MoleColor -Name "PurpleBold"
|
||||
$nc = Get-MoleColor -Name "NC"
|
||||
$arrow = Get-MoleIcon -Name "Arrow"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "${purple}${arrow} ${Title}${nc}"
|
||||
@@ -181,8 +181,8 @@ function Start-Spinner {
|
||||
param([string]$Message = "Working...")
|
||||
|
||||
$script:SpinnerIndex = 0
|
||||
$gray = $script:Colors.Gray
|
||||
$nc = $script:Colors.NC
|
||||
$gray = Get-MoleColor -Name "Gray"
|
||||
$nc = Get-MoleColor -Name "NC"
|
||||
|
||||
Write-Host -NoNewline " ${gray}$($script:SpinnerFrames[0]) $Message${nc}"
|
||||
}
|
||||
@@ -196,8 +196,8 @@ function Update-Spinner {
|
||||
|
||||
$script:SpinnerIndex = ($script:SpinnerIndex + 1) % $script:SpinnerFrames.Count
|
||||
$frame = $script:SpinnerFrames[$script:SpinnerIndex]
|
||||
$gray = $script:Colors.Gray
|
||||
$nc = $script:Colors.NC
|
||||
$gray = Get-MoleColor -Name "Gray"
|
||||
$nc = Get-MoleColor -Name "NC"
|
||||
|
||||
# Move cursor to beginning of line and clear
|
||||
Write-Host -NoNewline "`r ${gray}$frame $Message${nc} "
|
||||
@@ -232,8 +232,8 @@ function Write-Progress {
|
||||
$empty = $Width - $filled
|
||||
|
||||
$bar = ("[" + ("=" * $filled) + (" " * $empty) + "]")
|
||||
$cyan = $script:Colors.Cyan
|
||||
$nc = $script:Colors.NC
|
||||
$cyan = Get-MoleColor -Name "Cyan"
|
||||
$nc = Get-MoleColor -Name "NC"
|
||||
|
||||
Write-Host -NoNewline "`r ${cyan}$bar${nc} ${percent}% $Message "
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ BeforeAll {
|
||||
$script:WindowsDir = Split-Path -Parent $PSScriptRoot
|
||||
$script:BinDir = Join-Path $script:WindowsDir "bin"
|
||||
$script:InstallScript = Join-Path $script:WindowsDir "install.ps1"
|
||||
$script:VisualDefaultsErrorPattern = 'property ''Solid'' cannot be found|找不到属性.?Solid|VariableIsUndefined|\$script:Colors'
|
||||
$script:VisualDefaultsErrorPattern = 'property ''(Solid|Error)'' cannot be found|找不到属性.?(Solid|Error)|VariableIsUndefined|\$script:Colors'
|
||||
}
|
||||
|
||||
Describe "Clean Command" {
|
||||
|
||||
@@ -70,6 +70,14 @@ Describe "Base Module" {
|
||||
$script:Icons.Solid | Should -Be "*"
|
||||
$script:Icons.Admin | Should -Not -BeNullOrEmpty
|
||||
}
|
||||
|
||||
It "Should restore missing icon entries on demand" {
|
||||
$script:Icons = @{ Solid = "*" }
|
||||
|
||||
(Get-MoleIcon -Name "Error") | Should -Not -BeNullOrEmpty
|
||||
$script:Icons.Error | Should -Not -BeNullOrEmpty
|
||||
$script:Icons.Solid | Should -Be "*"
|
||||
}
|
||||
}
|
||||
|
||||
Context "Test-IsAdmin" {
|
||||
@@ -242,6 +250,19 @@ Describe "Logging Module" {
|
||||
# Note: The actual function is Write-MoleError
|
||||
{ Write-MoleError "Test message" } | Should -Not -Throw
|
||||
}
|
||||
|
||||
It "Should log errors even when the icon table is partial" {
|
||||
$originalIcons = $script:Icons.Clone()
|
||||
|
||||
try {
|
||||
$script:Icons = @{ Solid = "*" }
|
||||
{ Write-MoleError "Test message" } | Should -Not -Throw
|
||||
$script:Icons.Error | Should -Not -BeNullOrEmpty
|
||||
}
|
||||
finally {
|
||||
$script:Icons = $originalIcons
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context "Section Functions" {
|
||||
|
||||
Reference in New Issue
Block a user