Skip to content

Commit 1047cdf

Browse files
committed
feat: add snapshot summary screen after editing
- Show comprehensive summary after editing, before upload confirmation - Display package counts, matched preset, shell/git/dev tools info - Improve local save output with detailed summary and restore command - Fix progress counter from 7 to 8 steps
1 parent 014b51c commit 1047cdf

1 file changed

Lines changed: 113 additions & 7 deletions

File tree

internal/cli/snapshot.go

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ func runSnapshot(cmd *cobra.Command) error {
104104
if err != nil {
105105
return fmt.Errorf("failed to save snapshot: %w", err)
106106
}
107-
fmt.Fprintln(os.Stderr)
108-
fmt.Fprintln(os.Stderr, snapSuccessStyle.Render("✓ Snapshot saved to "+path))
109-
fmt.Fprintln(os.Stderr)
107+
showLocalSaveSummary(snap, path)
110108
return nil
111109
}
112110

@@ -130,6 +128,9 @@ func runSnapshot(cmd *cobra.Command) error {
130128
return nil
131129
}
132130

131+
// --- SUMMARY PHASE ---
132+
showSnapshotSummary(edited)
133+
133134
// --- CONFIRM PHASE ---
134135
fmt.Fprintln(os.Stderr)
135136
upload, err := ui.Confirm("Upload this snapshot to openboot.dev?", false)
@@ -138,7 +139,7 @@ func runSnapshot(cmd *cobra.Command) error {
138139
}
139140

