1 use clap::crate_version;
4 use std::path::{Path, PathBuf};
6 use clap::{arg, ArgMatches, Command};
8 use mdbook::errors::Result as Result3;
12 let crate_version = concat!("v", crate_version!());
13 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
14 let d_arg = arg!(-d --"dest-dir" <DEST_DIR>
15 "The output directory for your book\n(Defaults to ./book when omitted)")
17 .value_parser(clap::value_parser!(PathBuf));
19 let dir_arg = arg!([dir] "Root directory for the book\n\
20 (Defaults to the current directory when omitted)")
21 .value_parser(clap::value_parser!(PathBuf));
23 let matches = Command::new("rustbook")
24 .about("Build a book with mdBook")
25 .author("Steve Klabnik <steve@steveklabnik.com>")
26 .version(crate_version)
27 .subcommand_required(true)
28 .arg_required_else_help(true)
31 .about("Build the book from the markdown files")
37 .about("Tests that a book's Rust code samples compile")
42 // Check which subcomamnd the user ran...
43 match matches.subcommand() {
44 Some(("build", sub_matches)) => {
45 if let Err(e) = build(sub_matches) {
49 Some(("test", sub_matches)) => {
50 if let Err(e) = test(sub_matches) {
58 // Build command implementation
59 pub fn build(args: &ArgMatches) -> Result3<()> {
60 let book_dir = get_book_dir(args);
61 let mut book = load_book(&book_dir)?;
63 // Set this to allow us to catch bugs in advance.
64 book.config.build.create_missing = false;
66 if let Some(dest_dir) = args.get_one::<PathBuf>("dest-dir") {
67 book.config.build.build_dir = dest_dir.into();
75 fn test(args: &ArgMatches) -> Result3<()> {
76 let book_dir = get_book_dir(args);
77 let mut book = load_book(&book_dir)?;
81 fn get_book_dir(args: &ArgMatches) -> PathBuf {
82 if let Some(p) = args.get_one::<PathBuf>("dir") {
83 // Check if path is relative from current dir, or absolute...
84 if p.is_relative() { env::current_dir().unwrap().join(p) } else { p.to_path_buf() }
86 env::current_dir().unwrap()
90 fn load_book(book_dir: &Path) -> Result3<MDBook> {
91 let mut book = MDBook::load(book_dir)?;
92 book.config.set("output.html.input-404", "").unwrap();
96 fn handle_error(error: mdbook::errors::Error) -> ! {
97 eprintln!("Error: {}", error);
99 for cause in error.chain().skip(1) {
100 eprintln!("\tCaused By: {}", cause);
103 ::std::process::exit(101);