Skip to content

Commit fee3289

Browse files
committed
feat: add scan-all command, fix layout, improve UX
- Fix dashboard layout: logo on separate line, stats before search bar - Add git-scope scan-all for full system scan with stats summary - Add path format hints in init command (~/folder, absolute, .) - Improved init feedback showing all saved settings - Show total/dirty/clean counts after system scan
1 parent 024db03 commit fee3289

2 files changed

Lines changed: 83 additions & 6 deletions

File tree

cmd/git-scope/main.go

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ Usage:
2525
Commands:
2626
(default) Launch TUI dashboard
2727
scan Scan and print repos (JSON)
28+
scan-all Full system scan from home directory (with stats)
2829
init Create config file interactively
2930
help Show this help
3031
3132
Examples:
3233
git-scope # Scan configured dirs or current dir
3334
git-scope ~/code ~/work # Scan specific directories
3435
git-scope scan . # Scan current directory (JSON)
36+
git-scope scan-all # Find ALL repos on your system
3537
git-scope init # Setup config interactively
3638
3739
Flags:
@@ -51,7 +53,7 @@ func main() {
5153
// Parse command and directories
5254
if len(args) >= 1 {
5355
switch args[0] {
54-
case "scan", "tui", "help", "init", "-h", "--help":
56+
case "scan", "tui", "help", "init", "scan-all", "-h", "--help":
5557
cmd = args[0]
5658
dirs = args[1:]
5759
default:
@@ -97,6 +99,10 @@ func main() {
9799
log.Fatalf("print error: %v", err)
98100
}
99101

102+
case "scan-all":
103+
runScanAll()
104+
return
105+
100106
case "tui", "":
101107
if err := tui.Run(cfg); err != nil {
102108
log.Fatalf("tui error: %v", err)
@@ -198,6 +204,12 @@ func runInit() {
198204

199205
// Get directories
200206
fmt.Println("Enter directories to scan for git repos (one per line, empty line to finish):")
207+
fmt.Println()
208+
fmt.Println("💡 Path hints:")
209+
fmt.Println(" • Use ~/folder for home-relative paths (e.g., ~/code)")
210+
fmt.Println(" • Use absolute paths like /Users/you/projects")
211+
fmt.Println(" • Use . for current directory")
212+
fmt.Println()
201213
fmt.Println("Examples: ~/code, ~/projects, ~/work")
202214
fmt.Println()
203215

@@ -255,3 +267,64 @@ func runInit() {
255267
fmt.Printf(" Editor: %s\n", editor)
256268
fmt.Println("\n🚀 Run 'git-scope' to launch the dashboard!")
257269
}
270+
271+
// runScanAll performs a full system scan starting from home directory
272+
func runScanAll() {
273+
home, err := os.UserHomeDir()
274+
if err != nil {
275+
log.Fatalf("Failed to get home directory: %v", err)
276+
}
277+
278+
fmt.Println("🔍 Full System Scan — Finding all git repositories...")
279+
fmt.Printf("📁 Scanning from: %s\n\n", home)
280+
fmt.Println("⏳ This may take a while depending on your disk size...")
281+
fmt.Println()
282+
283+
// Use common ignore patterns
284+
ignorePatterns := []string{
285+
"node_modules", ".next", "dist", "build", "target",
286+
".venv", "vendor", ".Trash", "Library", ".cache",
287+
".npm", ".yarn", ".cargo", ".rustup", ".go",
288+
}
289+
290+
repos, err := scan.ScanRoots([]string{home}, ignorePatterns)
291+
if err != nil {
292+
log.Fatalf("scan error: %v", err)
293+
}
294+
295+
// Calculate stats
296+
dirty := 0
297+
clean := 0
298+
for _, r := range repos {
299+
if r.Status.IsDirty {
300+
dirty++
301+
} else {
302+
clean++
303+
}
304+
}
305+
306+
// Display summary
307+
fmt.Println()
308+
fmt.Println("═══════════════════════════════════════════════════")
309+
fmt.Println(" 📊 SCAN COMPLETE")
310+
fmt.Println("═══════════════════════════════════════════════════")
311+
fmt.Printf(" 📦 Total repos found: %d\n", len(repos))
312+
fmt.Printf(" ● Dirty (needs work): %d\n", dirty)
313+
fmt.Printf(" ✓ Clean: %d\n", clean)
314+
fmt.Println("═══════════════════════════════════════════════════")
315+
fmt.Println()
316+
317+
// Show dirty repos
318+
if dirty > 0 {
319+
fmt.Println("⚠️ Dirty repos that need attention:")
320+
for _, r := range repos {
321+
if r.Status.IsDirty {
322+
fmt.Printf(" • %s (%s) - %s\n", r.Name, r.Status.Branch, r.Path)
323+
}
324+
}
325+
fmt.Println()
326+
}
327+
328+
fmt.Println("💡 To add these directories to your config, run: git-scope init")
329+
fmt.Println("💡 Or run: git-scope ~/path/to/folder to scan specific folders")
330+
}

internal/tui/view.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,23 @@ func (m Model) renderError() string {
7777
func (m Model) renderDashboard() string {
7878
var b strings.Builder
7979

80-
// Header with logo
81-
b.WriteString(compactLogo())
80+
// Header with logo on its own line
81+
logo := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#A78BFA")).Render("git-scope")
82+
version := lipgloss.NewStyle().Foreground(lipgloss.Color("#6B7280")).Render(" v0.2.1")
83+
b.WriteString(logo + version)
8284
b.WriteString("\n\n")
8385

86+
// Stats bar (always show first for consistent layout)
87+
b.WriteString(m.renderStats())
88+
b.WriteString("\n")
89+
8490
// Search bar (show when searching or has active search)
8591
if m.state == StateSearching || m.searchQuery != "" {
8692
b.WriteString(m.renderSearchBar())
8793
b.WriteString("\n")
8894
}
8995

90-
// Stats bar with filter indicator
91-
b.WriteString(m.renderStats())
92-
b.WriteString("\n\n")
96+
b.WriteString("\n")
9397

9498
// Table
9599
b.WriteString(m.table.View())

0 commit comments

Comments
 (0)