package presenter import ( "fmt" "io" "strconv" "strings" "text/tabwriter" "gitea.oblak.solutions/dimitar/gitFlow/pkg/status" ) // TableFormatter renders repositories as an aligned terminal table followed // by a summary line. type TableFormatter struct { opts Options } // Format implements Formatter. func (t *TableFormatter) Format(w io.Writer, result status.ScanResult) error { r := newRenderer(t.opts.Color, w) tw := tabwriter.NewWriter(w, 2, 4, 2, ' ', 0) fmt.Fprintln(tw, "REPOSITORY\tBRANCH\tSTATUS\tAHEAD/BEHIND\tCHANGES\tSTASH") for _, repo := range result.Repos { branch := repo.Branch if branch == "" { branch = "-" } ab := "-" if repo.Status != status.StatusError && (repo.RemoteURL != "" || repo.AheadBy > 0 || repo.BehindBy > 0) { ab = fmt.Sprintf("%d/%d", repo.AheadBy, repo.BehindBy) } changes := "-" switch { case repo.Status == status.StatusError: changes = repo.Error case repo.FileCount() > 0: changes = summarizeChanges(repo) } stash := "-" if repo.StashCount > 0 { stash = strconv.Itoa(repo.StashCount) } fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\n", shortPath(repo.Path), branch, r.paint(repo.Status, repo.Status.String()), ab, changes, stash) } if err := tw.Flush(); err != nil { return err } s := result.Summary() label := "repos" if s.Total == 1 { label = "repo" } fmt.Fprintf(w, "\n%d %s | %s clean | %d need attention | %d errors\n", s.Total, label, r.paint(status.StatusClean, strconv.Itoa(s.Clean)), s.Attention, s.Errored) return nil } // summarizeChanges renders staged/modified/untracked counts, e.g. "2M 1U". func summarizeChanges(repo status.RepoInfo) string { parts := make([]string, 0, 3) if n := len(repo.StagedFiles); n > 0 { parts = append(parts, fmt.Sprintf("%dS", n)) } if n := len(repo.ModifiedFiles); n > 0 { parts = append(parts, fmt.Sprintf("%dM", n)) } if n := len(repo.UntrackedFiles); n > 0 { parts = append(parts, fmt.Sprintf("%dU", n)) } return strings.Join(parts, " ") }