From 4fb5f6c1725bf9c11d71a00a7f8b1b0e1040adde Mon Sep 17 00:00:00 2001 From: cloudhead Date: Fri, 1 Sep 2023 12:03:31 +0200 Subject: [PATCH] cli: Simplify fatal error output It didn't make sense to get eg. `Patch failed` when listing patches failed. We change all fatal errors to simply "Error:", giving more control over the individual commands. --- radicle-cli/examples/rad-clone-unknown.md | 2 +- radicle-cli/examples/rad-id-rebase.md | 2 +- radicle-cli/examples/rad-init-no-git.md | 2 +- radicle-cli/examples/rad-init-private.md | 2 +- radicle-cli/examples/rad-inspect-noauth.md | 3 +- radicle-cli/examples/rad-rm.md | 2 +- radicle-cli/examples/rad-sync-without-node.md | 6 +-- radicle-cli/examples/rad-sync.md | 4 +- radicle-cli/src/main.rs | 47 ++----------------- radicle-cli/src/terminal.rs | 25 ++++------ 10 files changed, 24 insertions(+), 71 deletions(-) diff --git a/radicle-cli/examples/rad-clone-unknown.md b/radicle-cli/examples/rad-clone-unknown.md index 01e2a2b3..91d1194f 100644 --- a/radicle-cli/examples/rad-clone-unknown.md +++ b/radicle-cli/examples/rad-clone-unknown.md @@ -3,5 +3,5 @@ Trying to clone a repository that is not in our routing table returns an error: ``` (fail) $ rad clone rad:zVNuptPuk5XauitpCWSNVCXGGfXW --scope trusted ✓ Tracking relationship established for rad:zVNuptPuk5XauitpCWSNVCXGGfXW with scope 'trusted' -✗ Clone failed: no seeds found for rad:zVNuptPuk5XauitpCWSNVCXGGfXW +✗ Error: no seeds found for rad:zVNuptPuk5XauitpCWSNVCXGGfXW ``` diff --git a/radicle-cli/examples/rad-id-rebase.md b/radicle-cli/examples/rad-id-rebase.md index c640e707..3681d213 100644 --- a/radicle-cli/examples/rad-id-rebase.md +++ b/radicle-cli/examples/rad-id-rebase.md @@ -242,7 +242,7 @@ $ rad id commit 2bf3a85e209d10b11a65e7ed8a8085f6f18ac6bf --no-confirm ! Warning: Revision is out of date ! Warning: d96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f * Consider using 'rad id rebase' to update the proposal to the latest identity -✗ Id failed: the identity hashes do not match for revision 2bf3a85e209d10b11a65e7ed8a8085f6f18ac6bf (d96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f) +✗ Error: the identity hashes do not match for revision 2bf3a85e209d10b11a65e7ed8a8085f6f18ac6bf (d96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f) ``` So, let's fix this by running a rebase on the proposal's revision: diff --git a/radicle-cli/examples/rad-init-no-git.md b/radicle-cli/examples/rad-init-no-git.md index 03c488c8..6d68311e 100644 --- a/radicle-cli/examples/rad-init-no-git.md +++ b/radicle-cli/examples/rad-init-no-git.md @@ -3,5 +3,5 @@ it will fail: ``` (fail) $ rad init -✗ Initialization failed: a Git repository was not found at the current path +✗ Error: a Git repository was not found at the current path ``` diff --git a/radicle-cli/examples/rad-init-private.md b/radicle-cli/examples/rad-init-private.md index 0ae2fa37..8046f67e 100644 --- a/radicle-cli/examples/rad-init-private.md +++ b/radicle-cli/examples/rad-init-private.md @@ -23,7 +23,7 @@ $ rad ls ``` ~bob (fail) $ rad sync rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --fetch --seed z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --timeout 1 ✗ Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from z6MknSL…StBU8Vi.. error: connection reset -✗ Sync failed: repository fetch from 1 seed(s) failed +✗ Error: repository fetch from 1 seed(s) failed ``` She allows Bob to view the repository. And when she syncs, one node (Bob) gets diff --git a/radicle-cli/examples/rad-inspect-noauth.md b/radicle-cli/examples/rad-inspect-noauth.md index 2cde4aba..264ae821 100644 --- a/radicle-cli/examples/rad-inspect-noauth.md +++ b/radicle-cli/examples/rad-inspect-noauth.md @@ -2,9 +2,8 @@ The `rad inspect` command can be run without being authenticated with radicle: ``` (fail) $ rad self -✗ Self failed: Could not load radicle profile: no profile found at path [..] +✗ Error: Could not load radicle profile: no profile found at path [..] ✗ Hint: To setup your radicle profile, run `rad auth`. - ``` ``` diff --git a/radicle-cli/examples/rad-rm.md b/radicle-cli/examples/rad-rm.md index fc07bfd5..a6e639c1 100644 --- a/radicle-cli/examples/rad-rm.md +++ b/radicle-cli/examples/rad-rm.md @@ -29,5 +29,5 @@ Attempting to remove a repository that doesn't exist gives us an error message: ``` (fail) $ rad rm rad:z2Jk1mNqyX7AjT4K83jJW9vQoHn4f -✗ Remove failed: repository rad:z2Jk1mNqyX7AjT4K83jJW9vQoHn4f was not found +✗ Error: repository rad:z2Jk1mNqyX7AjT4K83jJW9vQoHn4f was not found ``` diff --git a/radicle-cli/examples/rad-sync-without-node.md b/radicle-cli/examples/rad-sync-without-node.md index 4fdd49d6..67285906 100644 --- a/radicle-cli/examples/rad-sync-without-node.md +++ b/radicle-cli/examples/rad-sync-without-node.md @@ -2,15 +2,15 @@ When you try to track, clone, or sync without your node running, it gives you an ``` ~alice (fail) $ rad track rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 --no-fetch -✗ Track failed: to track a repository, your node must be running. To start it, run `rad node start` +✗ Error: to track a repository, your node must be running. To start it, run `rad node start` ``` ``` ~bob (fail) $ rad clone rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 -✗ Clone failed: to clone a repository, your node must be running. To start it, run `rad node start` +✗ Error: to clone a repository, your node must be running. To start it, run `rad node start` ``` ``` ~eve (fail) $ rad sync --fetch rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 --seed z6MksmpU5b1dS7oaqF2bHXhQi1DWy2hB7Mh9CuN7y1DN6QSz -✗ Sync failed: to sync a repository, your node must be running. To start it, run `rad node start` +✗ Error: to sync a repository, your node must be running. To start it, run `rad node start` ``` diff --git a/radicle-cli/examples/rad-sync.md b/radicle-cli/examples/rad-sync.md index 1722eb98..db6d6a0f 100644 --- a/radicle-cli/examples/rad-sync.md +++ b/radicle-cli/examples/rad-sync.md @@ -23,7 +23,7 @@ $ rad sync --announce --timeout 1 ✗ Syncing with 2 node(s).. ! Seed z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk timed out.. ! Seed z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z timed out.. -✗ Sync failed: all seeds timed out +✗ Error: all seeds timed out ``` We can also use the `--fetch` option to only fetch objects: @@ -45,7 +45,7 @@ $ rad sync --fetch --announce --timeout 1 ✗ Syncing with 2 node(s).. ! Seed z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk timed out.. ! Seed z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z timed out.. -✗ Sync failed: all seeds timed out +✗ Error: all seeds timed out ``` It's also possible to use the `--seed` flag to only sync with a specific node: diff --git a/radicle-cli/src/main.rs b/radicle-cli/src/main.rs index df225c29..1908b092 100644 --- a/radicle-cli/src/main.rs +++ b/radicle-cli/src/main.rs @@ -100,7 +100,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "assign" => { term::run_command_args::( rad_assign::HELP, - "Assign", rad_assign::run, args.to_vec(), ); @@ -108,7 +107,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "auth" => { term::run_command_args::( rad_auth::HELP, - "Authentication", rad_auth::run, args.to_vec(), ); @@ -116,7 +114,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "checkout" => { term::run_command_args::( rad_checkout::HELP, - "Checkout", rad_checkout::run, args.to_vec(), ); @@ -124,7 +121,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "clone" => { term::run_command_args::( rad_clone::HELP, - "Clone", rad_clone::run, args.to_vec(), ); @@ -132,7 +128,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "cob" => { term::run_command_args::( rad_cob::HELP, - "Cob", rad_cob::run, args.to_vec(), ); @@ -140,7 +135,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "comment" => { term::run_command_args::( rad_comment::HELP, - "Comment", rad_comment::run, args.to_vec(), ); @@ -148,7 +142,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "delegate" => { term::run_command_args::( rad_delegate::HELP, - "Delegate", rad_delegate::run, args.to_vec(), ); @@ -156,7 +149,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "edit" => { term::run_command_args::( rad_edit::HELP, - "Edit", rad_edit::run, args.to_vec(), ); @@ -164,7 +156,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "fork" => { term::run_command_args::( rad_fork::HELP, - "Fork", rad_fork::run, args.to_vec(), ); @@ -172,23 +163,16 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "help" => { term::run_command_args::( rad_help::HELP, - "Help", rad_help::run, args.to_vec(), ); } "id" => { - term::run_command_args::( - rad_id::HELP, - "Id", - rad_id::run, - args.to_vec(), - ); + term::run_command_args::(rad_id::HELP, rad_id::run, args.to_vec()); } "init" => { term::run_command_args::( rad_init::HELP, - "Initialization", rad_init::run, args.to_vec(), ); @@ -196,7 +180,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "inspect" => { term::run_command_args::( rad_inspect::HELP, - "Inspect", rad_inspect::run, args.to_vec(), ); @@ -204,23 +187,16 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "issue" => { term::run_command_args::( rad_issue::HELP, - "Issue", rad_issue::run, args.to_vec(), ); } "ls" => { - term::run_command_args::( - rad_ls::HELP, - "List", - rad_ls::run, - args.to_vec(), - ); + term::run_command_args::(rad_ls::HELP, rad_ls::run, args.to_vec()); } "node" => { term::run_command_args::( rad_node::HELP, - "Node", rad_node::run, args.to_vec(), ); @@ -228,7 +204,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "patch" => { term::run_command_args::( rad_patch::HELP, - "Patch", rad_patch::run, args.to_vec(), ); @@ -236,7 +211,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "path" => { term::run_command_args::( rad_path::HELP, - "Path", rad_path::run, args.to_vec(), ); @@ -244,23 +218,16 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "review" => { term::run_command_args::( rad_review::HELP, - "Review", rad_review::run, args.to_vec(), ); } "rm" => { - term::run_command_args::( - rad_rm::HELP, - "Remove", - rad_rm::run, - args.to_vec(), - ); + term::run_command_args::(rad_rm::HELP, rad_rm::run, args.to_vec()); } "self" => { term::run_command_args::( rad_self::HELP, - "Self", rad_self::run, args.to_vec(), ); @@ -268,7 +235,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "sync" => { term::run_command_args::( rad_sync::HELP, - "Sync", rad_sync::run, args.to_vec(), ); @@ -276,7 +242,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "label" => { term::run_command_args::( rad_label::HELP, - "Label", rad_label::run, args.to_vec(), ); @@ -284,7 +249,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "track" => { term::run_command_args::( rad_track::HELP, - "Track", rad_track::run, args.to_vec(), ); @@ -292,7 +256,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "unassign" => { term::run_command_args::( rad_unassign::HELP, - "Unassign", rad_unassign::run, args.to_vec(), ); @@ -300,7 +263,6 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "unlabel" => { term::run_command_args::( rad_unlabel::HELP, - "Unlabel", rad_unlabel::run, args.to_vec(), ); @@ -308,20 +270,17 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option> "untrack" => { term::run_command_args::( rad_untrack::HELP, - "Untrack", rad_untrack::run, args.to_vec(), ); } "web" => term::run_command_args::( rad_web::HELP, - "Web", rad_web::run, args.to_vec(), ), "remote" => term::run_command_args::( rad_remote::HELP, - "Remote", rad_remote::run, args.to_vec(), ), diff --git a/radicle-cli/src/terminal.rs b/radicle-cli/src/terminal.rs index 83f04a0c..7aae5b72 100644 --- a/radicle-cli/src/terminal.rs +++ b/radicle-cli/src/terminal.rs @@ -50,17 +50,17 @@ where } } -pub fn run_command(help: Help, action: &str, cmd: C) -> ! +pub fn run_command(help: Help, cmd: C) -> ! where A: Args, C: Command anyhow::Result>, { let args = std::env::args_os().skip(1).collect(); - run_command_args(help, action, cmd, args) + run_command_args(help, cmd, args) } -pub fn run_command_args(help: Help, action: &str, cmd: C, args: Vec) -> ! +pub fn run_command_args(help: Help, cmd: C, args: Vec) -> ! where A: Args, C: Command anyhow::Result>, @@ -107,7 +107,7 @@ where match cmd.run(options, self::profile) { Ok(()) => process::exit(0), Err(err) => { - terminal::fail(&format!("{action} failed"), &err); + terminal::fail(help.name, &err); process::exit(1); } } @@ -127,26 +127,21 @@ pub fn profile() -> Result { pub fn perror(name: &str, err: impl std::fmt::Display) { eprintln!( - "{} {} rad {}: {err}", - Paint::red(ERROR_PREFIX), + "{ERROR_PREFIX} {} rad {}: {err}", Paint::red("Error:"), name, ); } -pub fn fail(header: &str, error: &anyhow::Error) { +pub fn fail(_name: &str, error: &anyhow::Error) { let err = error.to_string(); let err = err.trim_end(); - let separator = if err.contains('\n') { ":\n" } else { ": " }; - println!( - "{ERROR_PREFIX} {}{}{error}", - Paint::red(header).bold(), - Paint::red(separator), - ); + for line in err.lines() { + println!("{ERROR_PREFIX} {} {line}", Paint::red("Error:")); + } if let Some(Error::WithHint { hint, .. }) = error.downcast_ref::() { - println!("{} {}", ERROR_HINT_PREFIX, Paint::yellow(hint)); - blank(); + println!("{ERROR_HINT_PREFIX} {}", Paint::yellow(hint)); } }