Skip to content

feat(printer): redesign output as stacked completion lines + colorized summary table#29

Merged
takecy merged 4 commits intomasterfrom
feat/table-output
May 5, 2026
Merged

feat(printer): redesign output as stacked completion lines + colorized summary table#29
takecy merged 4 commits intomasterfrom
feat/table-output

Conversation

@takecy
Copy link
Copy Markdown
Owner

@takecy takecy commented May 5, 2026

Issue

なし(運用フィードバックから派生した出力フォーマットの再設計)

Overview

gih <git-cmd> の出力をリポジトリごとに 4〜5 行出すスタイルから、Homebrew 風の「完了 1 行積み上げ + 末尾のテーブルサマリ」に再設計しました。29 リポジトリ規模での実行時のスクロール量を大幅に削減し、結果の俯瞰と失敗の視覚的識別を改善します。

3 つのコミットで段階的に実装:

1. テーブル化 (19b8c59)

リポジトリごとに path / message / Success: / Done: N/M の 4〜5 行を出していた既存形式を、Homebrew 風の ✓ <repo> <message> <duration> 1 行 + 末尾の整形テーブルサマリに刷新しました。

  • printer パッケージに Outcome / Status / Summary 型と新メソッド (PrintHeader / PrintRepoLine / PrintSummaryTable / PrintFailureDetails) を追加
  • 標準ライブラリ (text/tabwriter 不使用) で +----+ | の罫線テーブルを描画する renderTable を実装
  • syncer 側で goroutine ごとに実行時間を計測し Outcome を構築する形に変更
  • Result / Print / Error / PrintCmd / PrintMsgErr / PrintRepoErr は削除

2. 冗長な失敗詳細出力の排除 (cfc6753)

テーブル直後に stderr へ出ていた ==> Failed: <絶対パス> + full git stderr + Err.Error() のブロックは、Message 列に既に出ているエラー 1 行目と重複しスクロールを増やすだけだったため完全に廃止しました。

  • PrintFailureDetails メソッドを削除
  • 消費先がなくなった Outcome.Stderr / Printer.errWriter フィールドも削除
  • NewPrinter(writer io.Writer) に第 2 引数を削除しシグネチャ簡略化

3. 失敗・タイムアウト行の着色 (db33597)

サマリテーブルで失敗行を赤、タイムアウト行を黄色に着色し、視覚的な識別性を向上させました。

  • rowColorFor(Status) を追加(StatusFailed → 赤、StatusTimeout → 黄、StatusSuccess → nil)
  • renderTablerowColors []func(string) string 引数を追加
  • 着色は幅計算・padding 後に行全体に適用するため、ANSI エスケープがテーブル整列を壊さない

期待される出力

==> Running pull origin master on 29 repositories
✗ takecy/adk-test                fatal: couldn't find remote ref master   2.3s
✓ takecy/git-here                Already up to date.                      2.3s
... (29 行)
==> Summary
+----------------------------------+--------+----------+----------------------------------------+
| Repository                       | Status | Duration | Message                                |
+----------------------------------+--------+----------+----------------------------------------+
| takecy/adk-test                  | ✗      | 2.3s     | fatal: couldn't find remote ref master |  ← 赤色
| takecy/git-here                  | ✓      | 2.3s     | Already up to date.                    |
... (29 行、失敗行は赤・タイムアウト行は黄)
+----------------------------------+--------+----------+----------------------------------------+
Total: 29  Success: 10  Failed: 19  Timeout: 0  Elapsed: 7.0s

