##// END OF EJS Templates
rhg: refactor to pass argv down, instead of caling args_os()...
Arseniy Alekseyev -
r49961:137a9312 default
parent child Browse files
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(&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
@@ -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() -> 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();
@@ -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(exit_code(
129 blackbox.log_command_end(
129 &result,
130 argv.iter(),
130 // TODO: show a warning or combine with original error if
131 exit_code(
131 // `get_bool` returns an error
132 &result,
132 config
133 // TODO: show a warning or combine with original error if
133 .get_bool(b"ui", b"detailed-exit-code")
134 // `get_bool` returns an error
134 .unwrap_or(false),
135 config
135 ));
136 .get_bool(b"ui", b"detailed-exit-code")
137 .unwrap_or(false),
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(std::env::args_os());
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 = std::env::args_os();
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