Skip to content

feat: add --json flag to list command#3

Closed
glitch418x wants to merge 5 commits intomainfrom
feat/list-json-coderabbit
Closed

feat: add --json flag to list command#3
glitch418x wants to merge 5 commits intomainfrom
feat/list-json-coderabbit

Conversation

@glitch418x
Copy link
Contributor

@glitch418x glitch418x commented Feb 18, 2026

Summary

Adds a --json flag to the list subcommand for machine-readable output.

Changes

  • Add serde + serde_json dependencies
  • Derive Serialize on TccEntry and sub-types
  • Add --json bool flag to List command — outputs a JSON array when set, existing table output unchanged

Usage

tccutil-rs list --json
tccutil-rs list --json --client Accessibility

Summary by CodeRabbit

  • New Features

    • Added a --json option to the list command to emit JSON-formatted output (full entry details) and made --compact mutually exclusive with --json.
    • Improved service-name matching so lookups accept exact, display-name, and partial inputs.
  • Tests

    • Added integration tests validating JSON output structure and client-filter behavior when using --json.
  • Documentation

    • Updated contribution guidelines to focus on Pull Requests and commit message guidance.

Adds serde/serde_json dependencies and a --json flag to the list
subcommand. When passed, entries serialize as a JSON array instead
of the human-readable table. Includes integration tests for valid
JSON output and filtered JSON output.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@glitch418x glitch418x self-assigned this Feb 18, 2026
@glitch418x glitch418x requested a review from altaywtf February 18, 2026 06:55
@coderabbitai
Copy link

coderabbitai bot commented Feb 18, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds a --json flag to the list command and runtime branch to emit JSON; derives serde::Serialize for TccEntry; expands TCC public API (new TccError variants, DbTarget variants, TccDb::new, list signature, service resolution and SERVICE_MAP); updates Cargo.toml to add serde/serde_json and adds integration tests for JSON output.

Changes

Cohort / File(s) Summary
Manifest / Dependencies
Cargo.toml
Added serde (with derive) and serde_json = "1" to [dependencies]; added serde_json = "1" to [dev-dependencies].
CLI & Runtime
src/main.rs
Extended Commands::List with json: bool; enforced --compact conflicts with --json; runtime branches to serialize entries with serde_json::to_string_pretty when --json is set; tests updated/added to exercise parsing and conflict behavior.
Data Model & Public API
src/tcc.rs
Derived Serialize for TccEntry; added comprehensive SERVICE_MAP; expanded TccError variants; changed DbTarget to include Default and User; added TccDb::new; updated list(&self, client_filter, service_filter) signature and service resolution helpers; added doc comments.
Integration Tests
tests/integration.rs
Added tests that run the binary with --json (and client filter), assert exit code 0, parse stdout as JSON array and validate entry fields and filter behavior; imported serde_json::Value.
Docs / Guidelines
.claude/rules/coding.md
Removed Conventional/Atomic Commits guidance, changed MR → PR terminology, added “Commit Messages” subsection with examples and squash-before-merge directive.

Sequence Diagram(s)

sequenceDiagram
  participant User as "User (CLI)"
  participant Main as "tccutil-rs (main)"
  participant TccDb as "TccDb"
  participant Serializer as "serde_json"

  User->>Main: invoke `--user list [--client X] [--service Y] [--json]`
  Main->>TccDb: list(client_filter, service_filter)
  TccDb-->>Main: Vec<TccEntry>
  alt --json flag set
    Main->>Serializer: to_string_pretty(Vec<TccEntry>)
    Serializer-->>Main: JSON string
    Main-->>User: print JSON
  else
    Main->>Main: print_entries(Vec<TccEntry>) (pretty text)
    Main-->>User: print human-readable output
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble flags and map each name,

I turn entries into neat JSON rain.
A hop, a serialize, a tiny cheer—
Arrays parade so outputs are clear.
Happy rabbit, bytes alight, sincere!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add --json flag to list command' directly and clearly describes the main feature added in the pull request—a JSON output flag for the list subcommand.
Docstring Coverage ✅ Passed Docstring coverage is 82.35% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/list-json-coderabbit

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
Cargo.toml (1)

19-23: Redundant dev-dependency.

serde_json is listed in both [dependencies] (Line 20) and [dev-dependencies] (Line 23). When a crate is in [dependencies], it's automatically available for tests, making the dev-dependency entry redundant.

♻️ Proposed fix
 [dev-dependencies]
