annotate rust/rhg/src/ui.rs @ 50215:ae61851e6fe2 stable

dirstate: add a way to test races happening during status We add the `devel.sync.status.pre-dirstate-write-file` config option to easily test what happens when other operations happen during the window where `hg status` is done working but has not updated the cache on disk yet. We introduce the framework for testing such races too, actual tests will be added in the next changesets. For now the test is only checking dirstate-v1. We will extend the test coverage later too. Check test documentation for details. Code change from Rapha?l Gom?s <rgomes@octobus.net> Test change from Pierre-Yves David <pierre-yves.david@octobus.net>
author Rapha?l Gom?s <rgomes@octobus.net>, Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 28 Feb 2023 15:25:47 +0100
parents 467d9df98c68
children 364e78389653
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
1 use crate::color::ColorConfig;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
2 use crate::color::Effect;
45984
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
3 use format_bytes::format_bytes;
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
4 use format_bytes::write_bytes;
48730
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
5 use hg::config::Config;
49513
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
6 use hg::config::PlainInfo;
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
7 use hg::errors::HgError;
45528
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
8 use std::borrow::Cow;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
9 use std::io;
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
10 use std::io::{ErrorKind, Write};
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
11
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
12 pub struct Ui {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
13 stdout: std::io::Stdout,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
14 stderr: std::io::Stderr,
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
15 colors: Option<ColorConfig>,
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
16 }
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
17
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
18 /// The kind of user interface error
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
19 pub enum UiError {
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
20 /// The standard output stream cannot be written to
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
21 StdoutError(io::Error),
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
22 /// The standard error stream cannot be written to
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
23 StderrError(io::Error),
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
24 }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
25
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
26 /// The commandline user interface
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
27 impl Ui {
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
28 pub fn new(config: &Config) -> Result<Self, HgError> {
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
29 Ok(Ui {
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
30 // If using something else, also adapt `isatty()` below.
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
31 stdout: std::io::stdout(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
32
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
33 stderr: std::io::stderr(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
34 colors: ColorConfig::new(config)?,
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
35 })
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
36 }
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
37
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
38 /// Default to no color if color configuration errors.
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
39 ///
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
40 /// Useful when we’re already handling another error.
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
41 pub fn new_infallible(config: &Config) -> Self {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
42 Ui {
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
43 // If using something else, also adapt `isatty()` below.
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
44 stdout: std::io::stdout(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
45
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
46 stderr: std::io::stderr(),
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
47 colors: ColorConfig::new(config).unwrap_or(None),
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
48 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
49 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
50
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
51 /// Returns a buffered handle on stdout for faster batch printing
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
52 /// operations.
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
53 pub fn stdout_buffer(&self) -> StdoutBuffer<std::io::StdoutLock> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
54 StdoutBuffer::new(self.stdout.lock())
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
55 }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
56
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
57 /// Write bytes to stdout
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
58 pub fn write_stdout(&self, bytes: &[u8]) -> Result<(), UiError> {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
59 let mut stdout = self.stdout.lock();
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
60
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
61 stdout.write_all(bytes).or_else(handle_stdout_error)?;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
62
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
63 stdout.flush().or_else(handle_stdout_error)
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
64 }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
65
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
66 /// Write bytes to stderr
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
67 pub fn write_stderr(&self, bytes: &[u8]) -> Result<(), UiError> {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
68 let mut stderr = self.stderr.lock();
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
69
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
70 stderr.write_all(bytes).or_else(handle_stderr_error)?;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
71
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
72 stderr.flush().or_else(handle_stderr_error)
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
73 }
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
74
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
75 /// Write bytes to stdout with the given label
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
76 ///
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
77 /// Like the optional `label` parameter in `mercurial/ui.py`,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
78 /// this label influences the color used for this output.
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
79 pub fn write_stdout_labelled(
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
80 &self,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
81 bytes: &[u8],
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
82 label: &str,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
83 ) -> Result<(), UiError> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
84 if let Some(colors) = &self.colors {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
85 if let Some(effects) = colors.styles.get(label.as_bytes()) {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
86 if !effects.is_empty() {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
87 return self
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
88 .write_stdout_with_effects(bytes, effects)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
89 .or_else(handle_stdout_error);
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
90 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
91 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
92 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
93 self.write_stdout(bytes)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
94 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
95
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
96 fn write_stdout_with_effects(
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
97 &self,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
98 bytes: &[u8],
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
99 effects: &[Effect],
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
100 ) -> io::Result<()> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
101 let stdout = &mut self.stdout.lock();
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
102 let mut write_line = |line: &[u8], first: bool| {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
103 // `line` does not include the newline delimiter
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
104 if !first {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
105 stdout.write_all(b"\n")?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
106 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
107 if line.is_empty() {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
108 return Ok(());
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
109 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
110 /// 0x1B == 27 == 0o33
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
111 const ASCII_ESCAPE: &[u8] = b"\x1b";
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
112 write_bytes!(stdout, b"{}[0", ASCII_ESCAPE)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
113 for effect in effects {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
114 write_bytes!(stdout, b";{}", effect)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
115 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
116 write_bytes!(stdout, b"m")?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
117 stdout.write_all(line)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
118 write_bytes!(stdout, b"{}[0m", ASCII_ESCAPE)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
119 };
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
120 let mut lines = bytes.split(|&byte| byte == b'\n');
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
121 if let Some(first) = lines.next() {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
122 write_line(first, true)?;
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
123 for line in lines {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
124 write_line(line, false)?
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
125 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
126 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
127 stdout.flush()
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
128 }
48729
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
129 }
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
130
49513
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
131 // TODO: pass the PlainInfo to call sites directly and
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
132 // delete this function
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
133 pub fn plain(opt_feature: Option<&str>) -> bool {
49513
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
134 let plain_info = PlainInfo::from_env();
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
135 match opt_feature {
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
136 None => plain_info.is_plain(),
467d9df98c68 rhg: centralize PlainInfo
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49512
diff changeset
137 Some(feature) => plain_info.is_feature_plain(feature),
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
138 }
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
139 }
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
140
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
141 /// A buffered stdout writer for faster batch printing operations.
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
142 pub struct StdoutBuffer<W: Write> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
143 buf: io::BufWriter<W>,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
144 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
145
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
146 impl<W: Write> StdoutBuffer<W> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
147 pub fn new(writer: W) -> Self {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
148 let buf = io::BufWriter::new(writer);
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
149 Self { buf }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
150 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
151
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
152 /// Write bytes to stdout buffer
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
153 pub fn write_all(&mut self, bytes: &[u8]) -> Result<(), UiError> {
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
154 self.buf.write_all(bytes).or_else(handle_stdout_error)
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
155 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
156
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
157 /// Flush bytes to stdout
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
158 pub fn flush(&mut self) -> Result<(), UiError> {
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
159 self.buf.flush().or_else(handle_stdout_error)
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
160 }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
161 }
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
162
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
163 /// Sometimes writing to stdout is not possible, try writing to stderr to
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
164 /// signal that failure, otherwise just bail.
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
165 fn handle_stdout_error(error: io::Error) -> Result<(), UiError> {
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
166 if let ErrorKind::BrokenPipe = error.kind() {
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
167 // This makes `| head` work for example
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
168 return Ok(());
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
169 }
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
170 let mut stderr = io::stderr();
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
171
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
172 stderr
45984
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
173 .write_all(&format_bytes!(
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
174 b"abort: {}\n",
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
175 error.to_string().as_bytes()
fada33872b5b rhg: use `format_bytes!` for error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45528
diff changeset
176 ))
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
177 .map_err(UiError::StderrError)?;
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
178
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
179 stderr.flush().map_err(UiError::StderrError)?;
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
180
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
181 Err(UiError::StdoutError(error))
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
182 }
45367
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
183
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
184 /// Sometimes writing to stderr is not possible.
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
185 fn handle_stderr_error(error: io::Error) -> Result<(), UiError> {
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
186 // A broken pipe should not result in a error
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
187 // like with `| head` for example
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
188 if let ErrorKind::BrokenPipe = error.kind() {
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
189 return Ok(());
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
190 }
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
191 Err(UiError::StdoutError(error))
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
192 }
45528
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
193
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
194 /// Encode rust strings according to the user system.
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
195 pub fn utf8_to_local(s: &str) -> Cow<[u8]> {
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
196 // TODO encode for the user's system //
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
197 let bytes = s.as_bytes();
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
198 Cow::Borrowed(bytes)
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
199 }
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
200
48770
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
201 /// Decode user system bytes to Rust string.
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
202 pub fn local_to_utf8(s: &[u8]) -> Cow<str> {
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
203 // TODO decode from the user's system
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
204 String::from_utf8_lossy(s)
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
205 }
f19be290756a rhg: signal when falling back in logs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48734
diff changeset
206
48733
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
207 /// Should formatted output be used?
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
208 ///
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
209 /// Note: rhg does not have the formatter mechanism yet,
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
210 /// but this is also used when deciding whether to use color.
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
211 pub fn formatted(config: &Config) -> Result<bool, HgError> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
212 if let Some(formatted) = config.get_option(b"ui", b"formatted")? {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
213 Ok(formatted)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
214 } else {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
215 isatty(config)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
216 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
217 }
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
218
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
219 fn isatty(config: &Config) -> Result<bool, HgError> {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
220 Ok(if config.get_bool(b"ui", b"nontty")? {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
221 false
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
222 } else {
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
223 atty::is(atty::Stream::Stdout)
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
224 })
39c447e03dbc rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents: 48731
diff changeset
225 }