Show More
@@ -5,6 +5,7 b' 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 | |||
@@ -83,14 +84,21 b" impl<'a> Blackbox<'a> {" | |||||
83 | }) |
|
84 | }) | |
84 | } |
|
85 | } | |
85 |
|
86 | |||
86 |
pub fn log_command_start( |
|
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( |
|
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 | |
@@ -100,7 +108,7 b" impl<'a> Blackbox<'a> {" | |||||
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 | ); | |
@@ -147,8 +155,9 b" impl ConfiguredBlackbox<'_> {" | |||||
147 | } |
|
155 | } | |
148 | } |
|
156 | } | |
149 |
|
157 | |||
150 |
fn format_cli_args( |
|
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(); |
@@ -25,6 +25,7 b' pub mod utils {' | |||||
25 | } |
|
25 | } | |
26 |
|
26 | |||
27 | fn main_with_result( |
|
27 | fn main_with_result( | |
|
28 | argv: Vec<OsString>, | |||
28 | process_start_time: &blackbox::ProcessStartTime, |
|
29 | process_start_time: &blackbox::ProcessStartTime, | |
29 | ui: &ui::Ui, |
|
30 | ui: &ui::Ui, | |
30 | repo: Result<&Repo, &NoRepoInCwdError>, |
|
31 | repo: Result<&Repo, &NoRepoInCwdError>, | |
@@ -78,7 +79,7 b' fn main_with_result(' | |||||
78 | .version("0.0.1"); |
|
79 | .version("0.0.1"); | |
79 | let app = add_subcommand_args(app); |
|
80 | let app = add_subcommand_args(app); | |
80 |
|
81 | |||
81 | let matches = app.clone().get_matches_safe()?; |
|
82 | let matches = app.clone().get_matches_from_safe(argv.iter())?; | |
82 |
|
83 | |||
83 | let (subcommand_name, subcommand_matches) = matches.subcommand(); |
|
84 | let (subcommand_name, subcommand_matches) = matches.subcommand(); | |
84 |
|
85 | |||
@@ -123,23 +124,26 b' fn main_with_result(' | |||||
123 | if config.is_extension_enabled(b"blackbox") { |
|
124 | if config.is_extension_enabled(b"blackbox") { | |
124 | let blackbox = |
|
125 | let blackbox = | |
125 | blackbox::Blackbox::new(&invocation, process_start_time)?; |
|
126 | blackbox::Blackbox::new(&invocation, process_start_time)?; | |
126 | blackbox.log_command_start(); |
|
127 | blackbox.log_command_start(argv.iter()); | |
127 | let result = run(&invocation); |
|
128 | let result = run(&invocation); | |
128 |
blackbox.log_command_end( |
|
129 | blackbox.log_command_end( | |
|
130 | argv.iter(), | |||
|
131 | exit_code( | |||
129 | &result, |
|
132 | &result, | |
130 | // TODO: show a warning or combine with original error if |
|
133 | // TODO: show a warning or combine with original error if | |
131 | // `get_bool` returns an error |
|
134 | // `get_bool` returns an error | |
132 | config |
|
135 | config | |
133 | .get_bool(b"ui", b"detailed-exit-code") |
|
136 | .get_bool(b"ui", b"detailed-exit-code") | |
134 | .unwrap_or(false), |
|
137 | .unwrap_or(false), | |
135 |
) |
|
138 | ), | |
|
139 | ); | |||
136 | result |
|
140 | result | |
137 | } else { |
|
141 | } else { | |
138 | run(&invocation) |
|
142 | run(&invocation) | |
139 | } |
|
143 | } | |
140 | } |
|
144 | } | |
141 |
|
145 | |||
142 | fn main() { |
|
146 | fn rhg_main(argv: Vec<OsString>) -> ! { | |
143 | // Run this first, before we find out if the blackbox extension is even |
|
147 | // Run this first, before we find out if the blackbox extension is even | |
144 | // enabled, in order to include everything in-between in the duration |
|
148 | // enabled, in order to include everything in-between in the duration | |
145 | // measurements. Reading config files can be slow if theyβre on NFS. |
|
149 | // measurements. Reading config files can be slow if theyβre on NFS. | |
@@ -147,7 +151,7 b' fn main() {' | |||||
147 |
|
151 | |||
148 | env_logger::init(); |
|
152 | env_logger::init(); | |
149 |
|
153 | |||
150 |
let early_args = EarlyArgs::parse( |
|
154 | let early_args = EarlyArgs::parse(&argv); | |
151 |
|
155 | |||
152 | let initial_current_dir = early_args.cwd.map(|cwd| { |
|
156 | let initial_current_dir = early_args.cwd.map(|cwd| { | |
153 | let cwd = get_path_from_bytes(&cwd); |
|
157 | let cwd = get_path_from_bytes(&cwd); | |
@@ -158,6 +162,7 b' fn main() {' | |||||
158 | }) |
|
162 | }) | |
159 | .unwrap_or_else(|error| { |
|
163 | .unwrap_or_else(|error| { | |
160 | exit( |
|
164 | exit( | |
|
165 | &argv, | |||
161 | &None, |
|
166 | &None, | |
162 | &Ui::new_infallible(&Config::empty()), |
|
167 | &Ui::new_infallible(&Config::empty()), | |
163 | OnUnsupported::Abort, |
|
168 | OnUnsupported::Abort, | |
@@ -179,6 +184,7 b' fn main() {' | |||||
179 | let on_unsupported = OnUnsupported::Abort; |
|
184 | let on_unsupported = OnUnsupported::Abort; | |
180 |
|
185 | |||
181 | exit( |
|
186 | exit( | |
|
187 | &argv, | |||
182 | &initial_current_dir, |
|
188 | &initial_current_dir, | |
183 | &Ui::new_infallible(&Config::empty()), |
|
189 | &Ui::new_infallible(&Config::empty()), | |
184 | on_unsupported, |
|
190 | on_unsupported, | |
@@ -191,6 +197,7 b' fn main() {' | |||||
191 | .load_cli_args(early_args.config, early_args.color) |
|
197 | .load_cli_args(early_args.config, early_args.color) | |
192 | .unwrap_or_else(|error| { |
|
198 | .unwrap_or_else(|error| { | |
193 | exit( |
|
199 | exit( | |
|
200 | &argv, | |||
194 | &initial_current_dir, |
|
201 | &initial_current_dir, | |
195 | &Ui::new_infallible(&non_repo_config), |
|
202 | &Ui::new_infallible(&non_repo_config), | |
196 | OnUnsupported::from_config(&non_repo_config), |
|
203 | OnUnsupported::from_config(&non_repo_config), | |
@@ -209,6 +216,7 b' fn main() {' | |||||
209 | } |
|
216 | } | |
210 | if SCHEME_RE.is_match(&repo_path_bytes) { |
|
217 | if SCHEME_RE.is_match(&repo_path_bytes) { | |
211 | exit( |
|
218 | exit( | |
|
219 | &argv, | |||
212 | &initial_current_dir, |
|
220 | &initial_current_dir, | |
213 | &Ui::new_infallible(&non_repo_config), |
|
221 | &Ui::new_infallible(&non_repo_config), | |
214 | OnUnsupported::from_config(&non_repo_config), |
|
222 | OnUnsupported::from_config(&non_repo_config), | |
@@ -299,6 +307,7 b' fn main() {' | |||||
299 | Err(NoRepoInCwdError { cwd: at }) |
|
307 | Err(NoRepoInCwdError { cwd: at }) | |
300 | } |
|
308 | } | |
301 | Err(error) => exit( |
|
309 | Err(error) => exit( | |
|
310 | &argv, | |||
302 | &initial_current_dir, |
|
311 | &initial_current_dir, | |
303 | &Ui::new_infallible(&non_repo_config), |
|
312 | &Ui::new_infallible(&non_repo_config), | |
304 | OnUnsupported::from_config(&non_repo_config), |
|
313 | OnUnsupported::from_config(&non_repo_config), | |
@@ -318,6 +327,7 b' fn main() {' | |||||
318 | }; |
|
327 | }; | |
319 | let ui = Ui::new(&config).unwrap_or_else(|error| { |
|
328 | let ui = Ui::new(&config).unwrap_or_else(|error| { | |
320 | exit( |
|
329 | exit( | |
|
330 | &argv, | |||
321 | &initial_current_dir, |
|
331 | &initial_current_dir, | |
322 | &Ui::new_infallible(&config), |
|
332 | &Ui::new_infallible(&config), | |
323 | OnUnsupported::from_config(&config), |
|
333 | OnUnsupported::from_config(&config), | |
@@ -330,12 +340,14 b' fn main() {' | |||||
330 | let on_unsupported = OnUnsupported::from_config(config); |
|
340 | let on_unsupported = OnUnsupported::from_config(config); | |
331 |
|
341 | |||
332 | let result = main_with_result( |
|
342 | let result = main_with_result( | |
|
343 | argv.iter().map(|s| s.to_owned()).collect(), | |||
333 | &process_start_time, |
|
344 | &process_start_time, | |
334 | &ui, |
|
345 | &ui, | |
335 | repo_result.as_ref(), |
|
346 | repo_result.as_ref(), | |
336 | config, |
|
347 | config, | |
337 | ); |
|
348 | ); | |
338 | exit( |
|
349 | exit( | |
|
350 | &argv, | |||
339 | &initial_current_dir, |
|
351 | &initial_current_dir, | |
340 | &ui, |
|
352 | &ui, | |
341 | on_unsupported, |
|
353 | on_unsupported, | |
@@ -348,6 +360,10 b' fn main() {' | |||||
348 | ) |
|
360 | ) | |
349 | } |
|
361 | } | |
350 |
|
362 | |||
|
363 | fn main() -> ! { | |||
|
364 | rhg_main(std::env::args_os().collect()) | |||
|
365 | } | |||
|
366 | ||||
351 | fn exit_code( |
|
367 | fn exit_code( | |
352 | result: &Result<(), CommandError>, |
|
368 | result: &Result<(), CommandError>, | |
353 | use_detailed_exit_code: bool, |
|
369 | use_detailed_exit_code: bool, | |
@@ -374,7 +390,8 b' fn exit_code(' | |||||
374 | } |
|
390 | } | |
375 | } |
|
391 | } | |
376 |
|
392 | |||
377 | fn exit( |
|
393 | fn exit<'a>( | |
|
394 | original_args: &'a [OsString], | |||
378 | initial_current_dir: &Option<PathBuf>, |
|
395 | initial_current_dir: &Option<PathBuf>, | |
379 | ui: &Ui, |
|
396 | ui: &Ui, | |
380 | mut on_unsupported: OnUnsupported, |
|
397 | mut on_unsupported: OnUnsupported, | |
@@ -386,7 +403,7 b' fn exit(' | |||||
386 | Err(CommandError::UnsupportedFeature { message }), |
|
403 | Err(CommandError::UnsupportedFeature { message }), | |
387 | ) = (&on_unsupported, &result) |
|
404 | ) = (&on_unsupported, &result) | |
388 | { |
|
405 | { | |
389 |
let mut args = |
|
406 | let mut args = original_args.iter(); | |
390 | let executable = match executable { |
|
407 | let executable = match executable { | |
391 | None => { |
|
408 | None => { | |
392 | exit_no_fallback( |
|
409 | exit_no_fallback( | |
@@ -546,7 +563,7 b' struct EarlyArgs {' | |||||
546 | } |
|
563 | } | |
547 |
|
564 | |||
548 | impl EarlyArgs { |
|
565 | impl EarlyArgs { | |
549 | fn parse(args: impl IntoIterator<Item = OsString>) -> Self { |
|
566 | fn parse<'a>(args: impl IntoIterator<Item = &'a OsString>) -> Self { | |
550 | let mut args = args.into_iter().map(get_bytes_from_os_str); |
|
567 | let mut args = args.into_iter().map(get_bytes_from_os_str); | |
551 | let mut config = Vec::new(); |
|
568 | let mut config = Vec::new(); | |
552 | let mut color = None; |
|
569 | let mut color = None; |
General Comments 0
You need to be logged in to leave comments.
Login now