Mercurial > public > mercurial-scm > hg
diff rust/rhg/src/main.rs @ 46601:755c31a1caf9
rhg: Add support for the blackbox extension
Only `command` and `commandfinish` events are logged.
The `dirty`, `logsource`, `track` and `ignore` configuration items
are not supported yet.
To indicate commands executed without Python, a `(rust) ` prefix is added
in corresponding log messages.
Differential Revision: https://phab.mercurial-scm.org/D10012
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Tue, 16 Feb 2021 13:08:37 +0100 |
parents | d2e61f00ee9d |
children | 4e4c70401028 |
line wrap: on
line diff
--- a/rust/rhg/src/main.rs Wed Feb 17 13:00:25 2021 +0100 +++ b/rust/rhg/src/main.rs Tue Feb 16 13:08:37 2021 +0100 @@ -9,6 +9,7 @@ use hg::repo::{Repo, RepoError}; use std::path::{Path, PathBuf}; +mod blackbox; mod error; mod exitcode; mod ui; @@ -36,7 +37,10 @@ ) } -fn main_with_result(ui: &ui::Ui) -> Result<(), CommandError> { +fn main_with_result( + ui: &ui::Ui, + process_start_time: &blackbox::ProcessStartTime, +) -> Result<(), CommandError> { env_logger::init(); let app = App::new("rhg") .setting(AppSettings::AllowInvalidUtf8) @@ -83,35 +87,47 @@ Err(error) => return Err(error.into()), }; - run(&CliInvocation { + let invocation = CliInvocation { ui, subcommand_args, non_repo_config, repo: repo.as_ref(), - }) + }; + let blackbox = blackbox::Blackbox::new(&invocation, process_start_time)?; + blackbox.log_command_start(); + let result = run(&invocation); + blackbox.log_command_end(exit_code(&result)); + result } fn main() { + // Run this first, before we find out if the blackbox extension is even + // enabled, in order to include everything in-between in the duration + // measurements. Reading config files can be slow if they’re on NFS. + let process_start_time = blackbox::ProcessStartTime::now(); + let ui = ui::Ui::new(); - let exit_code = match main_with_result(&ui) { + let result = main_with_result(&ui, &process_start_time); + if let Err(CommandError::Abort { message }) = &result { + if !message.is_empty() { + // Ignore errors when writing to stderr, we’re already exiting + // with failure code so there’s not much more we can do. + let _ = ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); + } + } + std::process::exit(exit_code(&result)) +} + +fn exit_code(result: &Result<(), CommandError>) -> i32 { + match result { Ok(()) => exitcode::OK, + Err(CommandError::Abort { .. }) => exitcode::ABORT, // Exit with a specific code and no error message to let a potential // wrapper script fallback to Python-based Mercurial. Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, - - Err(CommandError::Abort { message }) => { - if !message.is_empty() { - // Ignore errors when writing to stderr, we’re already exiting - // with failure code so there’s not much more we can do. - let _ = - ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); - } - exitcode::ABORT - } - }; - std::process::exit(exit_code) + } } macro_rules! subcommands {