1 use clap::{crate_version};
4 use std::path::{Path, PathBuf};
6 use clap::{App, ArgMatches, SubCommand, AppSettings};
9 use mdbook::errors::{Result as Result3};
11 #[cfg(all(target_arch = "x86_64", target_os = "linux"))]
12 use mdbook::renderer::RenderContext;
14 #[cfg(all(target_arch = "x86_64", target_os = "linux"))]
15 use mdbook_linkcheck::{self, errors::BrokenLinks};
19 let d_message = "-d, --dest-dir=[dest-dir]
20 'The output directory for your book{n}(Defaults to ./book when omitted)'";
21 let dir_message = "[dir]
22 'A directory for your book{n}(Defaults to Current Directory when omitted)'";
24 let matches = App::new("rustbook")
25 .about("Build a book with mdBook")
26 .author("Steve Klabnik <steve@steveklabnik.com>")
27 .version(&*format!("v{}", crate_version!()))
28 .setting(AppSettings::SubcommandRequired)
29 .subcommand(SubCommand::with_name("build")
30 .about("Build the book from the markdown files")
31 .arg_from_usage(d_message)
32 .arg_from_usage(dir_message))
33 .subcommand(SubCommand::with_name("linkcheck")
34 .about("Run linkcheck with mdBook 3")
35 .arg_from_usage(dir_message))
38 // Check which subcomamnd the user ran...
39 match matches.subcommand() {
40 ("build", Some(sub_matches)) => {
41 if let Err(e) = build(sub_matches) {
42 eprintln!("Error: {}", e);
44 for cause in e.iter().skip(1) {
45 eprintln!("\tCaused By: {}", cause);
48 ::std::process::exit(101);
51 ("linkcheck", Some(sub_matches)) => {
52 if let Err(err) = linkcheck(sub_matches) {
53 eprintln!("Error: {}", err);
55 #[cfg(all(target_arch = "x86_64", target_os = "linux"))]
57 if let Ok(broken_links) = err.downcast::<BrokenLinks>() {
58 for cause in broken_links.links().iter() {
59 eprintln!("\tCaused By: {}", cause);
64 ::std::process::exit(101);
67 (_, _) => unreachable!(),
71 #[cfg(all(target_arch = "x86_64", target_os = "linux"))]
72 pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
73 let book_dir = get_book_dir(args);
74 let book = MDBook::load(&book_dir).unwrap();
75 let cfg = book.config;
76 let render_ctx = RenderContext::new(&book_dir, book.book, cfg, &book_dir);
78 mdbook_linkcheck::check_links(&render_ctx)
81 #[cfg(not(all(target_arch = "x86_64", target_os = "linux")))]
82 pub fn linkcheck(_args: &ArgMatches<'_>) -> Result<(), Error> {
83 println!("mdbook-linkcheck only works on x86_64 linux targets.");
87 // Build command implementation
88 pub fn build(args: &ArgMatches<'_>) -> Result3<()> {
89 let book_dir = get_book_dir(args);
90 let mut book = MDBook::load(&book_dir)?;
92 // Set this to allow us to catch bugs in advance.
93 book.config.build.create_missing = false;
95 if let Some(dest_dir) = args.value_of("dest-dir") {
96 book.config.build.build_dir = PathBuf::from(dest_dir);
104 fn get_book_dir(args: &ArgMatches<'_>) -> PathBuf {
105 if let Some(dir) = args.value_of("dir") {
106 // Check if path is relative from current dir, or absolute...
107 let p = Path::new(dir);
109 env::current_dir().unwrap().join(dir)
114 env::current_dir().unwrap()