]> git.lizzy.rs Git - rust.git/blob - src/tools/rustbook/src/main.rs
Rollup merge of #96336 - Nilstrieb:link-to-correct-as_mut-in-ptr-as_ref, r=JohnTitor
[rust.git] / src / tools / rustbook / src / main.rs
1 use clap::crate_version;
2
3 use std::env;
4 use std::path::{Path, PathBuf};
5
6 use clap::{App, AppSettings, ArgMatches, SubCommand};
7
8 use mdbook::errors::Result as Result3;
9 use mdbook::MDBook;
10
11 fn main() {
12     env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
13     let d_message = "-d, --dest-dir=[dest-dir]
14 'The output directory for your book{n}(Defaults to ./book when omitted)'";
15     let dir_message = "[dir]
16 'A directory for your book{n}(Defaults to Current Directory when omitted)'";
17
18     let matches = App::new("rustbook")
19         .about("Build a book with mdBook")
20         .author("Steve Klabnik <steve@steveklabnik.com>")
21         .version(&*format!("v{}", crate_version!()))
22         .setting(AppSettings::SubcommandRequired)
23         .subcommand(
24             SubCommand::with_name("build")
25                 .about("Build the book from the markdown files")
26                 .arg_from_usage(d_message)
27                 .arg_from_usage(dir_message),
28         )
29         .subcommand(
30             SubCommand::with_name("test")
31                 .about("Tests that a book's Rust code samples compile")
32                 .arg_from_usage(dir_message),
33         )
34         .get_matches();
35
36     // Check which subcomamnd the user ran...
37     match matches.subcommand() {
38         ("build", Some(sub_matches)) => {
39             if let Err(e) = build(sub_matches) {
40                 handle_error(e);
41             }
42         }
43         ("test", Some(sub_matches)) => {
44             if let Err(e) = test(sub_matches) {
45                 handle_error(e);
46             }
47         }
48         (_, _) => unreachable!(),
49     };
50 }
51
52 // Build command implementation
53 pub fn build(args: &ArgMatches<'_>) -> Result3<()> {
54     let book_dir = get_book_dir(args);
55     let mut book = load_book(&book_dir)?;
56
57     // Set this to allow us to catch bugs in advance.
58     book.config.build.create_missing = false;
59
60     if let Some(dest_dir) = args.value_of("dest-dir") {
61         book.config.build.build_dir = PathBuf::from(dest_dir);
62     }
63
64     book.build()?;
65
66     Ok(())
67 }
68
69 fn test(args: &ArgMatches<'_>) -> Result3<()> {
70     let book_dir = get_book_dir(args);
71     let mut book = load_book(&book_dir)?;
72     book.test(vec![])
73 }
74
75 fn get_book_dir(args: &ArgMatches<'_>) -> PathBuf {
76     if let Some(dir) = args.value_of("dir") {
77         // Check if path is relative from current dir, or absolute...
78         let p = Path::new(dir);
79         if p.is_relative() { env::current_dir().unwrap().join(dir) } else { p.to_path_buf() }
80     } else {
81         env::current_dir().unwrap()
82     }
83 }
84
85 fn load_book(book_dir: &Path) -> Result3<MDBook> {
86     let mut book = MDBook::load(book_dir)?;
87     book.config.set("output.html.input-404", "").unwrap();
88     Ok(book)
89 }
90
91 fn handle_error(error: mdbook::errors::Error) -> ! {
92     eprintln!("Error: {}", error);
93
94     for cause in error.chain().skip(1) {
95         eprintln!("\tCaused By: {}", cause);
96     }
97
98     ::std::process::exit(101);
99 }