From 32687e64fe61da693cf4e3d72fa586317aba4b22 Mon Sep 17 00:00:00 2001 From: Stephen Checkoway Date: Wed, 6 Dec 2023 11:31:39 -0500 Subject: [PATCH] Color test output and shorten chapter paths Currently, the output from `rustdoc --test` is not colored because `rustdoc`'s stdout is not a tty. The output of a failed `rustdoc` run is sent to `mdbook`'s stderr via the `error!()` macro. This commit checks if stderr is a tty using the standard `.is_terminal()` and if so, passes `--color always` to `rustdoc`. The test output from `rustdoc` includes the full path that `rustdoc` was called with. This obscures the path of the file with the error. E.g., ``` ---- /var/folders/9v/90bm7kb10fx3_bprxltb3t1r0000gn/T/mdbook-tnGJxp/lab0/index.md - Lab_0__Getting_Started (line 3) stdout ---- error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `code` --> /var/folders/9v/90bm7kb10fx3_bprxltb3t1r0000gn/T/mdbook-tnGJxp/lab0/index.md:4:6 | 3 | this code has a bug | ^^^^ expected one of 8 possible tokens error: aborting due to previous error ``` This commit runs `rustdoc` in the temp directory and replaces any relative library paths with absolute library paths. This leads to simpler error messages. The one above becomes ``` ---- lab0/index.md - Lab_0__Getting_Started (line 3) stdout ---- error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `code` --> lab0/index.md:4:6 | 3 | this code has a bug | ^^^^ expected one of 8 possible tokens error: aborting due to previous error ``` (with colors, of course). --- src/book/mod.rs | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/book/mod.rs b/src/book/mod.rs index a5e3e78c6d..0bbf944811 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -15,8 +15,9 @@ pub use self::init::BookBuilder; pub use self::summary::{parse_summary, Link, SectionNumber, Summary, SummaryItem}; use log::{debug, error, info, log_enabled, trace, warn}; -use std::io::Write; -use std::path::PathBuf; +use std::ffi::OsString; +use std::io::{IsTerminal, Write}; +use std::path::{Path, PathBuf}; use std::process::Command; use std::string::ToString; use tempfile::Builder as TempFileBuilder; @@ -259,10 +260,18 @@ impl MDBook { /// Run `rustdoc` tests on a specific chapter of the book, linking against the provided libraries. /// If `chapter` is `None`, all tests will be run. pub fn test_chapter(&mut self, library_paths: Vec<&str>, chapter: Option<&str>) -> Result<()> { - let library_args: Vec<&str> = (0..library_paths.len()) - .map(|_| "-L") - .zip(library_paths.into_iter()) - .flat_map(|x| vec![x.0, x.1]) + let cwd = std::env::current_dir()?; + let library_args: Vec = library_paths + .into_iter() + .flat_map(|path| { + let path = Path::new(path); + let path = if path.is_relative() { + cwd.join(path).into_os_string() + } else { + path.to_path_buf().into_os_string() + }; + [OsString::from("-L"), path] + }) .collect(); let temp_dir = TempFileBuilder::new().prefix("mdbook-").tempdir()?; @@ -289,6 +298,7 @@ impl MDBook { .collect(); let (book, _) = self.preprocess_book(&TestRenderer)?; + let color_output = std::io::stderr().is_terminal(); let mut failed = false; for item in book.iter() { if let BookItem::Chapter(ref ch) = *item { @@ -314,7 +324,10 @@ impl MDBook { tmpf.write_all(ch.content.as_bytes())?; let mut cmd = Command::new("rustdoc"); - cmd.arg(&path).arg("--test").args(&library_args); + cmd.current_dir(temp_dir.path()) + .arg(&chapter_path) + .arg("--test") + .args(&library_args); if let Some(edition) = self.config.rust.edition { match edition { @@ -330,6 +343,10 @@ impl MDBook { } } + if color_output { + cmd.args(&["--color", "always"]); + } + debug!("running {:?}", cmd); let output = cmd.output()?;