(ctx *snap.Context)
| 3425 | } |
| 3426 | |
| 3427 | func runGitDiffSize(ctx *snap.Context) error { |
| 3428 | if err := ensureGitRepository(); err != nil { |
| 3429 | return err |
| 3430 | } |
| 3431 | |
| 3432 | // Get all changed and untracked files |
| 3433 | cmd := exec.Command("git", "status", "--porcelain") |
| 3434 | output, err := cmd.Output() |
| 3435 | if err != nil { |
| 3436 | return fmt.Errorf("git status: %w", err) |
| 3437 | } |
| 3438 | |
| 3439 | lines := strings.Split(strings.TrimSpace(string(output)), "\n") |
| 3440 | if len(lines) == 0 || (len(lines) == 1 && lines[0] == "") { |
| 3441 | fmt.Fprintln(ctx.Stdout(), "No changed or untracked files") |
| 3442 | return nil |
| 3443 | } |
| 3444 | |
| 3445 | type fileSize struct { |
| 3446 | status string |
| 3447 | path string |
| 3448 | bytes int64 |
| 3449 | tokens int64 |
| 3450 | } |
| 3451 | |
| 3452 | var files []fileSize |
| 3453 | for _, line := range lines { |
| 3454 | if len(line) < 4 { |
| 3455 | continue |
| 3456 | } |
| 3457 | status := strings.TrimSpace(line[:2]) |
| 3458 | path := strings.TrimSpace(line[3:]) |
| 3459 | if path == "" { |
| 3460 | continue |
| 3461 | } |
| 3462 | |
| 3463 | // Get file size |
| 3464 | var size int64 |
| 3465 | if info, err := os.Stat(path); err == nil && !info.IsDir() { |
| 3466 | size = info.Size() |
| 3467 | } |
| 3468 | |
| 3469 | files = append(files, fileSize{ |
| 3470 | status: status, |
| 3471 | path: path, |
| 3472 | bytes: size, |
| 3473 | tokens: size / 4, // rough estimate |
| 3474 | }) |
| 3475 | } |
| 3476 | |
| 3477 | if len(files) == 0 { |
| 3478 | fmt.Fprintln(ctx.Stdout(), "No files to show") |
| 3479 | return nil |
| 3480 | } |
| 3481 | |
| 3482 | // Sort by size descending |
| 3483 | sort.Slice(files, func(i, j int) bool { |
| 3484 | return files[i].bytes > files[j].bytes |
no test coverage detected