Skip to content

feat(cli): add streaming list output and man Doc.AddStringFlag helper - #3805

Open
alkalescent wants to merge 3 commits into
mainfrom
feat/cli-streaming-list-and-doc-flag-helper
Open

feat(cli): add streaming list output and man Doc.AddStringFlag helper#3805
alkalescent wants to merge 3 commits into
mainfrom
feat/cli-streaming-list-and-doc-flag-helper

Conversation

@alkalescent

@alkalescent alkalescent commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Two small, reusable additions to otdfctl, both prompted by CLI work that registers many flags and lists potentially large result sets:

  • Cli.StreamList (pkg/cli/stream.go) — renders a list incrementally. In JSON mode it writes a JSON array, marshaling one item at a time so the full result set is never buffered (memory-bounded, suitable for very large lists). In styled mode it writes a text/tabwriter-aligned table; that path buffers rows to align columns, so JSON mode is the memory-bounded path. Takes an iter.Seq[any] so callers can feed a paged iterator without materializing it.
  • man.Doc.AddStringFlag (pkg/man/docflags.go) — registers a string flag on a command from its doc definition in one call, replacing the repeated cmd.Flags().StringP(doc.GetDocFlag("x").Name, …Shorthand, …Default, …Description) boilerplate seen across cmd/.

Test plan

  • go test ./pkg/man/... ./pkg/cli/... -race passes (new unit tests cover JSON/styled streaming, empty input, HTML-escape parity, and the flag helper including its panic-on-unknown path).
  • golangci-lint run ./pkg/man/... ./pkg/cli/... clean.

Summary by CodeRabbit

  • New Features

    • Added list output in JSON and tabular formats for command-line results.
    • JSON output preserves item order and special characters, including empty results.
    • Tables support optional headers, aligned rows, and styled borders.
    • Added support for registering documented string command-line flags.
  • Bug Fixes

    • Improved handling of iterator, encoding, and output errors during list rendering.
  • Tests

    • Added comprehensive coverage for streaming output, table formatting, special characters, failures, and flag registration.

@alkalescent
alkalescent requested a review from a team as a code owner July 30, 2026 17:47
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 316013e0-f808-4b4b-bcff-2bd8a321b653

📥 Commits

Reviewing files that changed from the base of the PR and between 3737fda and 6625de5.

📒 Files selected for processing (1)
  • otdfctl/pkg/cli/stream_test.go

📝 Walkthrough

Walkthrough

Adds Cli.StreamList for incremental JSON output and buffered styled-table output. Adds Doc.AddStringFlag for Cobra flag registration from documented metadata. Tests cover formatting, encoding, iterator errors, writer errors, and flag validation.

Changes

Streaming CLI output

Layer / File(s) Summary
Streamed list rendering
otdfctl/pkg/cli/stream.go
StreamList selects JSON or table output. JSON output is encoded incrementally. Table output buffers rows before rendering.
Streamed output tests
otdfctl/pkg/cli/stream_test.go
Tests output ordering, empty input, HTML-safe JSON strings, marshal errors, writer errors, table headers, and headerless tables.

Documented flag registration

Layer / File(s) Summary
Cobra string-flag registration
otdfctl/pkg/man/docflags.go
AddStringFlag registers a Cobra string flag from documented metadata.
Flag registration tests
otdfctl/pkg/man/docflags_test.go
Tests flag metadata registration and panic behavior for unknown names.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Iterator as iter.Seq2
  participant CLI as Cli.StreamList
  participant Writer as io.Writer
  Iterator->>CLI: yield item or error
  CLI->>Writer: write JSON item or table output
  Writer-->>CLI: return write result
  CLI-->>Iterator: stop on iterator error
Loading

Suggested reviewers: c-r33d

Poem

A rabbit sends rows in a steady bright stream,
JSON and tables follow the scheme.
Flags gain their names and defaults with care,
Tests check each error along the way there.

Hop, test, and merge with a well-ordered dream!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies both reusable helpers added by the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli-streaming-list-and-doc-flag-helper

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 208.823575ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 117.076102ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 410.478061ms
Throughput 243.62 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 55.292833402s
Average Latency 550.577027ms
Throughput 90.43 requests/second

Add Cli.StreamList for rendering large lists incrementally: a memory-bounded
JSON array in JSON mode, and a tabwriter-aligned table in styled mode. Items are
supplied as an iter.Seq2[any, error] so a failed page fetch aborts the stream and
propagates to the caller rather than looking like normal exhaustion. Add
man.Doc.AddStringFlag to register a string flag from its doc definition in one
call, reducing per-flag boilerplate in commands with many flags.
@alkalescent
alkalescent force-pushed the feat/cli-streaming-list-and-doc-flag-helper branch from 5b54b1c to 57d0ba7 Compare July 30, 2026 17:58
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 124.174675ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 71.232368ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 273.91657ms
Throughput 365.07 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 34.167144705s
Average Latency 340.66713ms
Throughput 146.34 requests/second

Replace the tabwriter styled path in StreamList with a lipgloss/table
render so styled output matches the rounded, indigo-bordered look of
NewTable. The tabwriter path already buffered all rows until Flush, so
buffering rows for a one-shot styled render costs the same memory while
restoring borders and cell styling; the JSON branch stays streamed and
memory-bounded. lipgloss/table needs no bubbletea and stays
terminal-width-agnostic.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@otdfctl/pkg/cli/stream.go`:
- Around line 52-66: Update the separator values in the stream item writing loop
to use "\n" for the first item and ",\n" for subsequent items, avoiding
duplicate indentation from marshalStreamItem. Add an exact-output assertion to
TestStreamListJSON covering the corrected formatting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c01a3747-8e37-4d0b-8271-f1df24da58a0

📥 Commits

Reviewing files that changed from the base of the PR and between 5b54b1c and 3737fda.

📒 Files selected for processing (4)
  • otdfctl/pkg/cli/stream.go
  • otdfctl/pkg/cli/stream_test.go
  • otdfctl/pkg/man/docflags.go
  • otdfctl/pkg/man/docflags_test.go

Comment thread otdfctl/pkg/cli/stream.go
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 210.637745ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 108.62036ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 407.078777ms
Throughput 245.65 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 49.256369378s
Average Latency 490.586213ms
Throughput 101.51 requests/second

Add an exact-output assertion to TestStreamListJSON so the array
indentation is guarded against regression. SetIndent does not prefix an
object's opening brace, so the item separators supply the two-space
indent that aligns each object with printJSON; the golden string locks
that layout in.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 218.918192ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 107.906432ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 449.885694ms
Throughput 222.28 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 50.109747017s
Average Latency 499.10119ms
Throughput 99.78 requests/second

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • otdfctl
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant