Add --verbose logging and --extern flags to test subcommand

This commit is contained in:
Rick Weber 2022-02-23 14:04:42 -08:00
parent 5bea83114b
commit 4bcc075ad8
3 changed files with 51 additions and 5 deletions

View File

@ -245,13 +245,21 @@ impl MDBook {
} }
/// Run `rustdoc` tests on the book, linking against the provided libraries. /// Run `rustdoc` tests on the book, linking against the provided libraries.
pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> { pub fn test(&mut self, library_paths: Vec<&str>, externs: Vec<&str>, verbose: bool) -> Result<()> {
let library_args: Vec<&str> = (0..library_paths.len()) let library_args: Vec<&str> = (0..library_paths.len())
.map(|_| "-L") .map(|_| "-L")
.zip(library_paths.into_iter()) .zip(library_paths.into_iter())
.flat_map(|x| vec![x.0, x.1]) .flat_map(|x| vec![x.0, x.1])
.collect(); .collect();
let extern_args: Vec<&str> = (0..externs.len())
.map(|_| "--extern")
.zip(externs.into_iter())
.flat_map(|x| vec![x.0, x.1])
.collect();
let verbose_arg = if verbose { vec!["-v"] } else { vec![] };
let temp_dir = TempFileBuilder::new().prefix("mdbook-").tempdir()?; let temp_dir = TempFileBuilder::new().prefix("mdbook-").tempdir()?;
// FIXME: Is "test" the proper renderer name to use here? // FIXME: Is "test" the proper renderer name to use here?
@ -279,7 +287,12 @@ impl MDBook {
tmpf.write_all(ch.content.as_bytes())?; tmpf.write_all(ch.content.as_bytes())?;
let mut cmd = Command::new("rustdoc"); let mut cmd = Command::new("rustdoc");
cmd.arg(&path).arg("--test").args(&library_args); cmd
.arg(&path)
.arg("--test")
.args(&library_args)
.args(&extern_args)
.args(&verbose_arg);
if let Some(edition) = self.config.rust.edition { if let Some(edition) = self.config.rust.edition {
match edition { match edition {
@ -295,6 +308,14 @@ impl MDBook {
} }
} }
let command = cmd
.get_args()
.map(|x| x.to_string_lossy().into_owned())
.collect::<Vec<String>>()
.join(" ");
info!("Running `rustdoc {}`", command);
let output = cmd.output()?; let output = cmd.output()?;
if !output.status.success() { if !output.status.success() {

View File

@ -3,6 +3,13 @@ use clap::{arg, App, Arg, ArgMatches};
use mdbook::errors::Result; use mdbook::errors::Result;
use mdbook::MDBook; use mdbook::MDBook;
const EXTERN_HELP: &str = "Specify the name and location of an external crate. This argument
gets passed down to rustdoc. To see the set of --extern and --library-path
arguments needed to use a given crate, create a simple example project that
uses said crate and run `cargo doc -v.`
Example: --extern my_crate=/path/to/crate.rlib";
// Create clap subcommand arguments // Create clap subcommand arguments
pub fn make_subcommand<'help>() -> App<'help> { pub fn make_subcommand<'help>() -> App<'help> {
App::new("test") App::new("test")
@ -33,6 +40,20 @@ pub fn make_subcommand<'help>() -> App<'help> {
.multiple_occurrences(true) .multiple_occurrences(true)
.forbid_empty_values(true) .forbid_empty_values(true)
.help("A comma-separated list of directories to add to {n}the crate search path when building tests")) .help("A comma-separated list of directories to add to {n}the crate search path when building tests"))
.arg(Arg::with_name("extern")
.long("extern")
.value_name("file")
.takes_value(true)
.require_delimiter(false)
.multiple(true)
.empty_values(false)
.help(EXTERN_HELP))
.arg(Arg::with_name("verbose")
.long("verbose")
.short("v")
.takes_value(false)
.multiple(false)
.help("Enables verbose logging with the test command."))
} }
// test command implementation // test command implementation
@ -43,12 +64,16 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
.unwrap_or_default(); .unwrap_or_default();
let book_dir = get_book_dir(args); let book_dir = get_book_dir(args);
let mut book = MDBook::load(&book_dir)?; let mut book = MDBook::load(&book_dir)?;
let externs: Vec<&str> = args
.values_of("extern")
.map(std::iter::Iterator::collect)
.unwrap_or_default();
if let Some(dest_dir) = args.value_of("dest-dir") { if let Some(dest_dir) = args.value_of("dest-dir") {
book.config.build.build_dir = dest_dir.into(); book.config.build.build_dir = dest_dir.into();
} }
book.test(library_paths)?; book.test(library_paths, externs, args.is_present("verbose"))?;
Ok(()) Ok(())
} }

View File

@ -9,7 +9,7 @@ fn mdbook_can_correctly_test_a_passing_book() {
let temp = DummyBook::new().with_passing_test(true).build().unwrap(); let temp = DummyBook::new().with_passing_test(true).build().unwrap();
let mut md = MDBook::load(temp.path()).unwrap(); let mut md = MDBook::load(temp.path()).unwrap();
let result = md.test(vec![]); let result = md.test(vec![], vec![], false);
assert!( assert!(
result.is_ok(), result.is_ok(),
"Tests failed with {}", "Tests failed with {}",
@ -22,5 +22,5 @@ fn mdbook_detects_book_with_failing_tests() {
let temp = DummyBook::new().with_passing_test(false).build().unwrap(); let temp = DummyBook::new().with_passing_test(false).build().unwrap();
let mut md = MDBook::load(temp.path()).unwrap(); let mut md = MDBook::load(temp.path()).unwrap();
assert!(md.test(vec![]).is_err()); assert!(md.test(vec![], vec![], false).is_err());
} }