comparison rust/rhg/src/commands/status.rs @ 50427:98fc949bec14

rhg: support `status --print0` This seems very easy to support, and useful because it makes it possible to parse the [hg status] output even if the user creates files with '\n' characters by accident.
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Thu, 06 Apr 2023 11:41:51 +0100
parents a6b8b1ab9116
children f57f5ab0e220
comparison
equal deleted inserted replaced
50426:f0d2b18f0274 50427:98fc949bec14
109 .short('C') 109 .short('C')
110 .action(clap::ArgAction::SetTrue) 110 .action(clap::ArgAction::SetTrue)
111 .long("copies"), 111 .long("copies"),
112 ) 112 )
113 .arg( 113 .arg(
114 Arg::new("print0")
115 .help("end filenames with NUL, for use with xargs")
116 .short('0')
117 .action(clap::ArgAction::SetTrue)
118 .long("print0"),
119 )
120 .arg(
114 Arg::new("no-status") 121 Arg::new("no-status")
115 .help("hide status prefix") 122 .help("hide status prefix")
116 .short('n') 123 .short('n')
117 .action(clap::ArgAction::SetTrue) 124 .action(clap::ArgAction::SetTrue)
118 .long("no-status"), 125 .long("no-status"),
211 218
212 let ui = invocation.ui; 219 let ui = invocation.ui;
213 let config = invocation.config; 220 let config = invocation.config;
214 let args = invocation.subcommand_args; 221 let args = invocation.subcommand_args;
215 222
216 // TODO add `!args.get_flag("print0") &&` when we support `print0` 223 let print0 = args.get_flag("print0");
217 let verbose = args.get_flag("verbose") 224 let verbose = args.get_flag("verbose")
218 || config.get_bool(b"ui", b"verbose")? 225 || config.get_bool(b"ui", b"verbose")?
219 || config.get_bool(b"commands", b"status.verbose")?; 226 || config.get_bool(b"commands", b"status.verbose")?;
227 let verbose = verbose && !print0;
220 228
221 let all = args.get_flag("all"); 229 let all = args.get_flag("all");
222 let display_states = if all { 230 let display_states = if all {
223 // TODO when implementing `--quiet`: it excludes clean files 231 // TODO when implementing `--quiet`: it excludes clean files
224 // from `--all` 232 // from `--all`
361 relativize: if relative_paths { 369 relativize: if relative_paths {
362 Some(RelativizePaths::new(repo)?) 370 Some(RelativizePaths::new(repo)?)
363 } else { 371 } else {
364 None 372 None
365 }, 373 },
374 print0,
366 }; 375 };
367 if display_states.modified { 376 if display_states.modified {
368 output.display(b"M ", "status.modified", ds_status.modified)?; 377 output.display(b"M ", "status.modified", ds_status.modified)?;
369 } 378 }
370 if display_states.added { 379 if display_states.added {
525 534
526 struct DisplayStatusPaths<'a> { 535 struct DisplayStatusPaths<'a> {
527 ui: &'a Ui, 536 ui: &'a Ui,
528 no_status: bool, 537 no_status: bool,
529 relativize: Option<RelativizePaths>, 538 relativize: Option<RelativizePaths>,
539 print0: bool,
530 } 540 }
531 541
532 impl DisplayStatusPaths<'_> { 542 impl DisplayStatusPaths<'_> {
533 // Probably more elegant to use a Deref or Borrow trait rather than 543 // Probably more elegant to use a Deref or Borrow trait rather than
534 // harcode HgPathBuf, but probably not really useful at this point 544 // harcode HgPathBuf, but probably not really useful at this point
553 // in order to stream to stdout instead of allocating an 563 // in order to stream to stdout instead of allocating an
554 // itermediate `Vec<u8>`. 564 // itermediate `Vec<u8>`.
555 if !self.no_status { 565 if !self.no_status {
556 self.ui.write_stdout_labelled(status_prefix, label)? 566 self.ui.write_stdout_labelled(status_prefix, label)?
557 } 567 }
558 self.ui 568 let linebreak = if self.print0 { b"\x00" } else { b"\n" };
559 .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?; 569 self.ui.write_stdout_labelled(
570 &format_bytes!(b"{}{}", path, linebreak),
571 label,
572 )?;
560 if let Some(source) = copy_source { 573 if let Some(source) = copy_source {
561 let label = "status.copied"; 574 let label = "status.copied";
562 self.ui.write_stdout_labelled( 575 self.ui.write_stdout_labelled(
563 &format_bytes!(b" {}\n", source.as_bytes()), 576 &format_bytes!(b" {}{}", source.as_bytes(), linebreak),
564 label, 577 label,
565 )? 578 )?
566 } 579 }
567 } 580 }
568 Ok(()) 581 Ok(())