Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make globs an optional feature #498

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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" }
85 changes: 49 additions & 36 deletions src/tera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a subtle change in behavior that caught me off guard at first. I thought this was a behavioral breaking change at first, but then i realized that you've made globs a default feature, so it's subtly not a breaking change. 👍

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a breaking change for anyone using default-features=false

{
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(())
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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() {
Expand All @@ -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");
Expand All @@ -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");
Expand Down
1 change: 1 addition & 0 deletions tests/render_fails.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(feature = "globs")]
extern crate tera;
#[macro_use]
extern crate serde_derive;
Expand Down