fix: preserve selections when config import is invalid (#4994)

* fix: validate imports before replacing selections

* test: cover atomic config imports

* docs: explain stale config imports

---------

Co-authored-by: Guilherme de Oliveira Rocha <contatoguilhermeoliveira@protonmail.com>
Co-authored-by: Chris Titus <contact@christitus.com>
This commit is contained in:
Guilherme Oliveira
2026-08-19 15:30:46 -05:00
committed by GitHub
co-authored by Guilherme de Oliveira Rocha Chris Titus
parent 2d0fd43bd3
commit 792122e998
4 changed files with 183 additions and 13 deletions
+56 -2
View File
@@ -1,4 +1,19 @@
function Update-WinUtilSelections ($flatJson) {
function Update-WinUtilSelections {
param(
[Parameter(Mandatory)]
[string[]]$flatJson,
[switch]$Replace
)
$nextSelections = @{
selectedApps = [System.Collections.Generic.List[string]]::new()
selectedTweaks = [System.Collections.Generic.List[string]]::new()
selectedToggles = [System.Collections.Generic.List[string]]::new()
selectedFeatures = [System.Collections.Generic.List[string]]::new()
selectedAppx = [System.Collections.Generic.List[string]]::new()
}
foreach ($cbkey in $flatJson) {
$listName = switch -Regex ($cbkey) {
@@ -9,6 +24,45 @@ function Update-WinUtilSelections ($flatJson) {
'^WPFAppx' { 'selectedAppx' }
}
$sync.$listName.Add($cbkey)
if (-not $listName) {
throw "Unsupported selection key '$cbkey'."
}
$isKnownSelection = switch ($listName) {
'selectedApps' {
$sync.configs.applicationsHashtable.ContainsKey($cbkey)
}
'selectedTweaks' {
$null -ne $sync.configs.tweaks.PSObject.Properties[$cbkey]
}
'selectedToggles' {
$null -ne $sync.configs.tweaks.PSObject.Properties[$cbkey]
}
'selectedFeatures' {
$null -ne $sync.configs.feature.PSObject.Properties[$cbkey]
}
'selectedAppx' {
$sync.configs.appxHashtable.ContainsKey($cbkey)
}
}
if (-not $isKnownSelection) {
throw "Unknown selection key '$cbkey'."
}
$nextSelections[$listName].Add($cbkey)
}
if ($Replace) {
foreach ($listName in $nextSelections.Keys) {
$sync[$listName] = $nextSelections[$listName]
}
return
}
foreach ($listName in $nextSelections.Keys) {
foreach ($cbkey in $nextSelections[$listName]) {
$sync.$listName.Add($cbkey)
}
}
}
+3 -9
View File
@@ -84,15 +84,9 @@ function Invoke-WPFImpex {
return
}
# Clear all existing selections before importing so the import replaces
# the current state rather than merging with it
$sync.selectedAppx = [System.Collections.Generic.List[string]]::new()
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
$sync.selectedTweaks = [System.Collections.Generic.List[string]]::new()
$sync.selectedToggles = [System.Collections.Generic.List[string]]::new()
$sync.selectedFeatures = [System.Collections.Generic.List[string]]::new()
Update-WinUtilSelections -flatJson $flattenedJson
# Build and validate every imported selection before replacing the current
# state. This keeps a malformed config from leaving partial selections behind.
Update-WinUtilSelections -flatJson $flattenedJson -Replace
if ($sync.Form) {
Reset-WPFCheckBoxes -doToggles $true