動作確認

  • make build / make test (-race) / make lint 全 pass
  • 実機 29 リポジトリで pull origin master を実行し、19 失敗ケースで出力が完了行 + テーブルのみで完結することを確認
  • script -q 経由で pty 強制実行し、失敗行に \x1b[31m、タイムアウト行に \x1b[33m の ANSI エスケープが適用されアラインメントが保たれることを確認
  • exit code は summary.HasFailures() 経由で 0 / 2 を返す挙動を維持

🤖 Generated with Claude Code

takecy and others added 3 commits May 5, 2026 12:53
…n lines and summary table

リポジトリごとに 4〜5 行を出力していた既存形式を、Homebrew 風のシンプルな
完了 1 行積み上げ + 末尾の整形テーブルサマリへ刷新。リポジトリ数が増えても
スクロール量を抑え、全実行結果を俯瞰しやすくする。

変更内容:
- printer: Outcome/Status 型と PrintHeader / PrintRepoLine /
  PrintSummaryTable / PrintFailureDetails を追加。`text/tabwriter` を
  使わず標準ライブラリだけで罫線テーブルを描画する renderTable ヘルパ
  を実装。旧 Result / Print / Error / PrintCmd / PrintMsgErr /
  PrintRepoErr は削除。
- syncer: runStats に outcomes []printer.Outcome を追加し、execute 内で
  各 goroutine が実行時間・stderr・status を Outcome に詰めて
  PrintRepoLine を 1 回呼ぶ形へ変更。displayName / firstLine ヘルパを
  追加し、execCmd / printSummary は廃止。
- stdout/stderr 分離: 完了行とテーブルは stdout、失敗・タイムアウトの
  full git stderr と Err.Error() のみ stderr に出すことで、`2>/dev/null`
  でクリーンなダッシュボードが取り出せる。
- tests: PrintRepoLine / PrintSummaryTable / PrintFailureDetails /
  PrintHeader 用テスト、displayName のケース別テスト、failure 時に
  Outcome.Stderr に full stderr が保存されるリグレッションテストを
  追加。共有 mutex 検証は PrintRepoLine + PrintFailureDetails 組み合わ
  せに更新。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…table

テーブル化された Summary 行の Message 列に既に git のエラー1行目
(`fatal: ...` 等) が出ているため、その後 stderr に絶対パス + full git
stderr + Err.Error() を再掲する PrintFailureDetails の出力は重複・
冗長で、リポジトリ数が多いほどスクロール量を増やすだけのノイズとなって
いた。完全に廃止し、結果はテーブル + 完了行積み上げのみで完結させる。

変更内容:
- printer: PrintFailureDetails メソッド本体を削除。Outcome.Stderr /
  Printer.errWriter フィールドの消費先がなくなるためまとめて削除し、
  NewPrinter のシグネチャを `NewPrinter(writer io.Writer)` に簡略化。
- syncer: Run() からの PrintFailureDetails 呼び出しを 1 行削除。
  execute() 内 `o.Stderr = errMsg` 代入 (timeout / failed の 2 箇所)
  を削除。
- gih: ローカル変数 errWriter を削除し NewGitter には os.Stderr を直接
  渡す。NewPrinter は writer 単一引数で呼ぶ。
- tests: TestPrinter_PrintFailureDetails_HasFullStderr と
  TestPrinter_SharedMutex_AcrossWriterAndErrWriter を削除。
  TestPrinter_MixedPrints_ConcurrentSafe の case 4 削除し switch を
  4 ケースに。NewPrinter を呼んでいる全テスト (printer 側 +
  syncer/syncer_test.go の newSyncWithFake) を新シグネチャに追従。
  TestSync_Execute の `failure preserves full stderr in Outcome.Stderr`
  サブテストも削除。

Exit code は summary.HasFailures() で 2 を返す挙動を維持。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mary table

サマリテーブルで失敗/タイムアウト行を視覚的に識別しやすくするため、
fatih/color による行全体の着色を導入する。

実装:
- rowColorFor(Status) を追加。StatusFailed → 赤、StatusTimeout → 黄、
  StatusSuccess → nil (色付けなし) を返す。
- renderTable に rowColors []func(string) string 引数を追加。各行を
  buildRow で組み立てた後、対応する rowColors[i] が non-nil なら
  そのデコレータを適用してから writeLine。
- 色付けは padding/幅計算の後に適用するため ANSI エスケープが
  utf8.RuneCountInString に混入せず、テーブル整列は崩れない。
- 行全体(罫線 `|` 含む)に色を適用する方式を採用。失敗・タイムアウト
  行が一目で識別でき、成功行は通常色のまま。

テスト:
- TestRowColorFor を追加。Success → nil / Failed/Timeout → non-nil で
  原文字列が保持されることを検証。ANSI バイト列に依存しないため、
  fatih/color の TTY 検出 (NoColor) のグローバル状態に左右されない。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR redesigns gih's user-facing output flow: repository execution now streams as one completion line per repo, then ends with a compact summary table. The change fits the codebase by moving more presentation logic into printer while syncer now builds structured per-repo outcomes.

Changes:

  • Replaced the old multi-line per-repo printer API with Outcome/Summary-based rendering, including a bordered summary table.
  • Changed syncer to collect per-repo execution metadata (status, duration, message) and print the new header/summary flow.
  • Simplified printer construction to a single output writer and updated tests around the new output model.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
syncer/syncer.go Refactors execution to build printer.Outcome values, print one-line repo results, and emit the final summary table.
syncer/syncer_test.go Updates syncer tests for outcome collection and adds coverage for displayName.
printer/print.go Replaces template-based printing with structured line/table rendering, status coloring, and duration/message formatting helpers.
printer/print_test.go Rewrites printer tests around the new API and concurrent rendering behavior.
gih/main.go Adapts CLI wiring to the simplified printer constructor while keeping stderr for git execution errors.

Comment thread syncer/syncer.go
Comment thread printer/print.go Outdated
Comment thread syncer/syncer.go Outdated
Comment thread printer/print.go
…isplayName

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@takecy takecy marked this pull request as ready for review May 5, 2026 05:02
@takecy takecy merged commit 2206096 into master May 5, 2026
2 checks passed
@takecy takecy deleted the feat/table-output branch May 5, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants