[GH-ISSUE #450] Replace tabwriter with tablewriter for bordered table output #127

Closed
opened 2026-02-26 21:33:38 +03:00 by kerem · 0 comments
Owner

Originally created by @rudrankriyam on GitHub (Feb 8, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/450

Problem

All --output table rendering currently uses Go's text/tabwriter, which produces borderless, space-aligned columns:

ID           Name            Bundle ID                        SKU
6747745091   FoundationLab   com.rudrankriyam.foundationlab   FLab123

This is functional but hard to scan visually, especially for wide tables with many columns (subscriptions pricing, Game Center leaderboards, Xcode Cloud workflows, etc.).

Proposed solution

Replace text/tabwriter with github.com/olekukonenko/tablewriter to get Unicode box-bordered tables:

┌────────────┬───────────────┬───────────────────────────────┬──────────┐
│ ID         │ Name          │ Bundle ID                     │ SKU      │
├────────────┼───────────────┼───────────────────────────────┼──────────┤
│ 6747745091 │ FoundationLab │ com.rudrankriyam.foundationlab│ FLab123  │
└────────────┴───────────────┴───────────────────────────────┴──────────┘

Why tablewriter

  • Lightweight — adds ~200-300KB to the binary (vs ~5MB for go-pretty). Current binary is ~22MB, so this is negligible.
  • Zero transitive dependencies.
  • Built-in features — auto column width, alignment (left/right/center per column), word wrapping, Unicode box-drawing, header/footer separation.
  • Battle-tested — widely used across Go CLIs.

Scope

There are ~340 tabwriter.NewWriter call sites across the codebase:

  • ~330 in internal/asc/ (the output formatters)
  • ~8 in internal/cli/ (subscriptions pricing, IAP prices, migrate, shared)
  • 2 in internal/cli/shared/shared.go (help rendering — leave as-is)

The histogram in reviews_ratings.go (printHistogramRows) uses fmt.Printf with bars, not tabwriter — it should also be migrated for consistency.

Implementation plan

  1. Add a shared RenderTable(headers []string, rows [][]string) helper in internal/asc/ that wraps tablewriter with Unicode box-drawing style. This centralizes border style so it can be changed in one place.
  2. Migrate output formatters in internal/asc/ — each printXxxTable function currently builds a tabwriter, writes header + rows, and flushes. Replace with: build [][]string rows, call RenderTable. This is mechanical but touches ~60 files.
  3. Migrate CLI-level custom table printerssubscriptions/pricing.go, iap/prices.go, migrate/migrate_output.go.
  4. Update the histogram renderer in reviews_ratings.go to use the same bordered style.
  5. Keep help rendering (DefaultUsageFunc) on tabwriter — it's not data output, and bordered help text would look wrong.
  6. Tests — update any tests that assert exact table output format. Add a unit test for RenderTable itself.

Sequencing with #444

This pairs well with #444 (output registry refactor). Ideal order:

  • #444 first — modularizes dispatch so each formatter is self-contained.
  • This issue second — swaps the rendering layer underneath. With the registry in place, each formatter is isolated and can be migrated independently.

However, this can also be done standalone since the migration is mechanical (swap tabwriter calls for RenderTable calls).

Acceptance criteria

  • tablewriter added to go.mod
  • Shared RenderTable helper with Unicode box-drawing borders
  • All printXxxTable functions in internal/asc/ migrated
  • CLI-level custom table printers migrated
  • Help rendering (DefaultUsageFunc) unchanged
  • make test passes
  • make lint passes
  • Manual verification: asc apps list --output table shows bordered output
Originally created by @rudrankriyam on GitHub (Feb 8, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/450 ## Problem All `--output table` rendering currently uses Go's `text/tabwriter`, which produces borderless, space-aligned columns: ``` ID Name Bundle ID SKU 6747745091 FoundationLab com.rudrankriyam.foundationlab FLab123 ``` This is functional but hard to scan visually, especially for wide tables with many columns (subscriptions pricing, Game Center leaderboards, Xcode Cloud workflows, etc.). ## Proposed solution Replace `text/tabwriter` with [`github.com/olekukonenko/tablewriter`](https://github.com/olekukonenko/tablewriter) to get Unicode box-bordered tables: ``` ┌────────────┬───────────────┬───────────────────────────────┬──────────┐ │ ID │ Name │ Bundle ID │ SKU │ ├────────────┼───────────────┼───────────────────────────────┼──────────┤ │ 6747745091 │ FoundationLab │ com.rudrankriyam.foundationlab│ FLab123 │ └────────────┴───────────────┴───────────────────────────────┴──────────┘ ``` ### Why tablewriter - **Lightweight** — adds ~200-300KB to the binary (vs ~5MB for `go-pretty`). Current binary is ~22MB, so this is negligible. - **Zero transitive dependencies.** - **Built-in features** — auto column width, alignment (left/right/center per column), word wrapping, Unicode box-drawing, header/footer separation. - **Battle-tested** — widely used across Go CLIs. ### Scope There are **~340 `tabwriter.NewWriter` call sites** across the codebase: - ~330 in `internal/asc/` (the output formatters) - ~8 in `internal/cli/` (subscriptions pricing, IAP prices, migrate, shared) - 2 in `internal/cli/shared/shared.go` (help rendering — leave as-is) The histogram in `reviews_ratings.go` (`printHistogramRows`) uses `fmt.Printf` with `█` bars, not tabwriter — it should also be migrated for consistency. ## Implementation plan 1. **Add a shared `RenderTable(headers []string, rows [][]string)` helper** in `internal/asc/` that wraps `tablewriter` with Unicode box-drawing style. This centralizes border style so it can be changed in one place. 2. **Migrate output formatters in `internal/asc/`** — each `printXxxTable` function currently builds a `tabwriter`, writes header + rows, and flushes. Replace with: build `[][]string` rows, call `RenderTable`. This is mechanical but touches ~60 files. 3. **Migrate CLI-level custom table printers** — `subscriptions/pricing.go`, `iap/prices.go`, `migrate/migrate_output.go`. 4. **Update the histogram renderer** in `reviews_ratings.go` to use the same bordered style. 5. **Keep help rendering (`DefaultUsageFunc`) on `tabwriter`** — it's not data output, and bordered help text would look wrong. 6. **Tests** — update any tests that assert exact table output format. Add a unit test for `RenderTable` itself. ### Sequencing with #444 This pairs well with #444 (output registry refactor). Ideal order: - **#444 first** — modularizes dispatch so each formatter is self-contained. - **This issue second** — swaps the rendering layer underneath. With the registry in place, each formatter is isolated and can be migrated independently. However, this can also be done standalone since the migration is mechanical (swap `tabwriter` calls for `RenderTable` calls). ## Acceptance criteria - [ ] `tablewriter` added to `go.mod` - [ ] Shared `RenderTable` helper with Unicode box-drawing borders - [ ] All `printXxxTable` functions in `internal/asc/` migrated - [ ] CLI-level custom table printers migrated - [ ] Help rendering (`DefaultUsageFunc`) unchanged - [ ] `make test` passes - [ ] `make lint` passes - [ ] Manual verification: `asc apps list --output table` shows bordered output
kerem closed this issue 2026-02-26 21:33:38 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#127
No description provided.