Skip to content

Commit f927307

Browse files
committed
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_.
1 parent daa8e32 commit f927307

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

src/tools/rustbook/src/main.rs

+33-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::env;
22
use std::path::{Path, PathBuf};
33

4-
use clap::{ArgMatches, Command, arg, crate_version};
5-
use mdbook::MDBook;
4+
use clap::{arg, crate_version, ArgMatches, Command};
65
use mdbook::errors::Result as Result3;
6+
use mdbook::MDBook;
77
use mdbook_i18n_helpers::preprocessors::Gettext;
88
use mdbook_spec::Spec;
99
use mdbook_trpl_listing::TrplListing;
@@ -26,6 +26,20 @@ fn main() {
2626
(Defaults to the current directory when omitted)")
2727
.value_parser(clap::value_parser!(PathBuf));
2828

29+
// Note: we don't parse this into a `PathBuf` because it is comma separated
30+
// strings *and* we will ultimately pass it into `MDBook::test()`, which
31+
// accepts `Vec<&str>`. Although it is a bit annoying that `-l/--lang` and
32+
// `-L/--library-path` are so close, this is the same set of arguments we
33+
// would pass when invoking mdbook on the CLI, so making them match when
34+
// invoking rustbook makes for good consistency.
35+
let library_path_arg = arg!(
36+
-L --"library-path"
37+
"A comma-separated list of directories to add to the crate search\n\
38+
path when building tests"
39+
)
40+
.required(false)
41+
.value_parser(parse_library_paths);
42+
2943
let matches = Command::new("rustbook")
3044
.about("Build a book with mdBook")
3145
.author("Steve Klabnik <[email protected]>")
@@ -42,7 +56,8 @@ fn main() {
4256
.subcommand(
4357
Command::new("test")
4458
.about("Tests that a book's Rust code samples compile")
45-
.arg(dir_arg),
59+
.arg(dir_arg)
60+
.arg(library_path_arg),
4661
)
4762
.get_matches();
4863

@@ -106,14 +121,22 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
106121

107122
fn test(args: &ArgMatches) -> Result3<()> {
108123
let book_dir = get_book_dir(args);
124+
let library_paths = args
125+
.try_get_one::<Vec<String>>("library_path")?
126+
.map(|v| v.iter().map(|s| s.as_str()).collect::<Vec<&str>>())
127+
.unwrap_or_default();
109128
let mut book = load_book(&book_dir)?;
110-
book.test(vec![])
129+
book.test(library_paths)
111130
}
112131

113132
fn get_book_dir(args: &ArgMatches) -> PathBuf {
114133
if let Some(p) = args.get_one::<PathBuf>("dir") {
115134
// Check if path is relative from current dir, or absolute...
116-
if p.is_relative() { env::current_dir().unwrap().join(p) } else { p.to_path_buf() }
135+
if p.is_relative() {
136+
env::current_dir().unwrap().join(p)
137+
} else {
138+
p.to_path_buf()
139+
}
117140
} else {
118141
env::current_dir().unwrap()
119142
}
@@ -125,12 +148,16 @@ fn load_book(book_dir: &Path) -> Result3<MDBook> {
125148
Ok(book)
126149
}
127150

151+
fn parse_library_paths(input: &str) -> Result<Vec<String>, String> {
152+
Ok(input.split(",").map(String::from).collect())
153+
}
154+
128155
fn handle_error(error: mdbook::errors::Error) -> ! {
129156
eprintln!("Error: {}", error);
130157

131158
for cause in error.chain().skip(1) {
132159
eprintln!("\tCaused By: {}", cause);
133160
}
134161

135-
::std::process::exit(101);
162+
std::process::exit(101);
136163
}

0 commit comments

Comments
 (0)