main 5041353

migrate_config.go RawHistoryFolder

1package usecase
2
3import (
4	"context"
5
6	"github.com/bnema/dumber/internal/application/port"
7	"github.com/bnema/dumber/internal/logging"
8)
9
10// CheckConfigMigrationInput holds the input for checking config migration.
11type CheckConfigMigrationInput struct{}
12
13// CheckConfigMigrationOutput holds the result of the migration check.
14type CheckConfigMigrationOutput struct {
15	// NeedsMigration is true if there are missing keys.
16	NeedsMigration bool
17	// MissingKeys contains info about each missing key.
18	MissingKeys []port.KeyInfo
19	// ConfigFile is the path to the config file.
20	ConfigFile string
21}
22
23// DetectChangesInput holds the input for detecting config changes.
24type DetectChangesInput struct{}
25
26// DetectChangesOutput holds the result of change detection.
27type DetectChangesOutput struct {
28	// HasChanges is true if any changes were detected.
29	HasChanges bool
30	// Changes contains all detected changes.
31	Changes []port.KeyChange
32	// DiffText is a formatted diff-like string representation.
33	DiffText string
34}
35
36// MigrateConfigInput holds the input for migrating config.
37type MigrateConfigInput struct{}
38
39// MigrateConfigOutput holds the result of the migration.
40type MigrateConfigOutput struct {
41	// AddedKeys contains the keys that were added.
42	AddedKeys []string
43	// ConfigFile is the path to the config file.
44	ConfigFile string
45}
46
47// MigrateConfigUseCase handles config migration operations.
48type MigrateConfigUseCase struct {
49	migrator      port.ConfigMigrator
50	diffFormatter port.DiffFormatter
51}
52
53// NewMigrateConfigUseCase creates a new migrate config use case.
54func NewMigrateConfigUseCase(migrator port.ConfigMigrator, diffFormatter port.DiffFormatter) *MigrateConfigUseCase {
55	return &MigrateConfigUseCase{
56		migrator:      migrator,
57		diffFormatter: diffFormatter,
58	}
59}
60
61// Check checks if the user config is missing any default keys.
62func (uc *MigrateConfigUseCase) Check(ctx context.Context, _ CheckConfigMigrationInput) (*CheckConfigMigrationOutput, error) {
63	log := logging.FromContext(ctx)
64
65	result, err := uc.migrator.CheckMigration()
66	if err != nil {
67		log.Warn().Err(err).Msg("config migration check failed")
68		return nil, err
69	}
70
71	// No migration needed
72	if result == nil || len(result.MissingKeys) == 0 {
73		log.Debug().Msg("config is up to date, no migration needed")
74		return &CheckConfigMigrationOutput{
75			NeedsMigration: false,
76			MissingKeys:    nil,
77			ConfigFile:     "",
78		}, nil
79	}
80
81	// Build key info for each missing key
82	keyInfos := make([]port.KeyInfo, 0, len(result.MissingKeys))
83	for _, key := range result.MissingKeys {
84		keyInfos = append(keyInfos, uc.migrator.GetKeyInfo(key))
85	}
86
87	log.Debug().
88		Int("missing_keys", len(result.MissingKeys)).
89		Str("config_file", result.ConfigFile).
90		Msg("config migration check completed")
91
92	return &CheckConfigMigrationOutput{
93		NeedsMigration: true,
94		MissingKeys:    keyInfos,
95		ConfigFile:     result.ConfigFile,
96	}, nil
97}
98
99// DetectChanges detects all config changes and returns a diff-like output.
100func (uc *MigrateConfigUseCase) DetectChanges(ctx context.Context, _ DetectChangesInput) (*DetectChangesOutput, error) {
101	log := logging.FromContext(ctx)
102
103	changes, err := uc.migrator.DetectChanges()
104	if err != nil {
105		log.Warn().Err(err).Msg("config change detection failed")
106		return nil, err
107	}
108
109	if len(changes) == 0 {
110		log.Debug().Msg("no config changes detected")
111		return &DetectChangesOutput{
112			HasChanges: false,
113			Changes:    nil,
114			DiffText:   "No changes detected.",
115		}, nil
116	}
117
118	log.Debug().
119		Int("changes", len(changes)).
120		Msg("config changes detected")
121
122	return &DetectChangesOutput{
123		HasChanges: true,
124		Changes:    changes,
125		DiffText:   uc.diffFormatter.FormatChangesAsDiff(changes),
126	}, nil
127}
128
129// Execute adds missing default keys and removes deprecated keys from the user's config file.
130func (uc *MigrateConfigUseCase) Execute(ctx context.Context, _ MigrateConfigInput) (*MigrateConfigOutput, error) {
131	log := logging.FromContext(ctx)
132
133	// Check for any changes (added, removed, or renamed keys)
134	changes, err := uc.migrator.DetectChanges()
135	if err != nil {
136		return nil, err
137	}
138
139	if len(changes) == 0 {
140		log.Debug().Msg("no migration needed")
141		return &MigrateConfigOutput{
142			AddedKeys:  nil,
143			ConfigFile: "",
144		}, nil
145	}
146
147	// Get config file path for output
148	configFile, _ := uc.migrator.GetConfigFile()
149
150	// Perform migration
151	appliedKeys, err := uc.migrator.Migrate()
152	if err != nil {
153		log.Error().Err(err).Msg("config migration failed")
154		return nil, err
155	}
156
157	log.Info().
158		Int("applied_keys", len(appliedKeys)).
159		Str("config_file", configFile).
160		Msg("config migration completed")
161
162	return &MigrateConfigOutput{
163		AddedKeys:  appliedKeys,
164		ConfigFile: configFile,
165	}, nil
166}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close