diff --git a/examples/custom-backend/main.rs b/examples/custom-backend/main.rs index 4d8c042d0..dac126c3a 100644 --- a/examples/custom-backend/main.rs +++ b/examples/custom-backend/main.rs @@ -17,7 +17,7 @@ use std::path::Path; use clap::{FromArgMatches, Subcommand}; use git2::Repository; -use jujutsu::cli_util::{create_ui, parse_args, report_command_error, CommandError}; +use jujutsu::cli_util::{create_ui, handle_command_result, parse_args, CommandError}; use jujutsu::commands::{default_app, run_command}; use jujutsu::ui::Ui; use jujutsu_lib::backend::{ @@ -61,11 +61,9 @@ fn run(ui: &mut Ui) -> Result<(), CommandError> { } fn main() { - let mut ui = create_ui(); - let exit_code = match run(&mut ui) { - Ok(()) => 0, - Err(err) => report_command_error(&mut ui, err), - }; + let (mut ui, result) = create_ui(); + let result = result.and_then(|()| run(&mut ui)); + let exit_code = handle_command_result(&mut ui, result); std::process::exit(exit_code); } diff --git a/examples/custom-command/main.rs b/examples/custom-command/main.rs index 400c8a5f9..06a56080b 100644 --- a/examples/custom-command/main.rs +++ b/examples/custom-command/main.rs @@ -14,7 +14,7 @@ use clap::{FromArgMatches, Subcommand}; use jujutsu::cli_util::{ - create_ui, parse_args, report_command_error, short_commit_description, CommandError, + create_ui, handle_command_result, parse_args, short_commit_description, CommandError, }; use jujutsu::commands::{default_app, run_command}; use jujutsu::ui::Ui; @@ -59,10 +59,8 @@ fn run(ui: &mut Ui) -> Result<(), CommandError> { } fn main() { - let mut ui = create_ui(); - let exit_code = match run(&mut ui) { - Ok(()) => 0, - Err(err) => report_command_error(&mut ui, err), - }; + let (mut ui, result) = create_ui(); + let result = result.and_then(|()| run(&mut ui)); + let exit_code = handle_command_result(&mut ui, result); std::process::exit(exit_code); } diff --git a/src/cli_util.rs b/src/cli_util.rs index 38f46d333..c0b8eea55 100644 --- a/src/cli_util.rs +++ b/src/cli_util.rs @@ -49,6 +49,7 @@ use crate::ui::{ColorChoice, FilePathParseError, Ui}; pub enum CommandError { UserError(String), + ConfigError(String), /// Invalid command line CliError(String), BrokenPipe, @@ -68,7 +69,7 @@ impl From for CommandError { impl From for CommandError { fn from(err: config::ConfigError) -> Self { - CommandError::UserError(format!("Config error: {err}")) + CommandError::ConfigError(err.to_string()) } } @@ -1135,16 +1136,14 @@ pub struct GlobalArgs { pub color: Option, } -pub fn create_ui() -> Ui<'static> { +pub fn create_ui() -> (Ui<'static>, Result<(), CommandError>) { // TODO: We need to do some argument parsing here, at least for things like - // --config, and for reading user configs from the repo pointed to by - // -R. + // --config, and for reading user configs from the repo pointed to by -R. match read_config() { - Ok(user_settings) => Ui::for_terminal(user_settings), + Ok(user_settings) => (Ui::for_terminal(user_settings), Ok(())), Err(err) => { - let mut ui = Ui::for_terminal(UserSettings::default()); - ui.write_error(&format!("Config error: {}\n", err)).unwrap(); - std::process::exit(1); + let ui = Ui::for_terminal(UserSettings::default()); + (ui, Err(CommandError::ConfigError(err.to_string()))) } } } @@ -1264,18 +1263,24 @@ pub fn parse_args<'help>( // TODO: Return std::process::ExitCode instead, once our MSRV is >= 1.61 #[must_use] -pub fn report_command_error(ui: &mut Ui, err: CommandError) -> i32 { - match err { - CommandError::UserError(message) => { +pub fn handle_command_result(ui: &mut Ui, result: Result<(), CommandError>) -> i32 { + match result { + Ok(()) => 0, + Err(CommandError::UserError(message)) => { ui.write_error(&format!("Error: {}\n", message)).unwrap(); 1 } - CommandError::CliError(message) => { + Err(CommandError::ConfigError(message)) => { + ui.write_error(&format!("Config error: {}\n", message)) + .unwrap(); + 1 + } + Err(CommandError::CliError(message)) => { ui.write_error(&format!("Error: {}\n", message)).unwrap(); 2 } - CommandError::BrokenPipe => std::process::exit(3), - CommandError::InternalError(message) => { + Err(CommandError::BrokenPipe) => std::process::exit(3), + Err(CommandError::InternalError(message)) => { ui.write_error(&format!("Internal error: {}\n", message)) .unwrap(); 255 diff --git a/src/main.rs b/src/main.rs index 7e553e800..19b84d04b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use jujutsu::cli_util::{create_ui, parse_args, report_command_error, CommandError}; +use jujutsu::cli_util::{create_ui, handle_command_result, parse_args, CommandError}; use jujutsu::commands::{default_app, run_command}; use jujutsu::ui::Ui; @@ -23,10 +23,8 @@ fn run(ui: &mut Ui) -> Result<(), CommandError> { } fn main() { - let mut ui = create_ui(); - let exit_code = match run(&mut ui) { - Ok(()) => 0, - Err(err) => report_command_error(&mut ui, err), - }; + let (mut ui, result) = create_ui(); + let result = result.and_then(|()| run(&mut ui)); + let exit_code = handle_command_result(&mut ui, result); std::process::exit(exit_code); }