140141
if !upload {
141-
// Offer local save as fallback
142+
fmt.Fprintln(os.Stderr)
142143
saveLocal, err := ui.Confirm("Save snapshot locally instead?", true)
143144
if err != nil {
144145
return err
@@ -148,11 +149,12 @@ func runSnapshot(cmd *cobra.Command) error {
148149
if err != nil {
149150
return fmt.Errorf("failed to save snapshot: %w", err)
150151
}
151-
fmt.Fprintln(os.Stderr, snapSuccessStyle.Render("✓ Snapshot saved to "+path))
152+
showLocalSaveSummary(edited, path)
152153
} else {
154+
fmt.Fprintln(os.Stderr)
153155
fmt.Fprintln(os.Stderr, snapMutedStyle.Render("Snapshot discarded."))
156+
fmt.Fprintln(os.Stderr)
154157
}
155-
fmt.Fprintln(os.Stderr)
156158
return nil
157159
}
158160

@@ -164,7 +166,7 @@ func runSnapshot(cmd *cobra.Command) error {
164166
func captureWithUI() (*snapshot.Snapshot, error) {
165167
fmt.Fprintln(os.Stderr)
166168

167-
progress := ui.NewScanProgress(7)
169+
progress := ui.NewScanProgress(8)
168170

169171
snap, err := snapshot.CaptureWithProgress(func(step snapshot.ScanStep) {
170172
progress.Update(step)
@@ -273,6 +275,110 @@ func uploadSnapshot(snap *snapshot.Snapshot) error {
273275
return nil
274276
}
275277

278+
func showLocalSaveSummary(snap *snapshot.Snapshot, path string) {
279+
fmt.Fprintln(os.Stderr)
280+
fmt.Fprintln(os.Stderr, snapSuccessStyle.Render("✓ Snapshot saved successfully!"))
281+
fmt.Fprintln(os.Stderr)
282+
283+
totalFormulae := len(snap.Packages.Formulae)
284+
totalCasks := len(snap.Packages.Casks)
285+
totalTaps := len(snap.Packages.Taps)
286+
totalNpm := len(snap.Packages.Npm)
287+
288+
fmt.Fprintf(os.Stderr, " %s %d formulae, %d casks, %d taps, %d npm\n",
289+
snapBoldStyle.Render("Saved:"),
290+
totalFormulae, totalCasks, totalTaps, totalNpm)
291+
292+
if snap.MatchedPreset != "" {
293+
matchRate := int(snap.CatalogMatch.MatchRate * 100)
294+
fmt.Fprintf(os.Stderr, " %s Matches \"%s\" (%d%% similarity)\n",
295+
snapBoldStyle.Render("Preset:"),
296+
snap.MatchedPreset, matchRate)
297+
}
298+
299+
fmt.Fprintf(os.Stderr, " %s %s\n",
300+
snapBoldStyle.Render("Location:"),
301+
path)
302+
303+
fmt.Fprintln(os.Stderr)
304+
fmt.Fprintln(os.Stderr, snapBoldStyle.Render(" Restore this snapshot:"))
305+
fmt.Fprintf(os.Stderr, " %s\n", snapMutedStyle.Render("openboot snapshot --import "+path))
306+
fmt.Fprintln(os.Stderr)
307+
}
308+
309+
func showSnapshotSummary(snap *snapshot.Snapshot) {
310+
fmt.Fprintln(os.Stderr)
311+
fmt.Fprintln(os.Stderr, snapTitleStyle.Render("=== Snapshot Summary ==="))
312+
fmt.Fprintln(os.Stderr)
313+
314+
totalFormulae := len(snap.Packages.Formulae)
315+
totalCasks := len(snap.Packages.Casks)
316+
totalTaps := len(snap.Packages.Taps)
317+
totalNpm := len(snap.Packages.Npm)
318+
319+
fmt.Fprintf(os.Stderr, " %s %d formulae, %d casks, %d taps, %d npm packages\n",
320+
snapBoldStyle.Render("Packages:"),
321+
totalFormulae, totalCasks, totalTaps, totalNpm)
322+
323+
if snap.MatchedPreset != "" {
324+
matchRate := int(snap.CatalogMatch.MatchRate * 100)
325+
fmt.Fprintf(os.Stderr, " %s Matches \"%s\" (%d%% similarity)\n",
326+
snapBoldStyle.Render("Preset:"),
327+
snap.MatchedPreset, matchRate)
328+
} else {
329+
fmt.Fprintf(os.Stderr, " %s Custom configuration\n",
330+
snapBoldStyle.Render("Preset:"))
331+
}
332+
333+
omzStatus := "not installed"
334+
if snap.Shell.OhMyZsh {
335+
theme := snap.Shell.Theme
336+
if theme == "" {
337+
theme = "default"
338+
}
339+
pluginCount := len(snap.Shell.Plugins)
340+
omzStatus = fmt.Sprintf("Oh-My-Zsh (%s theme, %d plugins)", theme, pluginCount)
341+
}
342+
fmt.Fprintf(os.Stderr, " %s %s + %s\n",
343+
snapBoldStyle.Render("Shell:"),
344+
snap.Shell.Default, omzStatus)
345+
346+
if snap.Git.UserName != "" || snap.Git.UserEmail != "" {
347+
fmt.Fprintf(os.Stderr, " %s %s <%s>\n",
348+
snapBoldStyle.Render("Git:"),
349+
snap.Git.UserName, snap.Git.UserEmail)
350+
} else {
351+
fmt.Fprintf(os.Stderr, " %s Not configured\n",
352+
snapBoldStyle.Render("Git:"))
353+
}
354+
355+
if len(snap.DevTools) > 0 {
356+
var toolNames []string
357+
for _, tool := range snap.DevTools {
358+
toolNames = append(toolNames, tool.Name)
359+
}
360+
fmt.Fprintf(os.Stderr, " %s %s\n",
361+
snapBoldStyle.Render("Dev Tools:"),
362+
strings.Join(toolNames, ", "))
363+
} else {
364+
fmt.Fprintf(os.Stderr, " %s None detected\n",
365+
snapBoldStyle.Render("Dev Tools:"))
366+
}
367+
368+
prefCount := len(snap.MacOSPrefs)
369+
fmt.Fprintf(os.Stderr, " %s %d preferences captured\n",
370+
snapBoldStyle.Render("macOS:"),
371+
prefCount)
372+
373+
fmt.Fprintln(os.Stderr)
374+
capturedTime := snap.CapturedAt.Format("2006-01-02 15:04:05")
375+
fmt.Fprintf(os.Stderr, " %s %s\n",
376+
snapMutedStyle.Render("Captured:"),
377+
snapMutedStyle.Render(capturedTime))
378+
379+
fmt.Fprintln(os.Stderr)
380+
}
381+
276382
func showSnapshotPreview(snap *snapshot.Snapshot) {
277383
fmt.Fprintln(os.Stderr)
278384
fmt.Fprintln(os.Stderr, snapTitleStyle.Render("=== Snapshot Preview ==="))

0 commit comments

Comments
 (0)