clean output folder without removing dotfiles

This commit is contained in:
Gambhiro 2017-01-18 13:13:38 +00:00
parent a8021eb4e8
commit cb861a7354
3 changed files with 70 additions and 20 deletions

View File

@ -6,6 +6,7 @@ use book::toc::{TocItem, TocContent};
use utils; use utils;
use FILES; use FILES;
use std::process::exit;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::{self, File}; use std::fs::{self, File};
@ -35,15 +36,16 @@ impl Renderer for HtmlHandlebars {
let mut book_project = MDBook::new(&project_root); let mut book_project = MDBook::new(&project_root);
book_project.read_config(); book_project.read_config();
if !book_project.get_src_base().exists() {
println!("Source folder doesn't exist: {:?}", book_project.get_src_base());
exit(2);
}
book_project.parse_books(); book_project.parse_books();
book_project.link_translations(); book_project.link_translations();
// Clean output directory try!(utils::fs::clean_output_dir(&book_project.get_dest_base()));
// FIXME don't remove dotfiles such as .git/ folder. It's a common
// practice to track gh-pages in a versioned output folder.
//try!(utils::fs::remove_dir_content(&book_project.get_dest_base()));
// TODO talk to the user // TODO talk to the user
try!(self.render(&book_project)); try!(self.render(&book_project));

View File

@ -1,5 +1,6 @@
#[cfg(test)] #[cfg(test)]
use std;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
@ -8,7 +9,9 @@ use utils;
#[test] #[test]
fn it_copies_data_file() { fn it_copies_data_file() {
let dest_path = Path::new("the place was dark").join("and dusty and half-lost").join("book.css"); let dest_base = std::env::temp_dir().join("in tangles of old alleys");
let dest_path = dest_base.join("book.css");
utils::fs::copy_data_file("data/_html-template/css/books.css", &dest_path); utils::fs::copy_data_file("data/_html-template/css/books.css", &dest_path);
let mut file = match File::open(&dest_path) { let mut file = match File::open(&dest_path) {
@ -26,11 +29,15 @@ fn it_copies_data_file() {
} }
assert!(content.as_str().contains("Open Sans")); assert!(content.as_str().contains("Open Sans"));
if dest_base.exists() {
fs::remove_dir_all(dest_base);
}
} }
#[test] #[test]
fn it_copies_data_by_pattern() { fn it_copies_data_by_pattern() {
let dest_base = Path::new("in tangles of old alleys").join("near the quays"); let dest_base = std::env::temp_dir().join("near the quays");
if let Err(e) = utils::fs::copy_data("data/_html-template/**/*", if let Err(e) = utils::fs::copy_data("data/_html-template/**/*",
"data/_html-template/", "data/_html-template/",
@ -43,8 +50,32 @@ fn it_copies_data_by_pattern() {
assert!(dest_base.join("css").join("book.css").exists()); assert!(dest_base.join("css").join("book.css").exists());
assert!(!dest_base.join("_layouts").exists()); assert!(!dest_base.join("_layouts").exists());
let p = Path::new("in tangles of old alleys"); if dest_base.exists() {
if p.exists() { fs::remove_dir_all(dest_base);
fs::remove_dir_all(p); }
}
#[test]
fn it_doesnt_delete_toplevel_dotfiles() {
let dest_base = std::env::temp_dir().join("with queer curls of fog");
match utils::fs::create_with_str(&dest_base.join(".dotfile"), "that west winds tossed") {
Err(e) => { println!("Error: {:#?}", e); return; },
Ok(_) => {},
}
match utils::fs::create_with_str(&dest_base.join("door.html"), "<p>I entered, charmed</p>") {
Err(e) => { println!("Error: {:#?}", e); return; },
Ok(_) => {},
}
utils::fs::clean_output_dir(&dest_base);
assert!(dest_base.exists());
assert!(dest_base.join(".dotfile").exists());
assert!(!dest_base.join("door.html").exists());
if dest_base.exists() {
fs::remove_dir_all(dest_base);
} }
} }

View File

@ -89,6 +89,7 @@ pub fn copy_data(include_glob: &str,
.map(|x| { .map(|x| {
let mut s: &str = &x.replace(include_base, ""); let mut s: &str = &x.replace(include_base, "");
s = s.trim_left_matches("/"); s = s.trim_left_matches("/");
s = s.trim_left_matches(r"\");
let p = Path::new(s); let p = Path::new(s);
let dest_path = dest_base.join(p); let dest_path = dest_base.join(p);
@ -242,21 +243,37 @@ pub fn create_file(path: &Path) -> Result<File, Box<Error>> {
Ok(f) Ok(f)
} }
// TODO why not just delete the folder and re-create it? /// A cleaning operation intended to be used on the output directory of a book
/// before producing new output files. It removes the content of the directory,
/// Removes all the content of a directory but not the directory itself /// except for dotfiles at the toplevel.
pub fn remove_dir_content(dir: &Path) -> Result<(), Box<Error>> { ///
/// This keeps VCS files intact such as `.git/, .gitignore`, and the output
/// folder can be used to track the gh-pages branch of the repository, which is
/// a common practice.
pub fn clean_output_dir(dir: &Path) -> Result<(), Box<Error>> {
if !dir.exists() { if !dir.exists() {
return Ok(()); return Ok(());
} }
let exclude_pat = Pattern::new(".*").unwrap();
for item in try!(fs::read_dir(dir)) { for item in try!(fs::read_dir(dir)) {
if let Ok(item) = item { if let Ok(item) = item {
let item = item.path(); if let Some(a) = item.path().to_str() {
if item.is_dir() { if let Some(d) = dir.as_os_str().to_str() {
try!(fs::remove_dir_all(item)); let mut s: &str = &a.replace(d, "");
s = s.trim_left_matches("/");
s = s.trim_left_matches(r"\");
if !exclude_pat.matches(s) {
let p = item.path();
if p.is_dir() {
try!(fs::remove_dir_all(p));
} else { } else {
try!(fs::remove_file(item)); try!(fs::remove_file(p));
}
}
}
} }
} }
} }