Skip to content

Commit 10d3124

Browse files
committed
refactor: simplify CaptureWithProgress and clean up godoc comments
- Refactor CaptureWithProgress from 8 copy-paste blocks to step-driven loop (112 lines → 30 lines) using captureStep struct for DRY capture logic - Remove mechanical godoc comments (e.g., 'FunctionName does X.') - Simplify verbose comments to essential API documentation only - Affected packages: snapshot, auth, state, cleaner This reduces code duplication and improves maintainability without changing behavior or public API.
1 parent 5f38e2f commit 10d3124

6 files changed

Lines changed: 45 additions & 153 deletions

File tree

internal/auth/auth.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ type StoredAuth struct {
1818
CreatedAt time.Time `json:"created_at"`
1919
}
2020

21-
// TokenPath returns the path to the auth token file (~/.openboot/auth.json).
2221
func TokenPath() string {
2322
home, err := os.UserHomeDir()
2423
if err != nil {
@@ -27,8 +26,8 @@ func TokenPath() string {
2726
return filepath.Join(home, ".openboot", "auth.json")
2827
}
2928

30-
// LoadToken reads and unmarshals the stored auth token from disk.
31-
// Returns nil, nil if the file does not exist or the token is expired.
29+
// LoadToken reads the auth token from disk. Returns nil if the file
30+
// doesn't exist or the token is expired.
3231
func LoadToken() (*StoredAuth, error) {
3332
path := TokenPath()
3433
data, err := os.ReadFile(path)
@@ -51,7 +50,7 @@ func LoadToken() (*StoredAuth, error) {
5150
return &auth, nil
5251
}
5352

54-
// SaveToken persists the auth token to disk with restrictive permissions.
53+
// SaveToken writes the auth token to disk with 0600 permissions.
5554
func SaveToken(auth *StoredAuth) error {
5655
path := TokenPath()
5756

@@ -72,7 +71,6 @@ func SaveToken(auth *StoredAuth) error {
7271
return nil
7372
}
7473

75-
// DeleteToken removes the stored auth token file.
7674
func DeleteToken() error {
7775
path := TokenPath()
7876
err := os.Remove(path)
@@ -82,14 +80,12 @@ func DeleteToken() error {
8280
return nil
8381
}
8482

85-
// IsAuthenticated returns true if a valid, non-expired token exists on disk.
8683
func IsAuthenticated() bool {
8784
auth, err := LoadToken()
8885
return err == nil && auth != nil
8986
}
9087

91-
// GenerateCode produces an 8-character uppercase alphanumeric code using
92-
// crypto/rand for secure randomness.
88+
// GenerateCode returns an 8-character code using crypto/rand (ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789).
9389
func GenerateCode() string {
9490
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
9591
code := make([]byte, 8)

internal/auth/login.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ var httpClient = &http.Client{
2323

2424
const DefaultAPIBase = "https://openboot.dev"
2525

26-
// GetAPIBase returns the API base URL, checking the OPENBOOT_API_URL
27-
// environment variable first and falling back to DefaultAPIBase.
26+
// GetAPIBase returns OPENBOOT_API_URL env var or DefaultAPIBase.
2827
func GetAPIBase() string {
2928
if base := os.Getenv("OPENBOOT_API_URL"); base != "" {
3029
return base
@@ -47,9 +46,8 @@ type cliPollResponse struct {
4746
ExpiresAt string `json:"expires_at,omitempty"`
4847
}
4948

50-
// LoginInteractive performs the full CLI-to-browser authentication flow:
51-
// generates a code, starts the auth session, opens the browser for approval,
52-
// and polls until approved or timed out.
49+
// LoginInteractive runs CLI→browser auth flow: generates code, opens browser,
50+
// polls for approval.
5351
func LoginInteractive(apiBase string) (*StoredAuth, error) {
5452
code := GenerateCode()
5553

internal/cleaner/cleaner.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@ type CleanResult struct {
1616
ExtraNpm []string
1717
}
1818

19-
// TotalExtra returns the total number of packages to remove.
2019
func (r *CleanResult) TotalExtra() int {
2120
return len(r.ExtraFormulae) + len(r.ExtraCasks) + len(r.ExtraNpm)
2221
}
2322

24-
// DiffFromSnapshot compares the current system against a snapshot and returns packages
25-
// that are installed but not in the snapshot (i.e. candidates for removal).
2623
func DiffFromSnapshot(snap *snapshot.Snapshot) (*CleanResult, error) {
2724
desiredFormulae := toSet(snap.Packages.Formulae)
2825
desiredCasks := toSet(snap.Packages.Casks)
@@ -31,7 +28,6 @@ func DiffFromSnapshot(snap *snapshot.Snapshot) (*CleanResult, error) {
3128
return diff(desiredFormulae, desiredCasks, desiredNpm)
3229
}
3330

34-
// DiffFromLists compares the current system against explicit package lists.
3531
func DiffFromLists(formulae, casks, npmPkgs []string) (*CleanResult, error) {
3632
return diff(toSet(formulae), toSet(casks), toSet(npmPkgs))
3733
}

internal/snapshot/capture.go

Lines changed: 35 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/openbootdotdev/openboot/internal/system"
1414
)
1515

16-
// Capture orchestrates a full environment snapshot.
1716
func Capture() (*Snapshot, error) {
1817
hostname, err := os.Hostname()
1918
if err != nil {
@@ -92,134 +91,55 @@ type ScanStep struct {
9291
Count int `json:"count"` // items found (only meaningful on "done")
9392
}
9493

95-
// CaptureWithProgress orchestrates a full environment snapshot with progress callbacks.
96-
// The callback is invoked before and after each capture step.
97-
// If callback is nil, it is not invoked.
94+
type captureStep struct {
95+
name string
96+
capture func() (interface{}, error)
97+
count func(interface{}) int
98+
}
99+
98100
func CaptureWithProgress(callback func(step ScanStep)) (*Snapshot, error) {
99101
hostname, err := os.Hostname()
100102
if err != nil {
101103
hostname = "unknown"
102104
}
103105

104-
// Step 0: Homebrew Formulae
105-
if callback != nil {
106-
callback(ScanStep{Name: "Homebrew Formulae", Index: 0, Total: 8, Status: "scanning", Count: 0})
107-
}
108-
formulae, err := CaptureFormulae()
109-
if err != nil {
110-
if callback != nil {
111-
callback(ScanStep{Name: "Homebrew Formulae", Index: 0, Total: 8, Status: "error", Count: 0})
112-
}
113-
} else {
114-
if callback != nil {
115-
callback(ScanStep{Name: "Homebrew Formulae", Index: 0, Total: 8, Status: "done", Count: len(formulae)})
116-
}
117-
}
118-
119-
// Step 1: Homebrew Casks
120-
if callback != nil {
121-
callback(ScanStep{Name: "Homebrew Casks", Index: 1, Total: 8, Status: "scanning", Count: 0})
122-
}
123-
casks, err := CaptureCasks()
124-
if err != nil {
125-
if callback != nil {
126-
callback(ScanStep{Name: "Homebrew Casks", Index: 1, Total: 8, Status: "error", Count: 0})
127-
}
128-
} else {
129-
if callback != nil {
130-
callback(ScanStep{Name: "Homebrew Casks", Index: 1, Total: 8, Status: "done", Count: len(casks)})
131-
}
132-
}
133-
134-
// Step 2: Homebrew Taps
135-
if callback != nil {
136-
callback(ScanStep{Name: "Homebrew Taps", Index: 2, Total: 8, Status: "scanning", Count: 0})
137-
}
138-
taps, err := CaptureTaps()
139-
if err != nil {
140-
if callback != nil {
141-
callback(ScanStep{Name: "Homebrew Taps", Index: 2, Total: 8, Status: "error", Count: 0})
142-
}
143-
} else {
144-
if callback != nil {
145-
callback(ScanStep{Name: "Homebrew Taps", Index: 2, Total: 8, Status: "done", Count: len(taps)})
146-
}
147-
}
148-
149-
// Step 3: NPM Global Packages
150-
if callback != nil {
151-
callback(ScanStep{Name: "NPM Global Packages", Index: 3, Total: 8, Status: "scanning", Count: 0})
152-
}
153-
npmPkgs, err := CaptureNpm()
154-
if err != nil {
155-
if callback != nil {
156-
callback(ScanStep{Name: "NPM Global Packages", Index: 3, Total: 8, Status: "error", Count: 0})
157-
}
158-
} else {
159-
if callback != nil {
160-
callback(ScanStep{Name: "NPM Global Packages", Index: 3, Total: 8, Status: "done", Count: len(npmPkgs)})
161-
}
106+
steps := []captureStep{
107+
{"Homebrew Formulae", func() (interface{}, error) { return CaptureFormulae() }, func(v interface{}) int { return len(v.([]string)) }},
108+
{"Homebrew Casks", func() (interface{}, error) { return CaptureCasks() }, func(v interface{}) int { return len(v.([]string)) }},
109+
{"Homebrew Taps", func() (interface{}, error) { return CaptureTaps() }, func(v interface{}) int { return len(v.([]string)) }},
110+
{"NPM Global Packages", func() (interface{}, error) { return CaptureNpm() }, func(v interface{}) int { return len(v.([]string)) }},
111+
{"macOS Preferences", func() (interface{}, error) { return CaptureMacOSPrefs() }, func(v interface{}) int { return len(v.([]MacOSPref)) }},
112+
{"Shell Environment", func() (interface{}, error) { return CaptureShell() }, func(v interface{}) int { return 1 }},
113+
{"Git Configuration", func() (interface{}, error) { return CaptureGit() }, func(v interface{}) int { return 1 }},
114+
{"Dev Tools", func() (interface{}, error) { return CaptureDevTools() }, func(v interface{}) int { return len(v.([]DevTool)) }},
162115
}
163116

164-
// Step 4: macOS Preferences
165-
if callback != nil {
166-
callback(ScanStep{Name: "macOS Preferences", Index: 4, Total: 8, Status: "scanning", Count: 0})
167-
}
168-
prefs, err := CaptureMacOSPrefs()
169-
if err != nil {
170-
if callback != nil {
171-
callback(ScanStep{Name: "macOS Preferences", Index: 4, Total: 8, Status: "error", Count: 0})
172-
}
173-
} else {
117+
results := make([]interface{}, len(steps))
118+
for i, step := range steps {
174119
if callback != nil {
175-
callback(ScanStep{Name: "macOS Preferences", Index: 4, Total: 8, Status: "done", Count: len(prefs)})
120+
callback(ScanStep{Name: step.name, Index: i, Total: len(steps), Status: "scanning", Count: 0})
176121
}
177-
}
178122

179-
// Step 5: Shell Environment
180-
if callback != nil {
181-
callback(ScanStep{Name: "Shell Environment", Index: 5, Total: 8, Status: "scanning", Count: 0})
182-
}
183-
shellSnap, err := CaptureShell()
184-
if err != nil {
185-
if callback != nil {
186-
callback(ScanStep{Name: "Shell Environment", Index: 5, Total: 8, Status: "error", Count: 0})
187-
}
188-
} else {
189-
if callback != nil {
190-
callback(ScanStep{Name: "Shell Environment", Index: 5, Total: 8, Status: "done", Count: 1})
191-
}
192-
}
123+
result, err := step.capture()
124+
results[i] = result
193125

194-
// Step 6: Git Configuration
195-
if callback != nil {
196-
callback(ScanStep{Name: "Git Configuration", Index: 6, Total: 8, Status: "scanning", Count: 0})
197-
}
198-
gitSnap, err := CaptureGit()
199-
if err != nil {
200-
if callback != nil {
201-
callback(ScanStep{Name: "Git Configuration", Index: 6, Total: 8, Status: "error", Count: 0})
202-
}
203-
} else {
204126
if callback != nil {
205-
callback(ScanStep{Name: "Git Configuration", Index: 6, Total: 8, Status: "done", Count: 1})
127+
if err != nil {
128+
callback(ScanStep{Name: step.name, Index: i, Total: len(steps), Status: "error", Count: 0})
129+
} else {
130+
callback(ScanStep{Name: step.name, Index: i, Total: len(steps), Status: "done", Count: step.count(result)})
131+
}
206132
}
207133
}
208134

209-
// Step 7: Dev Tools
210-
if callback != nil {
211-
callback(ScanStep{Name: "Dev Tools", Index: 7, Total: 8, Status: "scanning", Count: 0})
212-
}
213-
devTools, err := CaptureDevTools()
214-
if err != nil {
215-
if callback != nil {
216-
callback(ScanStep{Name: "Dev Tools", Index: 7, Total: 8, Status: "error", Count: 0})
217-
}
218-
} else {
219-
if callback != nil {
220-
callback(ScanStep{Name: "Dev Tools", Index: 7, Total: 8, Status: "done", Count: len(devTools)})
221-
}
222-
}
135+
formulae := results[0].([]string)
136+
casks := results[1].([]string)
137+
taps := results[2].([]string)
138+
npmPkgs := results[3].([]string)
139+
prefs := results[4].([]MacOSPref)
140+
shellSnap := results[5].(*ShellSnapshot)
141+
gitSnap := results[6].(*GitSnapshot)
142+
devTools := results[7].([]DevTool)
223143

224144
return &Snapshot{
225145
Version: 1,
@@ -284,7 +204,7 @@ func isBrewInstalled() bool {
284204
return err == nil
285205
}
286206

287-
// CaptureFormulae returns user-intentional formulae via `brew leaves`.
207+
// CaptureFormulae returns user-installed formulae (via `brew leaves`, excludes dependencies).
288208
func CaptureFormulae() ([]string, error) {
289209
if !isBrewInstalled() {
290210
return []string{}, nil
@@ -299,7 +219,6 @@ func CaptureFormulae() ([]string, error) {
299219
return parseLines(string(output)), nil
300220
}
301221

302-
// CaptureCasks returns installed casks via `brew list --cask`.
303222
func CaptureCasks() ([]string, error) {
304223
if !isBrewInstalled() {
305224
return []string{}, nil
@@ -314,7 +233,6 @@ func CaptureCasks() ([]string, error) {
314233
return parseLines(string(output)), nil
315234
}
316235

317-
// CaptureTaps returns active Homebrew taps.
318236
func CaptureTaps() ([]string, error) {
319237
if !isBrewInstalled() {
320238
return []string{}, nil
@@ -329,7 +247,6 @@ func CaptureTaps() ([]string, error) {
329247
return parseLines(string(output)), nil
330248
}
331249

332-
// CaptureMacOSPrefs reads the current values of whitelisted macOS preferences.
333250
func CaptureMacOSPrefs() ([]MacOSPref, error) {
334251
prefs := []MacOSPref{}
335252

@@ -351,7 +268,6 @@ func CaptureMacOSPrefs() ([]MacOSPref, error) {
351268
return prefs, nil
352269
}
353270

354-
// CaptureShell detects the default shell, Oh-My-Zsh, plugins, and theme.
355271
func CaptureShell() (*ShellSnapshot, error) {
356272
snap := &ShellSnapshot{
357273
Default: os.Getenv("SHELL"),
@@ -393,7 +309,6 @@ func CaptureShell() (*ShellSnapshot, error) {
393309
return snap, nil
394310
}
395311

396-
// CaptureGit reads global git user.name and user.email.
397312
func CaptureGit() (*GitSnapshot, error) {
398313
snap := &GitSnapshot{}
399314

@@ -408,7 +323,7 @@ func CaptureGit() (*GitSnapshot, error) {
408323
return snap, nil
409324
}
410325

411-
// RestoreGit writes global git user.name and user.email from a snapshot, skipping values already configured.
326+
// RestoreGit sets git user.name/email if not already configured.
412327
func RestoreGit(git GitSnapshot) error {
413328
existingName, existingEmail := system.GetExistingGitConfig()
414329

@@ -444,7 +359,6 @@ var devToolCommands = []struct {
444359
{"docker", []string{"--version"}},
445360
}
446361

447-
// CaptureDevTools detects installed development tools and their versions.
448362
func CaptureDevTools() ([]DevTool, error) {
449363
tools := []DevTool{}
450364

internal/snapshot/local.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"path/filepath"
88
)
99

10-
// LocalPath returns the path to the local snapshot file (~/.openboot/snapshot.json).
1110
func LocalPath() string {
1211
home, err := os.UserHomeDir()
1312
if err != nil {
@@ -16,8 +15,6 @@ func LocalPath() string {
1615
return filepath.Join(home, ".openboot", "snapshot.json")
1716
}
1817

19-
// SaveLocal persists the snapshot to ~/.openboot/snapshot.json.
20-
// Returns the path where the snapshot was saved.
2118
func SaveLocal(snap *Snapshot) (string, error) {
2219
path := LocalPath()
2320

@@ -38,12 +35,10 @@ func SaveLocal(snap *Snapshot) (string, error) {
3835
return path, nil
3936
}
4037

41-
// LoadLocal reads and unmarshals the snapshot from ~/.openboot/snapshot.json.
4238
func LoadLocal() (*Snapshot, error) {
4339
return LoadFile(LocalPath())
4440
}
4541

46-
// LoadFile reads and unmarshals a snapshot from the given file path.
4742
func LoadFile(path string) (*Snapshot, error) {
4843
data, err := os.ReadFile(path)
4944
if err != nil {

0 commit comments

Comments
 (0)