Refactor: Move fs related functions from utils into their own submodule
This commit is contained in:
parent
ad0794a0bd
commit
74fff81e4b
|
@ -198,7 +198,7 @@ impl MDBook {
|
||||||
try!(self.init());
|
try!(self.init());
|
||||||
|
|
||||||
// Clean output directory
|
// Clean output directory
|
||||||
try!(utils::remove_dir_content(&self.config.get_dest()));
|
try!(utils::fs::remove_dir_content(&self.config.get_dest()));
|
||||||
|
|
||||||
try!(self.renderer.render(&self));
|
try!(self.renderer.render(&self));
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
//! I have regrouped some useful functions in the [utils](utils/index.html) module, like the following function
|
//! I have regrouped some useful functions in the [utils](utils/index.html) module, like the following function
|
||||||
//!
|
//!
|
||||||
//! ```ignore
|
//! ```ignore
|
||||||
//! utils::create_path(path: &Path)
|
//! utils::fs::create_path(path: &Path)
|
||||||
//! ```
|
//! ```
|
||||||
//! This function creates all the directories in a given path if they do not exist
|
//! This function creates all the directories in a given path if they do not exist
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
|
|
||||||
// Remove path to root from previous file and render content for this one
|
// Remove path to root from previous file and render content for this one
|
||||||
data.remove("path_to_root");
|
data.remove("path_to_root");
|
||||||
data.insert("path_to_root".to_owned(), utils::path_to_root(&ch.path).to_json());
|
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(&ch.path).to_json());
|
||||||
|
|
||||||
// Rendere the handlebars template with the data
|
// Rendere the handlebars template with the data
|
||||||
debug!("[*]: Render template");
|
debug!("[*]: Render template");
|
||||||
|
@ -108,7 +108,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
|
|
||||||
debug!("[*]: Create file {:?}", &book.get_dest().join(&ch.path).with_extension("html"));
|
debug!("[*]: Create file {:?}", &book.get_dest().join(&ch.path).with_extension("html"));
|
||||||
// Write to file
|
// Write to file
|
||||||
let mut file = try!(utils::create_file(&book.get_dest().join(&ch.path).with_extension("html")));
|
let mut file = try!(utils::fs::create_file(&book.get_dest().join(&ch.path).with_extension("html")));
|
||||||
output!("[*] Creating {:?} ✓", &book.get_dest().join(&ch.path).with_extension("html"));
|
output!("[*] Creating {:?} ✓", &book.get_dest().join(&ch.path).with_extension("html"));
|
||||||
|
|
||||||
try!(file.write_all(&rendered.into_bytes()));
|
try!(file.write_all(&rendered.into_bytes()));
|
||||||
|
@ -153,12 +153,12 @@ impl Renderer for HtmlHandlebars {
|
||||||
|
|
||||||
// Remove path to root from previous file and render content for this one
|
// Remove path to root from previous file and render content for this one
|
||||||
data.remove("path_to_root");
|
data.remove("path_to_root");
|
||||||
data.insert("path_to_root".to_owned(), utils::path_to_root(Path::new("print.md")).to_json());
|
data.insert("path_to_root".to_owned(), utils::fs::path_to_root(Path::new("print.md")).to_json());
|
||||||
|
|
||||||
// Rendere the handlebars template with the data
|
// Rendere the handlebars template with the data
|
||||||
debug!("[*]: Render template");
|
debug!("[*]: Render template");
|
||||||
let rendered = try!(handlebars.render("index", &data));
|
let rendered = try!(handlebars.render("index", &data));
|
||||||
let mut file = try!(utils::create_file(&book.get_dest().join("print").with_extension("html")));
|
let mut file = try!(utils::fs::create_file(&book.get_dest().join("print").with_extension("html")));
|
||||||
try!(file.write_all(&rendered.into_bytes()));
|
try!(file.write_all(&rendered.into_bytes()));
|
||||||
output!("[*] Creating print.html ✓");
|
output!("[*] Creating print.html ✓");
|
||||||
|
|
||||||
|
@ -220,14 +220,14 @@ impl Renderer for HtmlHandlebars {
|
||||||
try!(highlight_js.write_all(&theme.highlight_js));
|
try!(highlight_js.write_all(&theme.highlight_js));
|
||||||
|
|
||||||
// Font Awesome local fallback
|
// Font Awesome local fallback
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/css/font-awesome.css")) {
|
.join("_FontAwesome/css/font-awesome.css")) {
|
||||||
f
|
f
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create font-awesome.css")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create font-awesome.css")));
|
||||||
};
|
};
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME));
|
try!(font_awesome.write_all(theme::FONT_AWESOME));
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/fonts/fontawesome-webfon\
|
.join("_FontAwesome/fonts/fontawesome-webfon\
|
||||||
t.eot")) {
|
t.eot")) {
|
||||||
f
|
f
|
||||||
|
@ -235,7 +235,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.eot")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.eot")));
|
||||||
};
|
};
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME_EOT));
|
try!(font_awesome.write_all(theme::FONT_AWESOME_EOT));
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/fonts/fontawesome-webfon\
|
.join("_FontAwesome/fonts/fontawesome-webfon\
|
||||||
t.svg")) {
|
t.svg")) {
|
||||||
f
|
f
|
||||||
|
@ -243,7 +243,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.svg")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.svg")));
|
||||||
};
|
};
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME_SVG));
|
try!(font_awesome.write_all(theme::FONT_AWESOME_SVG));
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/fonts/fontawesome-webfon\
|
.join("_FontAwesome/fonts/fontawesome-webfon\
|
||||||
t.ttf")) {
|
t.ttf")) {
|
||||||
f
|
f
|
||||||
|
@ -251,7 +251,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.ttf")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.ttf")));
|
||||||
};
|
};
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
|
try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/fonts/fontawesome-webfon\
|
.join("_FontAwesome/fonts/fontawesome-webfon\
|
||||||
t.woff")) {
|
t.woff")) {
|
||||||
f
|
f
|
||||||
|
@ -259,7 +259,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff")));
|
||||||
};
|
};
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF));
|
try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF));
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/fonts/fontawesome-webfon\
|
.join("_FontAwesome/fonts/fontawesome-webfon\
|
||||||
t.woff2")) {
|
t.woff2")) {
|
||||||
f
|
f
|
||||||
|
@ -267,7 +267,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff2")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff2")));
|
||||||
};
|
};
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2));
|
try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2));
|
||||||
let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest()
|
let mut font_awesome = if let Ok(f) = utils::fs::create_file(&book.get_dest()
|
||||||
.join("_FontAwesome/fonts/FontAwesome.ttf")) {
|
.join("_FontAwesome/fonts/FontAwesome.ttf")) {
|
||||||
f
|
f
|
||||||
} else {
|
} else {
|
||||||
|
@ -276,7 +276,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
|
try!(font_awesome.write_all(theme::FONT_AWESOME_TTF));
|
||||||
|
|
||||||
// Copy all remaining files
|
// Copy all remaining files
|
||||||
try!(utils::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"]));
|
try!(utils::fs::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"]));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
use std::path::{Path, Component};
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io;
|
||||||
|
use std::fs::{self, metadata, File};
|
||||||
|
|
||||||
|
|
||||||
|
/// Takes a path and returns a path containing just enough `../` to point to the root of the given path.
|
||||||
|
///
|
||||||
|
/// This is mostly interesting for a relative path to point back to the directory from where the
|
||||||
|
/// path starts.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let mut path = Path::new("some/relative/path");
|
||||||
|
///
|
||||||
|
/// println!("{}", path_to_root(&path));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// **Outputs**
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// "../../"
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// **note:** it's not very fool-proof, if you find a situation where it doesn't return the correct
|
||||||
|
/// path. Consider [submitting a new issue](https://github.com/azerupi/mdBook/issues) or a
|
||||||
|
/// [pull-request](https://github.com/azerupi/mdBook/pulls) to improve it.
|
||||||
|
|
||||||
|
pub fn path_to_root(path: &Path) -> String {
|
||||||
|
debug!("[fn]: path_to_root");
|
||||||
|
// Remove filename and add "../" for every directory
|
||||||
|
|
||||||
|
path.to_path_buf()
|
||||||
|
.parent()
|
||||||
|
.expect("")
|
||||||
|
.components()
|
||||||
|
.fold(String::new(), |mut s, c| {
|
||||||
|
match c {
|
||||||
|
Component::Normal(_) => s.push_str("../"),
|
||||||
|
_ => {
|
||||||
|
debug!("[*]: Other path component... {:?}", c);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
s
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// This function creates a file and returns it. But before creating the file it checks every
|
||||||
|
/// directory in the path to see if it exists, and if it does not it will be created.
|
||||||
|
|
||||||
|
pub fn create_file(path: &Path) -> Result<File, Box<Error>> {
|
||||||
|
debug!("[fn]: create_file");
|
||||||
|
|
||||||
|
// Construct path
|
||||||
|
if let Some(p) = path.parent() {
|
||||||
|
debug!("Parent directory is: {:?}", p);
|
||||||
|
|
||||||
|
try!(fs::create_dir_all(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("[*]: Create file: {:?}", path);
|
||||||
|
let f = match File::create(path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(e) => {
|
||||||
|
debug!("File::create: {}", e);
|
||||||
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, format!("{}", e))));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes all the content of a directory but not the directory itself
|
||||||
|
|
||||||
|
pub fn remove_dir_content(dir: &Path) -> Result<(), Box<Error>> {
|
||||||
|
for item in try!(fs::read_dir(dir)) {
|
||||||
|
if let Ok(item) = item {
|
||||||
|
let item = item.path();
|
||||||
|
if item.is_dir() {
|
||||||
|
try!(fs::remove_dir_all(item));
|
||||||
|
} else {
|
||||||
|
try!(fs::remove_file(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// Copies all files of a directory to another one except the files with the extensions given in the
|
||||||
|
/// `ext_blacklist` array
|
||||||
|
|
||||||
|
pub fn copy_files_except_ext(from: &Path, to: &Path, recursive: bool, ext_blacklist: &[&str]) -> Result<(), Box<Error>> {
|
||||||
|
debug!("[fn] copy_files_except_ext");
|
||||||
|
// Check that from and to are different
|
||||||
|
if from == to {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
debug!("[*] Loop");
|
||||||
|
for entry in try!(fs::read_dir(from)) {
|
||||||
|
let entry = try!(entry);
|
||||||
|
debug!("[*] {:?}", entry.path());
|
||||||
|
let metadata = try!(entry.metadata());
|
||||||
|
|
||||||
|
// If the entry is a dir and the recursive option is enabled, call itself
|
||||||
|
if metadata.is_dir() && recursive {
|
||||||
|
if entry.path() == to.to_path_buf() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
debug!("[*] is dir");
|
||||||
|
|
||||||
|
// check if output dir already exists
|
||||||
|
if !to.join(entry.file_name()).exists() {
|
||||||
|
try!(fs::create_dir(&to.join(entry.file_name())));
|
||||||
|
}
|
||||||
|
|
||||||
|
try!(copy_files_except_ext(&from.join(entry.file_name()),
|
||||||
|
&to.join(entry.file_name()),
|
||||||
|
true,
|
||||||
|
ext_blacklist));
|
||||||
|
} else if metadata.is_file() {
|
||||||
|
|
||||||
|
// Check if it is in the blacklist
|
||||||
|
if let Some(ext) = entry.path().extension() {
|
||||||
|
if ext_blacklist.contains(&ext.to_str().unwrap()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
debug!("[*] creating path for file: {:?}",
|
||||||
|
&to.join(entry.path().file_name().expect("a file should have a file name...")));
|
||||||
|
|
||||||
|
output!("[*] copying file: {:?}\n to {:?}",
|
||||||
|
entry.path(),
|
||||||
|
&to.join(entry.path().file_name().expect("a file should have a file name...")));
|
||||||
|
try!(fs::copy(entry.path(),
|
||||||
|
&to.join(entry.path().file_name().expect("a file should have a file name..."))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// tests
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
extern crate tempdir;
|
||||||
|
|
||||||
|
use super::copy_files_except_ext;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn copy_files_except_ext_test() {
|
||||||
|
let tmp = match tempdir::TempDir::new("") {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(_) => panic!("Could not create a temp dir"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a couple of files
|
||||||
|
if let Err(_) = fs::File::create(&tmp.path().join("file.txt")) {
|
||||||
|
panic!("Could not create file.txt")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::File::create(&tmp.path().join("file.md")) {
|
||||||
|
panic!("Could not create file.md")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::File::create(&tmp.path().join("file.png")) {
|
||||||
|
panic!("Could not create file.png")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir")) {
|
||||||
|
panic!("Could not create sub_dir")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir/file.png")) {
|
||||||
|
panic!("Could not create sub_dir/file.png")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir_exists")) {
|
||||||
|
panic!("Could not create sub_dir_exists")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
|
||||||
|
panic!("Could not create sub_dir_exists/file.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create output dir
|
||||||
|
if let Err(_) = fs::create_dir(&tmp.path().join("output")) {
|
||||||
|
panic!("Could not create output")
|
||||||
|
}
|
||||||
|
if let Err(_) = fs::create_dir(&tmp.path().join("output/sub_dir_exists")) {
|
||||||
|
panic!("Could not create output/sub_dir_exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
match copy_files_except_ext(&tmp.path(), &tmp.path().join("output"), true, &["md"]) {
|
||||||
|
Err(e) => panic!("Error while executing the function:\n{:?}", e),
|
||||||
|
Ok(_) => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the correct files where created
|
||||||
|
if !(&tmp.path().join("output/file.txt")).exists() {
|
||||||
|
panic!("output/file.txt should exist")
|
||||||
|
}
|
||||||
|
if (&tmp.path().join("output/file.md")).exists() {
|
||||||
|
panic!("output/file.md should not exist")
|
||||||
|
}
|
||||||
|
if !(&tmp.path().join("output/file.png")).exists() {
|
||||||
|
panic!("output/file.png should exist")
|
||||||
|
}
|
||||||
|
if !(&tmp.path().join("output/sub_dir/file.png")).exists() {
|
||||||
|
panic!("output/sub_dir/file.png should exist")
|
||||||
|
}
|
||||||
|
if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
|
||||||
|
panic!("output/sub_dir/file.png should exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
218
src/utils/mod.rs
218
src/utils/mod.rs
|
@ -1,148 +1,9 @@
|
||||||
extern crate pulldown_cmark;
|
extern crate pulldown_cmark;
|
||||||
|
|
||||||
use std::path::{Path, Component};
|
pub mod fs;
|
||||||
use std::error::Error;
|
|
||||||
use std::io;
|
|
||||||
use std::fs::{self, metadata, File};
|
|
||||||
|
|
||||||
use self::pulldown_cmark::{Parser, html, Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES};
|
use self::pulldown_cmark::{Parser, html, Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES};
|
||||||
|
|
||||||
/// Takes a path and returns a path containing just enough `../` to point to the root of the given path.
|
|
||||||
///
|
|
||||||
/// This is mostly interesting for a relative path to point back to the directory from where the
|
|
||||||
/// path starts.
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// let mut path = Path::new("some/relative/path");
|
|
||||||
///
|
|
||||||
/// println!("{}", path_to_root(&path));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// **Outputs**
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// "../../"
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// **note:** it's not very fool-proof, if you find a situation where it doesn't return the correct
|
|
||||||
/// path. Consider [submitting a new issue](https://github.com/azerupi/mdBook/issues) or a
|
|
||||||
/// [pull-request](https://github.com/azerupi/mdBook/pulls) to improve it.
|
|
||||||
|
|
||||||
pub fn path_to_root(path: &Path) -> String {
|
|
||||||
debug!("[fn]: path_to_root");
|
|
||||||
// Remove filename and add "../" for every directory
|
|
||||||
|
|
||||||
path.to_path_buf()
|
|
||||||
.parent()
|
|
||||||
.expect("")
|
|
||||||
.components()
|
|
||||||
.fold(String::new(), |mut s, c| {
|
|
||||||
match c {
|
|
||||||
Component::Normal(_) => s.push_str("../"),
|
|
||||||
_ => {
|
|
||||||
debug!("[*]: Other path component... {:?}", c);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
s
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// This function creates a file and returns it. But before creating the file it checks every
|
|
||||||
/// directory in the path to see if it exists, and if it does not it will be created.
|
|
||||||
|
|
||||||
pub fn create_file(path: &Path) -> Result<File, Box<Error>> {
|
|
||||||
debug!("[fn]: create_file");
|
|
||||||
|
|
||||||
// Construct path
|
|
||||||
if let Some(p) = path.parent() {
|
|
||||||
debug!("Parent directory is: {:?}", p);
|
|
||||||
|
|
||||||
try!(fs::create_dir_all(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("[*]: Create file: {:?}", path);
|
|
||||||
let f = match File::create(path) {
|
|
||||||
Ok(f) => f,
|
|
||||||
Err(e) => {
|
|
||||||
debug!("File::create: {}", e);
|
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, format!("{}", e))));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes all the content of a directory but not the directory itself
|
|
||||||
|
|
||||||
pub fn remove_dir_content(dir: &Path) -> Result<(), Box<Error>> {
|
|
||||||
for item in try!(fs::read_dir(dir)) {
|
|
||||||
if let Ok(item) = item {
|
|
||||||
let item = item.path();
|
|
||||||
if item.is_dir() {
|
|
||||||
try!(fs::remove_dir_all(item));
|
|
||||||
} else {
|
|
||||||
try!(fs::remove_file(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// Copies all files of a directory to another one except the files with the extensions given in the
|
|
||||||
/// `ext_blacklist` array
|
|
||||||
|
|
||||||
pub fn copy_files_except_ext(from: &Path, to: &Path, recursive: bool, ext_blacklist: &[&str]) -> Result<(), Box<Error>> {
|
|
||||||
debug!("[fn] copy_files_except_ext");
|
|
||||||
// Check that from and to are different
|
|
||||||
if from == to {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
debug!("[*] Loop");
|
|
||||||
for entry in try!(fs::read_dir(from)) {
|
|
||||||
let entry = try!(entry);
|
|
||||||
debug!("[*] {:?}", entry.path());
|
|
||||||
let metadata = try!(entry.metadata());
|
|
||||||
|
|
||||||
// If the entry is a dir and the recursive option is enabled, call itself
|
|
||||||
if metadata.is_dir() && recursive {
|
|
||||||
if entry.path() == to.to_path_buf() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
debug!("[*] is dir");
|
|
||||||
|
|
||||||
// check if output dir already exists
|
|
||||||
if !to.join(entry.file_name()).exists() {
|
|
||||||
try!(fs::create_dir(&to.join(entry.file_name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
try!(copy_files_except_ext(&from.join(entry.file_name()),
|
|
||||||
&to.join(entry.file_name()),
|
|
||||||
true,
|
|
||||||
ext_blacklist));
|
|
||||||
} else if metadata.is_file() {
|
|
||||||
|
|
||||||
// Check if it is in the blacklist
|
|
||||||
if let Some(ext) = entry.path().extension() {
|
|
||||||
if ext_blacklist.contains(&ext.to_str().unwrap()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
debug!("[*] creating path for file: {:?}",
|
|
||||||
&to.join(entry.path().file_name().expect("a file should have a file name...")));
|
|
||||||
|
|
||||||
output!("[*] copying file: {:?}\n to {:?}",
|
|
||||||
entry.path(),
|
|
||||||
&to.join(entry.path().file_name().expect("a file should have a file name...")));
|
|
||||||
try!(fs::copy(entry.path(),
|
|
||||||
&to.join(entry.path().file_name().expect("a file should have a file name..."))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -160,80 +21,3 @@ pub fn render_markdown(text: &str) -> String {
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// tests
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
extern crate tempdir;
|
|
||||||
|
|
||||||
use super::copy_files_except_ext;
|
|
||||||
use std::fs;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn copy_files_except_ext_test() {
|
|
||||||
let tmp = match tempdir::TempDir::new("") {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(_) => panic!("Could not create a temp dir"),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a couple of files
|
|
||||||
if let Err(_) = fs::File::create(&tmp.path().join("file.txt")) {
|
|
||||||
panic!("Could not create file.txt")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::File::create(&tmp.path().join("file.md")) {
|
|
||||||
panic!("Could not create file.md")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::File::create(&tmp.path().join("file.png")) {
|
|
||||||
panic!("Could not create file.png")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir")) {
|
|
||||||
panic!("Could not create sub_dir")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir/file.png")) {
|
|
||||||
panic!("Could not create sub_dir/file.png")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::create_dir(&tmp.path().join("sub_dir_exists")) {
|
|
||||||
panic!("Could not create sub_dir_exists")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
|
|
||||||
panic!("Could not create sub_dir_exists/file.txt")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create output dir
|
|
||||||
if let Err(_) = fs::create_dir(&tmp.path().join("output")) {
|
|
||||||
panic!("Could not create output")
|
|
||||||
}
|
|
||||||
if let Err(_) = fs::create_dir(&tmp.path().join("output/sub_dir_exists")) {
|
|
||||||
panic!("Could not create output/sub_dir_exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
match copy_files_except_ext(&tmp.path(), &tmp.path().join("output"), true, &["md"]) {
|
|
||||||
Err(e) => panic!("Error while executing the function:\n{:?}", e),
|
|
||||||
Ok(_) => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the correct files where created
|
|
||||||
if !(&tmp.path().join("output/file.txt")).exists() {
|
|
||||||
panic!("output/file.txt should exist")
|
|
||||||
}
|
|
||||||
if (&tmp.path().join("output/file.md")).exists() {
|
|
||||||
panic!("output/file.md should not exist")
|
|
||||||
}
|
|
||||||
if !(&tmp.path().join("output/file.png")).exists() {
|
|
||||||
panic!("output/file.png should exist")
|
|
||||||
}
|
|
||||||
if !(&tmp.path().join("output/sub_dir/file.png")).exists() {
|
|
||||||
panic!("output/sub_dir/file.png should exist")
|
|
||||||
}
|
|
||||||
if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
|
|
||||||
panic!("output/sub_dir/file.png should exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue