]> git.lizzy.rs Git - rust.git/blob - src/tools/rustbook/src/main.rs
Update mdbook.
[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 #[cfg(feature = "linkcheck")]
12 use failure::Error;
13 #[cfg(feature = "linkcheck")]
14 use mdbook::renderer::RenderContext;
15
16 fn main() {
17     let d_message = "-d, --dest-dir=[dest-dir]
18 'The output directory for your book{n}(Defaults to ./book when omitted)'";
19     let dir_message = "[dir]
20 'A directory for your book{n}(Defaults to Current Directory when omitted)'";
21
22     let matches = App::new("rustbook")
23         .about("Build a book with mdBook")
24         .author("Steve Klabnik <steve@steveklabnik.com>")
25         .version(&*format!("v{}", crate_version!()))
26         .setting(AppSettings::SubcommandRequired)
27         .subcommand(
28             SubCommand::with_name("build")
29                 .about("Build the book from the markdown files")
30                 .arg_from_usage(d_message)
31                 .arg_from_usage(dir_message),
32         )
33         .subcommand(
34             SubCommand::with_name("linkcheck")
35                 .about("Run linkcheck with mdBook 3")
36                 .arg_from_usage(dir_message),
37         )
38         .get_matches();
39
40     // Check which subcomamnd the user ran...
41     match matches.subcommand() {
42         ("build", Some(sub_matches)) => {
43             if let Err(e) = build(sub_matches) {
44                 eprintln!("Error: {}", e);
45
46                 for cause in e.iter().skip(1) {
47                     eprintln!("\tCaused By: {}", cause);
48                 }
49
50                 ::std::process::exit(101);
51             }
52         }
53         ("linkcheck", Some(sub_matches)) => {
54             #[cfg(feature = "linkcheck")]
55             {
56                 if let Err(err) = linkcheck(sub_matches) {
57                     eprintln!("Error: {}", err);
58                     std::process::exit(101);
59                 }
60             }
61
62             #[cfg(not(feature = "linkcheck"))]
63             {
64                 // This avoids the `unused_binding` lint.
65                 println!(
66                     "mdbook-linkcheck is disabled, but arguments were passed: {:?}",
67                     sub_matches
68                 );
69             }
70         }
71         (_, _) => unreachable!(),
72     };
73 }
74
75 #[cfg(feature = "linkcheck")]
76 pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
77     let book_dir = get_book_dir(args);
78     let book = MDBook::load(&book_dir).unwrap();
79     let cfg = book.config;
80     let render_ctx = RenderContext::new(&book_dir, book.book, cfg, &book_dir);
81     let cache_file = render_ctx.destination.join("cache.json");
82     let color = codespan_reporting::term::termcolor::ColorChoice::Auto;
83     mdbook_linkcheck::run(&cache_file, color, &render_ctx)
84 }
85
86 // Build command implementation
87 pub fn build(args: &ArgMatches<'_>) -> Result3<()> {
88     let book_dir = get_book_dir(args);
89     let mut book = MDBook::load(&book_dir)?;
90
91     // Set this to allow us to catch bugs in advance.
92     book.config.build.create_missing = false;
93
94     if let Some(dest_dir) = args.value_of("dest-dir") {
95         book.config.build.build_dir = PathBuf::from(dest_dir);
96     }
97
98     book.build()?;
99
100     Ok(())
101 }
102
103 fn get_book_dir(args: &ArgMatches<'_>) -> PathBuf {
104     if let Some(dir) = args.value_of("dir") {
105         // Check if path is relative from current dir, or absolute...
106         let p = Path::new(dir);
107         if p.is_relative() { env::current_dir().unwrap().join(dir) } else { p.to_path_buf() }
108     } else {
109         env::current_dir().unwrap()
110     }
111 }