3 use crate::CliInvocation; |
3 use crate::CliInvocation; |
4 use format_bytes::format_bytes; |
4 use format_bytes::format_bytes; |
5 use hg::errors::HgError; |
5 use hg::errors::HgError; |
6 use hg::repo::Repo; |
6 use hg::repo::Repo; |
7 use hg::utils::{files::get_bytes_from_os_str, shell_quote}; |
7 use hg::utils::{files::get_bytes_from_os_str, shell_quote}; |
|
8 use std::ffi::OsString; |
8 |
9 |
9 const ONE_MEBIBYTE: u64 = 1 << 20; |
10 const ONE_MEBIBYTE: u64 = 1 << 20; |
10 |
11 |
11 // TODO: somehow keep defaults in sync with `configitem` in `hgext/blackbox.py` |
12 // TODO: somehow keep defaults in sync with `configitem` in `hgext/blackbox.py` |
12 const DEFAULT_MAX_SIZE: u64 = ONE_MEBIBYTE; |
13 const DEFAULT_MAX_SIZE: u64 = ONE_MEBIBYTE; |
81 process_start_time, |
82 process_start_time, |
82 configured, |
83 configured, |
83 }) |
84 }) |
84 } |
85 } |
85 |
86 |
86 pub fn log_command_start(&self) { |
87 pub fn log_command_start<'arg>( |
|
88 &self, |
|
89 argv: impl Iterator<Item = &'arg OsString>, |
|
90 ) { |
87 if let Some(configured) = &self.configured { |
91 if let Some(configured) = &self.configured { |
88 let message = format_bytes!(b"(rust) {}", format_cli_args()); |
92 let message = format_bytes!(b"(rust) {}", format_cli_args(argv)); |
89 configured.log(&self.process_start_time.calendar_based, &message); |
93 configured.log(&self.process_start_time.calendar_based, &message); |
90 } |
94 } |
91 } |
95 } |
92 |
96 |
93 pub fn log_command_end(&self, exit_code: i32) { |
97 pub fn log_command_end<'arg>( |
|
98 &self, |
|
99 argv: impl Iterator<Item = &'arg OsString>, |
|
100 exit_code: i32, |
|
101 ) { |
94 if let Some(configured) = &self.configured { |
102 if let Some(configured) = &self.configured { |
95 let now = chrono::Local::now(); |
103 let now = chrono::Local::now(); |
96 let duration = self |
104 let duration = self |
97 .process_start_time |
105 .process_start_time |
98 .monotonic_clock |
106 .monotonic_clock |
99 .elapsed() |
107 .elapsed() |
100 .as_secs_f64(); |
108 .as_secs_f64(); |
101 let message = format_bytes!( |
109 let message = format_bytes!( |
102 b"(rust) {} exited {} after {} seconds", |
110 b"(rust) {} exited {} after {} seconds", |
103 format_cli_args(), |
111 format_cli_args(argv), |
104 exit_code, |
112 exit_code, |
105 format_bytes::Utf8(format_args!("{:.03}", duration)) |
113 format_bytes::Utf8(format_args!("{:.03}", duration)) |
106 ); |
114 ); |
107 configured.log(&now, &message); |
115 configured.log(&now, &message); |
108 } |
116 } |
145 } |
153 } |
146 } |
154 } |
147 } |
155 } |
148 } |
156 } |
149 |
157 |
150 fn format_cli_args() -> Vec<u8> { |
158 fn format_cli_args<'a>( |
151 let mut args = std::env::args_os(); |
159 mut args: impl Iterator<Item = &'a OsString>, |
|
160 ) -> Vec<u8> { |
152 let _ = args.next(); // Skip the first (or zeroth) arg, the name of the `rhg` executable |
161 let _ = args.next(); // Skip the first (or zeroth) arg, the name of the `rhg` executable |
153 let mut args = args.map(|arg| shell_quote(&get_bytes_from_os_str(arg))); |
162 let mut args = args.map(|arg| shell_quote(&get_bytes_from_os_str(arg))); |
154 let mut formatted = Vec::new(); |
163 let mut formatted = Vec::new(); |
155 if let Some(arg) = args.next() { |
164 if let Some(arg) = args.next() { |
156 formatted.extend(arg) |
165 formatted.extend(arg) |