|
1 | 1 | use std::collections::HashSet; |
2 | 2 | use std::fmt::{Display, Formatter}; |
| 3 | +use std::io; |
3 | 4 | use std::path::{Path, PathBuf}; |
4 | 5 | use std::sync::{Arc, Mutex}; |
5 | 6 |
|
6 | | -use termcolor::{Color, WriteColor}; |
| 7 | +use termcolor::Color; |
7 | 8 |
|
8 | 9 | #[derive(Clone, Default)] |
9 | 10 | ///CLI flags used by tidy. |
@@ -245,30 +246,63 @@ pub const COLOR_WARNING: Color = Color::Yellow; |
245 | 246 | /// Output a message to stderr. |
246 | 247 | /// The message can be optionally scoped to a certain check, and it can also have a certain color. |
247 | 248 | pub fn output_message(msg: &str, id: Option<&CheckId>, color: Option<Color>) { |
248 | | - use std::io::Write; |
| 249 | + use termcolor::{ColorChoice, ColorSpec}; |
249 | 250 |
|
250 | | - use termcolor::{ColorChoice, ColorSpec, StandardStream}; |
| 251 | + let stderr: &mut dyn termcolor::WriteColor = if cfg!(test) { |
| 252 | + &mut StderrForUnitTests |
| 253 | + } else { |
| 254 | + &mut termcolor::StandardStream::stderr(ColorChoice::Auto) |
| 255 | + }; |
251 | 256 |
|
252 | | - let mut stderr = StandardStream::stderr(ColorChoice::Auto); |
253 | 257 | if let Some(color) = &color { |
254 | 258 | stderr.set_color(ColorSpec::new().set_fg(Some(*color))).unwrap(); |
255 | 259 | } |
256 | 260 |
|
257 | 261 | match id { |
258 | 262 | Some(id) => { |
259 | | - write!(&mut stderr, "tidy [{}", id.name).unwrap(); |
| 263 | + write!(stderr, "tidy [{}", id.name).unwrap(); |
260 | 264 | if let Some(path) = &id.path { |
261 | | - write!(&mut stderr, " ({})", path.display()).unwrap(); |
| 265 | + write!(stderr, " ({})", path.display()).unwrap(); |
262 | 266 | } |
263 | | - write!(&mut stderr, "]").unwrap(); |
| 267 | + write!(stderr, "]").unwrap(); |
264 | 268 | } |
265 | 269 | None => { |
266 | | - write!(&mut stderr, "tidy").unwrap(); |
| 270 | + write!(stderr, "tidy").unwrap(); |
267 | 271 | } |
268 | 272 | } |
269 | 273 | if color.is_some() { |
270 | 274 | stderr.set_color(&ColorSpec::new()).unwrap(); |
271 | 275 | } |
272 | 276 |
|
273 | | - writeln!(&mut stderr, ": {msg}").unwrap(); |
| 277 | + writeln!(stderr, ": {msg}").unwrap(); |
| 278 | +} |
| 279 | + |
| 280 | +/// An implementation of `io::Write` and `termcolor::WriteColor` that writes |
| 281 | +/// to stderr via `eprint!`, so that the output can be properly captured when |
| 282 | +/// running tidy's unit tests. |
| 283 | +struct StderrForUnitTests; |
| 284 | + |
| 285 | +impl io::Write for StderrForUnitTests { |
| 286 | + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
| 287 | + eprint!("{}", String::from_utf8_lossy(buf)); |
| 288 | + Ok(buf.len()) |
| 289 | + } |
| 290 | + |
| 291 | + fn flush(&mut self) -> io::Result<()> { |
| 292 | + Ok(()) |
| 293 | + } |
| 294 | +} |
| 295 | + |
| 296 | +impl termcolor::WriteColor for StderrForUnitTests { |
| 297 | + fn supports_color(&self) -> bool { |
| 298 | + false |
| 299 | + } |
| 300 | + |
| 301 | + fn set_color(&mut self, _spec: &termcolor::ColorSpec) -> io::Result<()> { |
| 302 | + Ok(()) |
| 303 | + } |
| 304 | + |
| 305 | + fn reset(&mut self) -> io::Result<()> { |
| 306 | + Ok(()) |
| 307 | + } |
274 | 308 | } |
0 commit comments