diff --git a/src/bin/mdbook.rs b/src/bin/mdbook.rs index 027fbb85..9d1db00a 100644 --- a/src/bin/mdbook.rs +++ b/src/bin/mdbook.rs @@ -33,6 +33,8 @@ fn main() { .arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'")) .subcommand(SubCommand::with_name("watch") .about("Watch the files for changes")) + .subcommand(SubCommand::with_name("test") + .about("Test that code samples compile")) .get_matches(); // Check which subcomamnd the user ran... @@ -40,6 +42,7 @@ fn main() { ("init", Some(sub_matches)) => init(sub_matches), ("build", Some(sub_matches)) => build(sub_matches), ("watch", _) => unimplemented!(), + ("test", Some(sub_matches)) => test(sub_matches), (_, _) => unreachable!() }; @@ -104,6 +107,15 @@ fn build(args: &ArgMatches) -> Result<(), Box> { Ok(()) } +fn test(args: &ArgMatches) -> Result<(), Box> { + let book_dir = get_book_dir(args); + let mut book = MDBook::new(&book_dir).read_config(); + + try!(book.test()); + + Ok(()) +} + fn get_book_dir(args: &ArgMatches) -> PathBuf { if let Some(dir) = args.value_of("dir") { // Check if path is relative from current dir, or absolute... diff --git a/src/book/mdbook.rs b/src/book/mdbook.rs index e2ee2581..02430414 100644 --- a/src/book/mdbook.rs +++ b/src/book/mdbook.rs @@ -1,7 +1,10 @@ use std::path::{Path, PathBuf}; use std::fs::{self, File}; -use std::io::Write; use std::error::Error; +use std::io; +use std::io::Write; +use std::io::ErrorKind; +use std::process::Command; use {BookConfig, BookItem, theme, parse, utils}; use book::BookItems; @@ -257,6 +260,39 @@ impl MDBook { self } + pub fn test(&mut self) -> Result<(), Box> { + // read in the chapters + try!(self.parse_summary()); + for item in self.iter() { + + match *item { + BookItem::Chapter(_, ref ch) => { + if ch.path != PathBuf::new() { + + let path = self.get_src().join(&ch.path); + + println!("[*]: Testing file: {:?}", path); + + let output_result = Command::new("rustdoc") + .arg(&path) + .arg("--test") + .output(); + let output = try!(output_result); + + if !output.status.success() { + return Err(Box::new(io::Error::new(ErrorKind::Other, format!( + "{}\n{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr)))) as Box); + } + } + } + _ => {} + } + } + Ok(()) + } + pub fn set_dest(mut self, dest: &Path) -> Self { // Handle absolute and relative paths