From f9273076a7058025d2b138e94aad8cd733ebb6fb Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Fri, 18 Oct 2024 12:49:00 -0600 Subject: [PATCH] Add support for `--library-path` to `rustbook test` This makes it possible to test an mdbook which has dependencies other than the direct crate for the book itself, e.g. the `trpl` crate used in _The Rust Programming Language_. --- src/tools/rustbook/src/main.rs | 39 ++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 2118af6139690..06cf5021d54b2 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -1,9 +1,9 @@ use std::env; use std::path::{Path, PathBuf}; -use clap::{ArgMatches, Command, arg, crate_version}; -use mdbook::MDBook; +use clap::{arg, crate_version, ArgMatches, Command}; use mdbook::errors::Result as Result3; +use mdbook::MDBook; use mdbook_i18n_helpers::preprocessors::Gettext; use mdbook_spec::Spec; use mdbook_trpl_listing::TrplListing; @@ -26,6 +26,20 @@ fn main() { (Defaults to the current directory when omitted)") .value_parser(clap::value_parser!(PathBuf)); + // Note: we don't parse this into a `PathBuf` because it is comma separated + // strings *and* we will ultimately pass it into `MDBook::test()`, which + // accepts `Vec<&str>`. Although it is a bit annoying that `-l/--lang` and + // `-L/--library-path` are so close, this is the same set of arguments we + // would pass when invoking mdbook on the CLI, so making them match when + // invoking rustbook makes for good consistency. + let library_path_arg = arg!( + -L --"library-path" + "A comma-separated list of directories to add to the crate search\n\ + path when building tests" + ) + .required(false) + .value_parser(parse_library_paths); + let matches = Command::new("rustbook") .about("Build a book with mdBook") .author("Steve Klabnik ") @@ -42,7 +56,8 @@ fn main() { .subcommand( Command::new("test") .about("Tests that a book's Rust code samples compile") - .arg(dir_arg), + .arg(dir_arg) + .arg(library_path_arg), ) .get_matches(); @@ -106,14 +121,22 @@ pub fn build(args: &ArgMatches) -> Result3<()> { fn test(args: &ArgMatches) -> Result3<()> { let book_dir = get_book_dir(args); + let library_paths = args + .try_get_one::>("library_path")? + .map(|v| v.iter().map(|s| s.as_str()).collect::>()) + .unwrap_or_default(); let mut book = load_book(&book_dir)?; - book.test(vec![]) + book.test(library_paths) } fn get_book_dir(args: &ArgMatches) -> PathBuf { if let Some(p) = args.get_one::("dir") { // Check if path is relative from current dir, or absolute... - if p.is_relative() { env::current_dir().unwrap().join(p) } else { p.to_path_buf() } + if p.is_relative() { + env::current_dir().unwrap().join(p) + } else { + p.to_path_buf() + } } else { env::current_dir().unwrap() } @@ -125,6 +148,10 @@ fn load_book(book_dir: &Path) -> Result3 { Ok(book) } +fn parse_library_paths(input: &str) -> Result, String> { + Ok(input.split(",").map(String::from).collect()) +} + fn handle_error(error: mdbook::errors::Error) -> ! { eprintln!("Error: {}", error); @@ -132,5 +159,5 @@ fn handle_error(error: mdbook::errors::Error) -> ! { eprintln!("\tCaused By: {}", cause); } - ::std::process::exit(101); + std::process::exit(101); }