-serde_json = "1"
 tempfile = "3"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Cargo.toml` around lines 19 - 23, Remove the redundant dev-dependency entry
for serde_json: since serde_json is already declared under [dependencies]
(serde_json = "1"), delete the duplicate serde_json = "1" line from the
[dev-dependencies] section so tests use the main dependency; ensure only one
declaration of serde_json remains in Cargo.toml.
src/main.rs (1)

422-431: Consider the interaction between --json and --compact flags.

When both --json and --compact are specified, --json takes precedence and --compact is silently ignored. The JSON output always includes the full client path since it serializes TccEntry directly.

This behavior is reasonable (JSON consumers can transform the data as needed), but you may want to either:

  1. Document this in the --json help text, or
  2. Make the flags mutually exclusive using clap's conflicts_with
Option: Make flags mutually exclusive
         /// Compact mode: show only binary name instead of full path
-        #[arg(short, long)]
+        #[arg(short, long, conflicts_with = "json")]
         compact: bool,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 422 - 431, The --json and --compact flags currently
interact so that --json wins and --compact is ignored; update the flag
definitions (the clap Arg for "json" or "compact" in the CLI setup) to make them
mutually exclusive by adding conflicts_with("compact") on the "json" arg (or
conflicts_with("json") on "compact") so the parser rejects using both;
alternatively, if you prefer to keep both allowed, update the help text for the
"json" flag to explicitly note that JSON output serializes TccEntry fully and
that --compact is ignored (the relevant symbols are the json and compact boolean
flags, the TccEntry serialization, and print_entries).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Cargo.toml`:
- Around line 19-23: Remove the redundant dev-dependency entry for serde_json:
since serde_json is already declared under [dependencies] (serde_json = "1"),
delete the duplicate serde_json = "1" line from the [dev-dependencies] section
so tests use the main dependency; ensure only one declaration of serde_json
remains in Cargo.toml.

In `@src/main.rs`:
- Around line 422-431: The --json and --compact flags currently interact so that
--json wins and --compact is ignored; update the flag definitions (the clap Arg
for "json" or "compact" in the CLI setup) to make them mutually exclusive by
adding conflicts_with("compact") on the "json" arg (or conflicts_with("json") on
"compact") so the parser rejects using both; alternatively, if you prefer to
keep both allowed, update the help text for the "json" flag to explicitly note
that JSON output serializes TccEntry fully and that --compact is ignored (the
relevant symbols are the json and compact boolean flags, the TccEntry
serialization, and print_entries).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/main.rs (1)

230-237: Consider adding a test for the --compact and --json conflict.

The test verifies --json parses correctly, but there's no test ensuring conflicts_with = "json" works. Consider adding a test that asserts combining both flags produces an error:

🧪 Suggested test for argument conflict
#[test]
fn parse_list_compact_and_json_conflict() {
    let err = parse(&["tcc", "list", "--compact", "--json"]).unwrap_err();
    assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 230 - 237, Add a new unit test named
parse_list_compact_and_json_conflict that calls parse(&["tcc", "list",
"--compact", "--json"]) and asserts it returns an error whose kind() is
ErrorKind::ArgumentConflict; this verifies the conflicts_with = "json" on the
List variant (see parse function and Commands::List) actually prevents using
--compact and --json together.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main.rs`:
- Around line 230-237: Add a new unit test named
parse_list_compact_and_json_conflict that calls parse(&["tcc", "list",
"--compact", "--json"]) and asserts it returns an error whose kind() is
ErrorKind::ArgumentConflict; this verifies the conflicts_with = "json" on the
List variant (see parse function and Commands::List) actually prevents using
--compact and --json together.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/main.rs (1)

428-438: Consider graceful error handling instead of .expect().

While serialization of TccEntry (containing only String, i32, bool) should never fail in practice, using .expect() will produce a panic with a stack trace if it ever does. For consistency with the error handling pattern used elsewhere in this function (lines 439-442), consider using match or unwrap_or_else to print a clean error and exit.

♻️ Optional: Graceful error handling
                 Ok(entries) => {
                     if json {
-                        println!(
-                            "{}",
-                            serde_json::to_string_pretty(&entries)
-                                .expect("failed to serialize entries")
-                        );
+                        match serde_json::to_string_pretty(&entries) {
+                            Ok(json_str) => println!("{}", json_str),
+                            Err(e) => {
+                                eprintln!("{}: failed to serialize entries: {}", "Error".red().bold(), e);
+                                process::exit(1);
+                            }
+                        }
                     } else {
                         print_entries(&entries, compact);
                     }
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 428 - 438, The current JSON branch uses
serde_json::to_string_pretty(&entries).expect(...) which panics on serialization
failure; change it to handle errors gracefully by matching the Result (or using
unwrap_or_else) from serde_json::to_string_pretty and on Err print a clean error
message (including the error) to stderr and exit with a non-zero status instead
of panicking; keep the JSON printing behavior on Ok and otherwise mirror the
existing error handling used elsewhere in this function (see usage of
print_entries, json, compact) so the program logs the serialization failure and
exits cleanly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main.rs`:
- Around line 428-438: The current JSON branch uses
serde_json::to_string_pretty(&entries).expect(...) which panics on serialization
failure; change it to handle errors gracefully by matching the Result (or using
unwrap_or_else) from serde_json::to_string_pretty and on Err print a clean error
message (including the error) to stderr and exit with a non-zero status instead
of panicking; keep the JSON printing behavior on Ok and otherwise mirror the
existing error handling used elsewhere in this function (see usage of
print_entries, json, compact) so the program logs the serialization failure and
exits cleanly.

glitch418x and others added 2 commits February 18, 2026 10:15
…ation

Match the error handling pattern used elsewhere in main(): print to
stderr with colored "Error" prefix and exit(1) instead of panicking
with a stack trace.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@glitch418x
Copy link
Contributor Author

Closing this PR to re-implement the same feature with Codex.

@glitch418x glitch418x closed this Feb 20, 2026
@glitch418x glitch418x deleted the feat/list-json-coderabbit branch February 20, 2026 18:30
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.

1 participant