Skip to content

Commit

Permalink
Merge pull request #83 from epage/dbg
Browse files Browse the repository at this point in the history
feat(debug): Adding CLI for testing liquid templates
  • Loading branch information
epage authored May 5, 2017
2 parents 79f4d81 + 9d4b408 commit f9c82c7
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 13 deletions.
8 changes: 5 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ install:
- export PATH=$HOME/.cargo/bin:$PATH

script:
- cargo build
- cargo test
- if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then (cargo clippy) fi
- cargo check
- cargo check --features "cli"
- cargo check --features "cli serde_yaml serde_json"
- cargo test --features "cli serde_yaml serde_json"
- if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then (cargo clippy --features=cli) fi
- cargo fmt -- --write-mode=diff

addons:
Expand Down
27 changes: 19 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[package]

name = "liquid"
version = "0.9.1"
authors = ["Johann Hofmann <[email protected]>"]
Expand All @@ -13,6 +12,20 @@ license = "MIT"

build = "build.rs"

[[bin]]
name = "liquid-dbg"
required-features = ["cli"]
test = false
doctest = false
bench = false
doc = false

[features]
default = ["extra-filters"]
cli = ["clap", "error-chain", "serde_yaml"]
extra-filters = []
dev = []

[dependencies]
regex = "0.2"
lazy_static = "0.2"
Expand All @@ -22,17 +35,15 @@ itertools = "0.6.0"
serde = "1.0"
serde_derive = "1.0"

clap = { version = "2.22.0", optional = true }
error-chain = { version = "0.10.0", optional = true }
serde_yaml = { version = "0.7", optional = true }
serde_json = { version = "1.0", optional = true }

[build-dependencies]
skeptic = "0.9"

[dev-dependencies]
difference = "1.0"
skeptic = "0.9"
serde_yaml = "0.7"

[features]
default = ["extra-filters"]

extra-filters = []

dev=[]
6 changes: 4 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ install:
- cargo -V

test_script:
- cargo build --verbose
- cargo test
- cargo check --verbose
- cargo check --verbose --features "cli"
- cargo check --verbose --features "cli serde_yaml serde_json"
- cargo test --features "cli serde_yaml serde_json"

cache:
- C:\Users\appveyor\.cargo\registry
Expand Down
116 changes: 116 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#[macro_use]
extern crate clap;
#[macro_use]
extern crate error_chain;
extern crate liquid;

#[cfg(feature = "serde_yaml")]
extern crate serde_yaml;
#[cfg(feature = "serde_json")]
extern crate serde_json;

use std::ffi;
use std::fs;
use std::io;
use std::io::Write;
use std::path;
use liquid::Renderable;

error_chain! {
links {
}

foreign_links {
Clap(clap::Error);
Io(io::Error);
Liquid(liquid::Error);
Yaml(serde_yaml::Error) #[cfg(feature = "serde_yaml")];
Json(serde_json::Error) #[cfg(feature = "serde_json")];
}

errors {
}
}

fn option<'a>(name: &'a str, value: &'a str) -> clap::Arg<'a, 'a> {
clap::Arg::with_name(name).long(name).value_name(value)
}

#[cfg(feature = "serde_yaml")]
fn load_yaml(path: &path::Path) -> Result<liquid::Value> {
let f = fs::File::open(path)?;
serde_yaml::from_reader(f).map_err(|e| e.into())
}

#[cfg(not(feature = "serde_yaml"))]
fn load_yaml(path: &path::Path) -> Result<liquid::Value> {
bail!("yaml is unsupported");
}

#[cfg(feature = "serde_json")]
fn load_json(path: &path::Path) -> Result<liquid::Value> {
let f = fs::File::open(path)?;
serde_json::from_reader(f).map_err(|e| e.into())
}

#[cfg(not(feature = "serde_json"))]
fn load_json(path: &path::Path) -> Result<liquid::Value> {
bail!("json is unsupported");
}

fn build_context(path: &path::Path) -> Result<liquid::Context> {
let extension = path.extension().unwrap_or_else(|| ffi::OsStr::new(""));
let value = if extension == ffi::OsStr::new("yaml") {
load_yaml(path)
} else if extension == ffi::OsStr::new("yaml") {
load_json(path)
} else {
Err("Unsupported file type".into())
}?;
let value = match value {
liquid::Value::Object(o) => Ok(o),
_ => Err("File must be an object"),
}?;
let data = liquid::Context::with_values(value);

Ok(data)
}

fn run() -> Result<()> {
let matches = clap::App::new("liquidate").version(crate_version!())
.author(crate_authors!())
.arg(option("input", "LIQUID").required(true))
.arg(option("output", "TXT"))
.arg(option("context", "TOML"))
.arg(option("include-root", "PATH"))
.get_matches_safe()?;

let mut options = liquid::LiquidOptions::default();
options.file_system = matches.value_of("include-root").map(path::PathBuf::from);

let mut data = matches.value_of("context")
.map(|s| {
let p = path::PathBuf::from(s);
build_context(p.as_path())
})
.map_or(Ok(None), |r| r.map(Some))?
.unwrap_or_else(liquid::Context::new);

let template_path =
matches.value_of("input").map(path::PathBuf::from).expect("Parameter was required");
let template = liquid::parse_file(template_path, options)?;
let output = template.render(&mut data)?.unwrap_or_else(|| "".to_string());
match matches.value_of("output") {
Some(path) => {
let mut out = fs::File::create(path::PathBuf::from(path))?;
out.write_all(output.as_bytes())?;
}
None => {
println!("{}", output);
}
}

Ok(())
}

quick_main!(run);

0 comments on commit f9c82c7

Please sign in to comment.