diff --git a/Cargo.toml b/Cargo.toml index 9ff9eb0a5..6e5eed8f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["template-engine"] edition = "2018" [dependencies] -globwalk = "0.8" +globwalk = {version = "0.8", optional = true} serde = "1.0" serde_json = "1.0" pest = "2" @@ -41,9 +41,10 @@ pretty_assertions = "0.6" tempfile = "3" [features] -default = ["builtins"] +default = ["builtins", "globs"] builtins = ["slug", "percent-encoding", "humansize", "chrono", "chrono-tz", "unic-segment", "rand"] preserve_order = ["serde_json/preserve_order"] +globs = ["globwalk"] [badges] maintenance = { status = "actively-developed" } diff --git a/src/tera.rs b/src/tera.rs index 65daefc66..8c7534d5d 100644 --- a/src/tera.rs +++ b/src/tera.rs @@ -5,6 +5,7 @@ use std::io::prelude::*; use std::path::Path; use std::sync::Arc; +#[cfg(feature = "globs")] use globwalk::glob; use crate::builtins::filters::{array, common, number, object, string, Filter}; @@ -123,48 +124,51 @@ impl Tera { .map(|(n, t)| (n.clone(), t.clone())) // TODO: avoid that clone .collect(); - let mut errors = String::new(); - - let dir = self.glob.clone().unwrap(); - // We clean the filename by removing the dir given - // to Tera so users don't have to prefix everytime - let mut parent_dir = dir.split_at(dir.find('*').unwrap()).0; - // Remove `./` from the glob if used as it would cause an error in strip_prefix - if parent_dir.starts_with("./") { - parent_dir = &parent_dir[2..]; - } + #[cfg(feature = "globs")] + { + let mut errors = String::new(); + + let dir = self.glob.clone().unwrap(); + // We clean the filename by removing the dir given + // to Tera so users don't have to prefix everytime + let mut parent_dir = dir.split_at(dir.find('*').unwrap()).0; + // Remove `./` from the glob if used as it would cause an error in strip_prefix + if parent_dir.starts_with("./") { + parent_dir = &parent_dir[2..]; + } - // We are parsing all the templates on instantiation - for entry in glob(&dir).unwrap().filter_map(std::result::Result::ok) { - let mut path = entry.into_path(); - // We only care about actual files - if path.is_file() { - if path.starts_with("./") { - path = path.strip_prefix("./").unwrap().to_path_buf(); - } + // We are parsing all the templates on instantiation + for entry in glob(&dir).unwrap().filter_map(std::result::Result::ok) { + let mut path = entry.into_path(); + // We only care about actual files + if path.is_file() { + if path.starts_with("./") { + path = path.strip_prefix("./").unwrap().to_path_buf(); + } - let filepath = path - .strip_prefix(&parent_dir) - .unwrap() - .to_string_lossy() - // unify on forward slash - .replace("\\", "/"); - - if let Err(e) = self.add_file(Some(&filepath), path) { - use std::error::Error; - - errors += &format!("\n* {}", e); - let mut cause = e.source(); - while let Some(e) = cause { - errors += &format!("\n{}", e); - cause = e.source(); + let filepath = path + .strip_prefix(&parent_dir) + .unwrap() + .to_string_lossy() + // unify on forward slash + .replace("\\", "/"); + + if let Err(e) = self.add_file(Some(&filepath), path) { + use std::error::Error; + + errors += &format!("\n* {}", e); + let mut cause = e.source(); + while let Some(e) = cause { + errors += &format!("\n{}", e); + cause = e.source(); + } } } } - } - if !errors.is_empty() { - return Err(Error::msg(errors)); + if !errors.is_empty() { + return Err(Error::msg(errors)); + } } Ok(()) @@ -729,9 +733,11 @@ impl fmt::Debug for Tera { #[cfg(test)] mod tests { + #[cfg(feature = "globs")] use tempfile::tempdir; use std::collections::HashMap; + #[cfg(feature = "globs")] use std::fs::File; use super::Tera; @@ -973,18 +979,21 @@ mod tests { assert!(my_tera.testers.contains_key("hello")); } + #[cfg(feature = "globs")] #[test] fn can_load_from_glob() { let tera = Tera::new("examples/basic/templates/**/*").unwrap(); assert!(tera.get_template("base.html").is_ok()); } + #[cfg(feature = "globs")] #[test] fn can_load_from_glob_with_patterns() { let tera = Tera::new("examples/basic/templates/**/*.{html, xml}").unwrap(); assert!(tera.get_template("base.html").is_ok()); } + #[cfg(feature = "globs")] #[test] fn full_reload_with_glob() { let mut tera = Tera::new("examples/basic/templates/**/*").unwrap(); @@ -993,6 +1002,7 @@ mod tests { assert!(tera.get_template("base.html").is_ok()); } + #[cfg(feature = "globs")] #[test] fn full_reload_with_glob_after_extending() { let mut tera = Tera::new("examples/basic/templates/**/*").unwrap(); @@ -1007,6 +1017,7 @@ mod tests { assert!(tera.get_template("one").is_ok()); } + #[cfg(feature = "globs")] #[should_panic] #[test] fn test_can_only_parse_templates() { @@ -1023,6 +1034,7 @@ mod tests { } // https://github.com/Keats/tera/issues/380 + #[cfg(feature = "globs")] #[test] fn glob_work_with_absolute_paths() { let tmp_dir = tempdir().expect("create temp dir"); @@ -1034,6 +1046,7 @@ mod tests { assert_eq!(tera.templates.len(), 2); } + #[cfg(feature = "globs")] #[test] fn glob_work_with_absolute_paths_and_double_star() { let tmp_dir = tempdir().expect("create temp dir"); diff --git a/tests/render_fails.rs b/tests/render_fails.rs index bbd256e8f..89db5a165 100644 --- a/tests/render_fails.rs +++ b/tests/render_fails.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "globs")] extern crate tera; #[macro_use] extern crate serde_derive;