feat(config): some additional config options, and config migration from deprecated keys
This commit is contained in:
parent
629358a81b
commit
4e78cefd56
16 changed files with 363 additions and 51 deletions
92
cmd/config_migrate.go
Normal file
92
cmd/config_migrate.go
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package cmd
|
||||
|
||||
import "strings"
|
||||
|
||||
type deprecation struct {
|
||||
Old string // e.g. "list.list_all_stores"
|
||||
New string // e.g. "list.always_show_all_stores"
|
||||
}
|
||||
|
||||
type migration struct {
|
||||
Old string // key that was removed
|
||||
New string // key that holds the value
|
||||
Conflict bool // both old and new were present; new key wins
|
||||
}
|
||||
|
||||
var deprecations = []deprecation{
|
||||
{"list.list_all_stores", "list.always_show_all_stores"},
|
||||
}
|
||||
|
||||
func migrateRawConfig(raw map[string]any) []migration {
|
||||
var migrations []migration
|
||||
for _, dep := range deprecations {
|
||||
oldParts := strings.Split(dep.Old, ".")
|
||||
newParts := strings.Split(dep.New, ".")
|
||||
|
||||
_, ok := nestedGet(raw, oldParts)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
m := migration{Old: dep.Old, New: dep.New}
|
||||
if _, exists := nestedGet(raw, newParts); exists {
|
||||
m.Conflict = true
|
||||
} else {
|
||||
nestedSet(raw, newParts, nestedMustGet(raw, oldParts))
|
||||
}
|
||||
nestedDelete(raw, oldParts)
|
||||
migrations = append(migrations, m)
|
||||
}
|
||||
return migrations
|
||||
}
|
||||
|
||||
func nestedMustGet(m map[string]any, parts []string) any {
|
||||
v, _ := nestedGet(m, parts)
|
||||
return v
|
||||
}
|
||||
|
||||
func nestedGet(m map[string]any, parts []string) (any, bool) {
|
||||
for i, p := range parts {
|
||||
v, ok := m[p]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
if i == len(parts)-1 {
|
||||
return v, true
|
||||
}
|
||||
sub, ok := v.(map[string]any)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
m = sub
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func nestedSet(m map[string]any, parts []string, val any) {
|
||||
for i, p := range parts {
|
||||
if i == len(parts)-1 {
|
||||
m[p] = val
|
||||
return
|
||||
}
|
||||
sub, ok := m[p].(map[string]any)
|
||||
if !ok {
|
||||
sub = make(map[string]any)
|
||||
m[p] = sub
|
||||
}
|
||||
m = sub
|
||||
}
|
||||
}
|
||||
|
||||
func nestedDelete(m map[string]any, parts []string) {
|
||||
for i, p := range parts {
|
||||
if i == len(parts)-1 {
|
||||
delete(m, p)
|
||||
return
|
||||
}
|
||||
sub, ok := m[p].(map[string]any)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
m = sub
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue