From fec65b373ab11189b6091fea52adbffeebdfdc4b Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 15 Jun 2017 20:03:35 -0500 Subject: [PATCH] feat(debug): Dump intermediate state This is useful for - Seeing what variables are available - Isolate bugs to be either in cobalt or liquid --- Cargo.lock | 33 +++++++++++++++++++++++++++++++ Cargo.toml | 4 +++- src/cobalt.rs | 38 ++++++++++++++++++++++++++++++++++-- src/config.rs | 9 +++++++++ src/error.rs | 2 ++ src/lib.rs | 6 ++++++ src/main.rs | 54 ++++++++++++++++++++++++++++++++++++++++----------- 7 files changed, 132 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a17ec4e1..de1f04c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,8 @@ dependencies = [ "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rss 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_yaml 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntect 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -438,6 +440,16 @@ name = "libc" version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "linked-hash-map" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "linked-hash-map" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "liquid" version = "0.10.0" @@ -447,6 +459,7 @@ dependencies = [ "itertools 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -735,6 +748,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "serde" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "serde_derive" @@ -766,6 +782,17 @@ dependencies = [ "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_yaml" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "skeptic" version = "0.5.0" @@ -1020,6 +1047,9 @@ dependencies = [ name = "yaml-rust" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [metadata] "checksum RustyXML 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9222d58bccd9e6e3b82098a2ec142ad34e5d433de986d46cec03ad3a2b5fd529" @@ -1074,6 +1104,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e7eb6b826bfc1fdea7935d46556250d1799b7fe2d9f7951071f4291710665e3e" +"checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" +"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum liquid 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "010033be1c21a08b0f8e2cc4e002bd7fe759f1f64714c336a80f8a9065829f84" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" @@ -1112,6 +1144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3" "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" +"checksum serde_yaml 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49d983aa39d2884a4b422bb11bb38f4f48fa05186e17469bc31e47d01e381111" "checksum skeptic 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "061203a849117b0f7090baf8157aa91dac30545208fbb85166ac58b4ca33d89c" "checksum skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7d8dc1315094150052d0ab767840376335a98ac66ef313ff911cdf439a5b69" "checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" diff --git a/Cargo.toml b/Cargo.toml index b69865b4..12624c21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ doc = false [dependencies] clap = "2.24" -liquid = "0.10" +liquid = {version = "0.10", features=["serde"]} walkdir = "1.0" yaml-rust = "0.3" chrono = "0.3" @@ -39,6 +39,8 @@ error-chain = "0.10" lazy_static = "0.2" itertools = "0.5" ignore = "0.2" +serde = "1.0" +serde_yaml = "0.7" [dependencies.hyper] version = "0.10" diff --git a/src/cobalt.rs b/src/cobalt.rs index 8753bbe8..f9b7a352 100644 --- a/src/cobalt.rs +++ b/src/cobalt.rs @@ -3,14 +3,15 @@ use std::collections::HashMap; use std::io::Write; use std::path::Path; use std::ffi::OsStr; -use liquid::Value; +use liquid::{Value, Object}; use chrono::{UTC, FixedOffset}; use chrono::offset::TimeZone; use rss::{Channel, Rss}; +use serde_yaml; use document::Document; use error::{ErrorKind, Result}; -use config::Config; +use config::{Config, Dump}; use files::FilesBuilder; /// The primary build function that transforms a directory into a site @@ -151,6 +152,10 @@ pub fn build(config: &Config) -> Result<()> { } } + if config.dump.contains(&Dump::Liquid) { + create_liquid_dump(dest, &post.path, &post.content, &post.attributes)?; + } + let mut context = post.get_render_context(&simple_posts_data); try!(post.render_excerpt(&mut context, source, &config.excerpt_separator)); @@ -174,6 +179,10 @@ pub fn build(config: &Config) -> Result<()> { for mut doc in documents { trace!("Generating {}", doc.path); + if config.dump.contains(&Dump::Liquid) { + create_liquid_dump(dest, &doc.path, &doc.content, &doc.attributes)?; + } + let mut context = doc.get_render_context(&posts_data); let doc_html = try!(doc.render(&mut context, source, &layouts, &mut layouts_cache)); try!(create_document_file(&doc_html, &doc.path, dest)); @@ -216,6 +225,31 @@ pub fn build(config: &Config) -> Result<()> { Ok(()) } +fn create_liquid_dump(dest: &Path, path: &str, content: &str, attributes: &Object) -> Result<()> { + let mut liquid_file_path = dest.join(path); + let mut liquid_file_name = OsStr::new("_").to_os_string(); + { + let original_file_name = liquid_file_path.file_name().ok_or("File name missing")?; + liquid_file_name.push(original_file_name); + liquid_file_name.push(".liquid"); + } + liquid_file_path.set_file_name(liquid_file_name); + + let mut dump_file_path = liquid_file_path.clone(); + dump_file_path.set_extension(".yml"); + + info!("Dumping content at {}", liquid_file_path.display()); + let mut liquid_out = fs::File::create(liquid_file_path)?; + liquid_out.write_all(content.as_bytes())?; + + info!("Dumping attributes at {}", dump_file_path.display()); + let mut dump_out = fs::File::create(dump_file_path)?; + let values = serde_yaml::to_string(attributes)?; + dump_out.write_all(values.as_bytes())?; + + Ok(()) +} + // creates a new RSS file with the contents of the site blog fn create_rss(path: &str, dest: &Path, config: &Config, posts: &[Document]) -> Result<()> { match (&config.name, &config.description, &config.link) { diff --git a/src/config.rs b/src/config.rs index 41a2eac2..95e76013 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,6 +5,13 @@ use std::io::Read; use error::Result; use yaml_rust::YamlLoader; +arg_enum! { + #[derive(Debug, PartialEq)] + pub enum Dump { + Liquid + } +} + #[derive(Debug, PartialEq)] pub struct Config { pub source: String, @@ -22,6 +29,7 @@ pub struct Config { pub link: Option, pub ignore: Vec, pub excerpt_separator: String, + pub dump: Vec, } impl Default for Config { @@ -42,6 +50,7 @@ impl Default for Config { link: None, ignore: vec![], excerpt_separator: "\n\n".to_owned(), + dump: vec![], } } } diff --git a/src/error.rs b/src/error.rs index a30eee2a..92dca177 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,6 +4,7 @@ use yaml_rust::scanner; use walkdir; use liquid; use ignore; +use serde_yaml; error_chain! { @@ -15,6 +16,7 @@ error_chain! { Liquid(liquid::Error); WalkDir(walkdir::Error); Yaml(scanner::ScanError); + SerdeYaml(serde_yaml::Error); Ignore(ignore::Error); } diff --git a/src/lib.rs b/src/lib.rs index 4ec710f9..cf6a4911 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,8 @@ extern crate regex; extern crate rss; extern crate walkdir; extern crate yaml_rust; +extern crate serde; +extern crate serde_yaml; extern crate itertools; @@ -26,6 +28,9 @@ extern crate syntect; #[macro_use] extern crate log; +#[macro_use] +extern crate clap; + #[macro_use] extern crate error_chain; @@ -35,6 +40,7 @@ extern crate lazy_static; pub use cobalt::build; pub use error::Error; pub use config::Config; +pub use config::Dump; pub use new::{create_new_project, create_new_document}; pub mod error; diff --git a/src/main.rs b/src/main.rs index 8cbd56d8..08040da4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,20 +9,24 @@ ))] extern crate cobalt; -#[macro_use] -extern crate clap; extern crate env_logger; extern crate notify; extern crate ghp; extern crate hyper; +#[macro_use] +extern crate error_chain; + +#[macro_use] +extern crate clap; + #[macro_use] extern crate log; use clap::{Arg, App, SubCommand, AppSettings}; use std::fs; -use cobalt::Config; +use cobalt::{Config, Dump}; use log::{LogRecord, LogLevelFilter}; use env_logger::LogBuilder; use hyper::server::{Server, Request, Response}; @@ -38,7 +42,24 @@ use std::io::prelude::*; use std::io::Result as IoResult; use std::fs::File; -fn main() { +error_chain! { + + links { + } + + foreign_links { + Cobalt(cobalt::Error); + Notify(notify::Error); + Clap(clap::Error); + } + + errors { + } +} + +quick_main!(run); + +fn run() -> Result<()> { let global_matches = App::new("Cobalt") .version(crate_version!()) .author("Benny Klotz , Johann Hofmann") @@ -102,6 +123,13 @@ fn main() { .help("Suppress all output") .global(true) .takes_value(false)) + .arg(Arg::with_name("dump") + .long("dump") + .possible_values(&Dump::variants()) + .help("Dump the specified internal state") + .global(true) + .multiple(true) + .takes_value(true)) .subcommand(SubCommand::with_name("init") .about("create a new cobalt project") .arg(Arg::with_name("DIRECTORY") @@ -262,6 +290,12 @@ fn main() { config.include_drafts = matches.is_present("drafts"); + if global_matches.is_present("dump") { + let dump = values_t!(global_matches, "dump", Dump)?; + config.dump = dump; + info!("Setting: {:?}", config.dump); + } + match command { "init" => { let directory = matches.value_of("DIRECTORY").unwrap(); @@ -332,10 +366,7 @@ fn main() { match w { Ok(mut watcher) => { - // TODO: clean up this unwrap - watcher - .watch(&config.source, RecursiveMode::Recursive) - .unwrap(); + watcher.watch(&config.source, RecursiveMode::Recursive)?; info!("Watching {:?} for changes", &config.source); loop { @@ -367,10 +398,11 @@ fn main() { } _ => { - println!("{}", global_matches.usage()); - return; + bail!(global_matches.usage()); } - } + }; + + Ok(()) } fn build(config: &Config) {