Add global --output flag with table, json, and csv support#291
Conversation
Replaces the per-subcommand --json flag scattered across 14 variants with a single global -o/--output flag on the root command. CSV output uses the csv crate for RFC-4180-compliant formatting.
Add a `supports_csv()` opt-in method to the `Formatter` trait (default false). Flat formatters (Screens, Assets, Playlists, PlaylistItems, EdgeApps, EdgeAppInstances) override it to true. Commands that return nested data (EdgeAppSettings) stay false. `handle_command_execution_result` checks this before processing and exits with a clear error message.
Users on the old --json per-subcommand flag now get a deprecation warning and JSON output instead of a clap error, easing migration to --output json.
Code ReviewOverviewReplaces 14 per-subcommand Strengths
Issues & SuggestionsCorrectness / consistency
Polish
Test coverageNet +191 / −154 with no new unit tests. Worth adding at least:
Security / performance
Risk SummaryLow-to-moderate. The deprecated-alias migration is well-handled. The two things to fix before merging:
Everything else is polish. Recommend addressing those two, optionally adding a couple of focused tests, then ship. |
playlist get was hand-rolling serde_json::to_string_pretty and ignoring --output entirely. Add Formatter impl for PlaylistFile (table, json, csv) and route the handler through handle_command_execution_result so all three output formats work consistently with the rest of the get/list commands.
warn! routes through env_logger, so RUST_LOG=off (which the README recommends for clean CSV/JSON pipes) silently swallows the warning. Users migrating from --json won't see it in exactly the scenario where they're most likely to hit it. Switch to eprintln! so the warning always reaches stderr regardless of log level.
The numeric fallback chain as_u64 -> as_f64 caused negative integers to fail as_u64 and fall through to as_f64, producing "-1.0" instead of "-1". Insert as_i64 between as_u64 and as_f64 to handle negative integers correctly.
OutputFormat is a fieldless three-variant enum. Adding Copy removes the need to pass &OutputFormat through every handle_cli_*_command and handle_command_execution_result, and eliminates the *output dereferences and &OutputFormat::Json temporary references in handle_cli.
Both fields are only accessed inside cli.rs (in handle_cli). main.rs only calls Cli::parse() and hands the struct to handle_cli, so pub visibility is wider than necessary. pub(crate) matches the existing visibility of the command field.
List {} and Update {} are idiomatic as unit variants (List, Update) since
they carry no data. No behavior change.
csv::Writer already terminates each record with \r\n per RFC 4180. println! appended an extra \n, producing a blank line at the end of every CSV stream. Switch to print! for CSV output only; table and JSON keep println! since they don't embed their own line terminator.
- Assets CSV round-trip: verifies header row and RFC 4180 escaping for values containing commas and embedded quotes - EdgeAppSettings::supports_csv returns false: pins the guard that triggers the CSV-not-supported rejection path - --json sets cli.json and leaves output at the Table default - --json combined with --output is rejected by clap's conflicts_with
|
|
Thanks for the quick turnaround — all major points addressed:
Two small remaining nits, both non-blocking:
LGTM otherwise. |
sergey-borovkov
left a comment
There was a problem hiding this comment.
LGTM — all major review points addressed, remaining nits are non-blocking.
Summary
--jsonflags with a single global--output <table|json|csv>flag — consistent interface across all commandsedge-app setting list) reject it with a clear error rather than producing malformed output--jsonis kept as a hidden deprecated alias with a warning to avoid breaking existing scripts during migration