Skip to content

Commit 0138b9e

Browse files
committed
fixup! Log a list of migration changes to the console
1 parent 14770a8 commit 0138b9e

File tree

2 files changed

+40
-43
lines changed

2 files changed

+40
-43
lines changed

pkg/config/app_config.go

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import (
1111
"time"
1212

1313
"github.com/adrg/xdg"
14+
"github.com/jesseduffield/generics/orderedset"
1415
"github.com/jesseduffield/lazygit/pkg/utils"
1516
"github.com/jesseduffield/lazygit/pkg/utils/yaml_utils"
1617
"github.com/samber/lo"
17-
orderedmap "github.com/wk8/go-ordered-map/v2"
1818
"gopkg.in/yaml.v3"
1919
)
2020

@@ -216,12 +216,18 @@ func loadUserConfig(configFiles []*ConfigFile, base *UserConfig, isGuiInitialize
216216
return base, nil
217217
}
218218

219+
type ChangesSet = orderedset.OrderedSet[string]
220+
221+
func NewChangesSet() *ChangesSet {
222+
return orderedset.New[string]()
223+
}
224+
219225
// Do any backward-compatibility migrations of things that have changed in the
220226
// config over time; examples are renaming a key to a better name, moving a key
221227
// from one container to another, or changing the type of a key (e.g. from bool
222228
// to an enum).
223229
func migrateUserConfig(path string, content []byte, isGuiInitialized bool) ([]byte, error) {
224-
changes := orderedmap.New[string, bool]()
230+
changes := NewChangesSet()
225231

226232
changedContent, didChange, err := computeMigratedConfig(path, content, changes)
227233
if err != nil {
@@ -234,9 +240,9 @@ func migrateUserConfig(path string, content []byte, isGuiInitialized bool) ([]by
234240
}
235241

236242
changesText := "The following changes were made:\n\n"
237-
for pair := changes.Oldest(); pair != nil; pair = pair.Next() {
238-
changesText += fmt.Sprintf("- %s\n", pair.Key)
239-
}
243+
changesText += strings.Join(lo.Map(changes.ToSliceFromOldest(), func(change string, _ int) string {
244+
return fmt.Sprintf("- %s\n", change)
245+
}), "")
240246

241247
// Write config back
242248
if !isGuiInitialized {
@@ -257,7 +263,7 @@ func migrateUserConfig(path string, content []byte, isGuiInitialized bool) ([]by
257263
}
258264

259265
// A pure function helper for testing purposes
260-
func computeMigratedConfig(path string, content []byte, changes *orderedmap.OrderedMap[string, bool]) ([]byte, bool, error) {
266+
func computeMigratedConfig(path string, content []byte, changes *ChangesSet) ([]byte, bool, error) {
261267
var err error
262268
var rootNode yaml.Node
263269
err = yaml.Unmarshal(content, &rootNode)
@@ -285,7 +291,7 @@ func computeMigratedConfig(path string, content []byte, changes *orderedmap.Orde
285291
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s` for key %s: %s", path, strings.Join(pathToReplace.oldPath, "."), err)
286292
}
287293
if didReplace {
288-
changes.Set(fmt.Sprintf("Renamed '%s' to '%s'", strings.Join(pathToReplace.oldPath, "."), pathToReplace.newName), true)
294+
changes.Add(fmt.Sprintf("Renamed '%s' to '%s'", strings.Join(pathToReplace.oldPath, "."), pathToReplace.newName))
289295
}
290296
}
291297

@@ -327,17 +333,17 @@ func computeMigratedConfig(path string, content []byte, changes *orderedmap.Orde
327333
return newContent, true, nil
328334
}
329335

330-
func changeNullKeybindingsToDisabled(rootNode *yaml.Node, changes *orderedmap.OrderedMap[string, bool]) error {
336+
func changeNullKeybindingsToDisabled(rootNode *yaml.Node, changes *ChangesSet) error {
331337
return yaml_utils.Walk(rootNode, func(node *yaml.Node, path string) {
332338
if strings.HasPrefix(path, "keybinding.") && node.Kind == yaml.ScalarNode && node.Tag == "!!null" {
333339
node.Value = "<disabled>"
334340
node.Tag = "!!str"
335-
changes.Set(fmt.Sprintf("Changed 'null' to '<disabled>' for keybinding '%s'", path), true)
341+
changes.Add(fmt.Sprintf("Changed 'null' to '<disabled>' for keybinding '%s'", path))
336342
}
337343
})
338344
}
339345

340-
func changeElementToSequence(rootNode *yaml.Node, path []string, changes *orderedmap.OrderedMap[string, bool]) error {
346+
func changeElementToSequence(rootNode *yaml.Node, path []string, changes *ChangesSet) error {
341347
return yaml_utils.TransformNode(rootNode, path, func(node *yaml.Node) error {
342348
if node.Kind == yaml.MappingNode {
343349
nodeContentCopy := node.Content
@@ -349,15 +355,15 @@ func changeElementToSequence(rootNode *yaml.Node, path []string, changes *ordere
349355
Content: nodeContentCopy,
350356
}}
351357

352-
changes.Set(fmt.Sprintf("Changed '%s' to an array of strings", strings.Join(path, ".")), true)
358+
changes.Add(fmt.Sprintf("Changed '%s' to an array of strings", strings.Join(path, ".")))
353359

354360
return nil
355361
}
356362
return nil
357363
})
358364
}
359365

360-
func changeCommitPrefixesMap(rootNode *yaml.Node, changes *orderedmap.OrderedMap[string, bool]) error {
366+
func changeCommitPrefixesMap(rootNode *yaml.Node, changes *ChangesSet) error {
361367
return yaml_utils.TransformNode(rootNode, []string{"git", "commitPrefixes"}, func(prefixesNode *yaml.Node) error {
362368
if prefixesNode.Kind == yaml.MappingNode {
363369
for _, contentNode := range prefixesNode.Content {
@@ -370,15 +376,15 @@ func changeCommitPrefixesMap(rootNode *yaml.Node, changes *orderedmap.OrderedMap
370376
Kind: yaml.MappingNode,
371377
Content: nodeContentCopy,
372378
}}
373-
changes.Set("Changed 'git.commitPrefixes' elements to arrays of strings", true)
379+
changes.Add("Changed 'git.commitPrefixes' elements to arrays of strings")
374380
}
375381
}
376382
}
377383
return nil
378384
})
379385
}
380386

381-
func changeCustomCommandStreamAndOutputToOutputEnum(rootNode *yaml.Node, changes *orderedmap.OrderedMap[string, bool]) error {
387+
func changeCustomCommandStreamAndOutputToOutputEnum(rootNode *yaml.Node, changes *ChangesSet) error {
382388
return yaml_utils.Walk(rootNode, func(node *yaml.Node, path string) {
383389
// We are being lazy here and rely on the fact that the only mapping
384390
// nodes in the tree under customCommands are actual custom commands. If
@@ -389,25 +395,25 @@ func changeCustomCommandStreamAndOutputToOutputEnum(rootNode *yaml.Node, changes
389395
if streamKey, streamValue := yaml_utils.RemoveKey(node, "subprocess"); streamKey != nil {
390396
if streamValue.Kind == yaml.ScalarNode && streamValue.Value == "true" {
391397
output = "terminal"
392-
changes.Set("Changed 'subprocess: true' to 'output: terminal' in custom command", true)
398+
changes.Add("Changed 'subprocess: true' to 'output: terminal' in custom command")
393399
} else {
394-
changes.Set("Deleted redundant 'subprocess: false' in custom command", true)
400+
changes.Add("Deleted redundant 'subprocess: false' in custom command")
395401
}
396402
}
397403
if streamKey, streamValue := yaml_utils.RemoveKey(node, "stream"); streamKey != nil {
398404
if streamValue.Kind == yaml.ScalarNode && streamValue.Value == "true" && output == "" {
399405
output = "log"
400-
changes.Set("Changed 'stream: true' to 'output: log' in custom command", true)
406+
changes.Add("Changed 'stream: true' to 'output: log' in custom command")
401407
} else {
402-
changes.Set(fmt.Sprintf("Deleted redundant 'stream: %v' property in custom command", streamValue.Value), true)
408+
changes.Add(fmt.Sprintf("Deleted redundant 'stream: %v' property in custom command", streamValue.Value))
403409
}
404410
}
405411
if streamKey, streamValue := yaml_utils.RemoveKey(node, "showOutput"); streamKey != nil {
406412
if streamValue.Kind == yaml.ScalarNode && streamValue.Value == "true" && output == "" {
407-
changes.Set("Changed 'showOutput: true' to 'output: popup' in custom command", true)
413+
changes.Add("Changed 'showOutput: true' to 'output: popup' in custom command")
408414
output = "popup"
409415
} else {
410-
changes.Set(fmt.Sprintf("Deleted redundant 'showOutput: %v' property in custom command", streamValue.Value), true)
416+
changes.Add(fmt.Sprintf("Deleted redundant 'showOutput: %v' property in custom command", streamValue.Value))
411417
}
412418
}
413419
if output != "" {
@@ -431,7 +437,7 @@ func changeCustomCommandStreamAndOutputToOutputEnum(rootNode *yaml.Node, changes
431437
// a single element at `allBranchesLogCmd` and the sequence at `allBranchesLogCmds`.
432438
// Some users have explicitly set `allBranchesLogCmd` to be an empty string in order
433439
// to remove it, so in that case we just delete the element, and add nothing to the list
434-
func migrateAllBranchesLogCmd(rootNode *yaml.Node, changes *orderedmap.OrderedMap[string, bool]) error {
440+
func migrateAllBranchesLogCmd(rootNode *yaml.Node, changes *ChangesSet) error {
435441
return yaml_utils.TransformNode(rootNode, []string{"git"}, func(gitNode *yaml.Node) error {
436442
cmdKeyNode, cmdValueNode := yaml_utils.LookupKey(gitNode, "allBranchesLogCmd")
437443
// Nothing to do if they do not have the deprecated item
@@ -462,12 +468,12 @@ func migrateAllBranchesLogCmd(rootNode *yaml.Node, changes *orderedmap.OrderedMa
462468
if cmdValueNode.Value != "" {
463469
// Prepending the individual element to make it show up first in the list, which was prior behavior
464470
cmdsValueNode.Content = utils.Prepend(cmdsValueNode.Content, &yaml.Node{Kind: yaml.ScalarNode, Value: cmdValueNode.Value})
465-
changes.Set(change, true)
471+
changes.Add(change)
466472
}
467473

468474
// Clear out the existing allBranchesLogCmd, now that we have migrated it into the list
469475
_, _ = yaml_utils.RemoveKey(gitNode, "allBranchesLogCmd")
470-
changes.Set("Removed obsolete git.allBranchesLogCmd", true)
476+
changes.Add("Removed obsolete git.allBranchesLogCmd")
471477

472478
return nil
473479
})

pkg/config/app_config_test.go

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,8 @@ import (
44
"testing"
55

66
"github.com/stretchr/testify/assert"
7-
orderedmap "github.com/wk8/go-ordered-map/v2"
87
)
98

10-
func orderedMapToSlice(m *orderedmap.OrderedMap[string, bool]) []string {
11-
result := make([]string, 0, m.Len())
12-
for i := m.Oldest(); i != nil; i = i.Next() {
13-
result = append(result, i.Key)
14-
}
15-
return result
16-
}
17-
189
func TestMigrationOfRenamedKeys(t *testing.T) {
1910
scenarios := []struct {
2011
name string
@@ -75,14 +66,14 @@ keybinding:
7566

7667
for _, s := range scenarios {
7768
t.Run(s.name, func(t *testing.T) {
78-
changes := orderedmap.New[string, bool]()
69+
changes := NewChangesSet()
7970
actual, didChange, err := computeMigratedConfig("path doesn't matter", []byte(s.input), changes)
8071
assert.NoError(t, err)
8172
assert.Equal(t, s.expectedDidChange, didChange)
8273
if didChange {
8374
assert.Equal(t, s.expected, string(actual))
8475
}
85-
assert.Equal(t, s.expectedChanges, orderedMapToSlice(changes))
76+
assert.Equal(t, s.expectedChanges, changes.ToSliceFromOldest())
8677
})
8778
}
8879
}
@@ -147,14 +138,14 @@ func TestMigrateNullKeybindingsToDisabled(t *testing.T) {
147138

148139
for _, s := range scenarios {
149140
t.Run(s.name, func(t *testing.T) {
150-
changes := orderedmap.New[string, bool]()
141+
changes := NewChangesSet()
151142
actual, didChange, err := computeMigratedConfig("path doesn't matter", []byte(s.input), changes)
152143
assert.NoError(t, err)
153144
assert.Equal(t, s.expectedDidChange, didChange)
154145
if didChange {
155146
assert.Equal(t, s.expected, string(actual))
156147
}
157-
assert.Equal(t, s.expectedChanges, orderedMapToSlice(changes))
148+
assert.Equal(t, s.expectedChanges, changes.ToSliceFromOldest())
158149
})
159150
}
160151
}
@@ -235,14 +226,14 @@ git:
235226

236227
for _, s := range scenarios {
237228
t.Run(s.name, func(t *testing.T) {
238-
changes := orderedmap.New[string, bool]()
229+
changes := NewChangesSet()
239230
actual, didChange, err := computeMigratedConfig("path doesn't matter", []byte(s.input), changes)
240231
assert.NoError(t, err)
241232
assert.Equal(t, s.expectedDidChange, didChange)
242233
if didChange {
243234
assert.Equal(t, s.expected, string(actual))
244235
}
245-
assert.Equal(t, s.expectedChanges, orderedMapToSlice(changes))
236+
assert.Equal(t, s.expectedChanges, changes.ToSliceFromOldest())
246237
})
247238
}
248239
}
@@ -358,14 +349,14 @@ func TestCustomCommandsOutputMigration(t *testing.T) {
358349

359350
for _, s := range scenarios {
360351
t.Run(s.name, func(t *testing.T) {
361-
changes := orderedmap.New[string, bool]()
352+
changes := NewChangesSet()
362353
actual, didChange, err := computeMigratedConfig("path doesn't matter", []byte(s.input), changes)
363354
assert.NoError(t, err)
364355
assert.Equal(t, s.expectedDidChange, didChange)
365356
if didChange {
366357
assert.Equal(t, s.expected, string(actual))
367358
}
368-
assert.Equal(t, s.expectedChanges, orderedMapToSlice(changes))
359+
assert.Equal(t, s.expectedChanges, changes.ToSliceFromOldest())
369360
})
370361
}
371362
}
@@ -974,7 +965,7 @@ keybinding:
974965

975966
func BenchmarkMigrationOnLargeConfiguration(b *testing.B) {
976967
for b.Loop() {
977-
changes := orderedmap.New[string, bool]()
968+
changes := NewChangesSet()
978969
_, _, _ = computeMigratedConfig("path doesn't matter", largeConfiguration, changes)
979970
}
980971
}
@@ -1084,14 +1075,14 @@ func TestAllBranchesLogCmdMigrations(t *testing.T) {
10841075

10851076
for _, s := range scenarios {
10861077
t.Run(s.name, func(t *testing.T) {
1087-
changes := orderedmap.New[string, bool]()
1078+
changes := NewChangesSet()
10881079
actual, didChange, err := computeMigratedConfig("path doesn't matter", []byte(s.input), changes)
10891080
assert.NoError(t, err)
10901081
assert.Equal(t, s.expectedDidChange, didChange)
10911082
if didChange {
10921083
assert.Equal(t, s.expected, string(actual))
10931084
}
1094-
assert.Equal(t, s.expectedChanges, orderedMapToSlice(changes))
1085+
assert.Equal(t, s.expectedChanges, changes.ToSliceFromOldest())
10951086
})
10961087
}
10971088
}

0 commit comments

Comments
 (0)