shtola

ssg in rust
git clone https://tilde.team/~marisa/repo/shtola.git
Log | Files | Refs | LICENSE

commit d33916984fa73979b58d83294dbc5e2b049a2378
parent 8711e830338ae1fb1479cd0d2ed33cd865083ffe
Author: marisa <mokou@posteo.de>
Date:   Mon, 11 Nov 2019 21:12:50 +0100

Add metadata implementation

Diffstat:
MCargo.lock | 30++++++++++++++++++++++++++++++
Mshtola/Cargo.toml | 1+
Mshtola/src/lib.rs | 105+++++--------------------------------------------------------------------------
Ashtola/src/tests.rs | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 165 insertions(+), 99 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -49,6 +49,11 @@ dependencies = [ ] [[package]] +name = "itoa" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -101,6 +106,11 @@ dependencies = [ ] [[package]] +name = "ryu" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "same-file" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -122,6 +132,21 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "serde" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_json" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "shtola" version = "0.1.0" dependencies = [ @@ -129,6 +154,7 @@ dependencies = [ "im 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pathdiff 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "ware 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -216,6 +242,7 @@ dependencies = [ "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" "checksum im 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8db49f8bc08d5cc4e2bb0f7d25a6d1db2c79bc6f7d7c86c96c657eb3d214125f" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" @@ -224,9 +251,12 @@ dependencies = [ "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" +"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" "checksum sized-chunks 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f01db57d7ee89c8e053245deb77040a6cc8508311f381c88749c33d4b9b78785" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" diff --git a/shtola/Cargo.toml b/shtola/Cargo.toml @@ -18,3 +18,4 @@ im = "13.0.0" yaml-rust = "0.4.3" pathdiff = "0.1.0" globset = "0.4.4" +serde_json = "1.0.41" diff --git a/shtola/src/lib.rs b/shtola/src/lib.rs @@ -9,8 +9,12 @@ use walkdir::WalkDir; pub use im::HashMap; pub use ware::Ware; pub use yaml_rust::Yaml; +pub use serde_json::Value; +pub use serde_json as json; mod frontmatter; +#[cfg(test)] +mod tests; pub struct Shtola { ware: Ware<IR>, @@ -23,6 +27,7 @@ impl Shtola { let ir = IR { files: HashMap::new(), config, + metadata: HashMap::new(), }; Shtola { ware: Ware::new(), @@ -85,6 +90,7 @@ impl Shtola { pub struct IR { files: HashMap<PathBuf, ShFile>, config: Config, + metadata: HashMap<String, Value>, } #[derive(Debug, Clone)] @@ -156,102 +162,3 @@ fn write_dir(ir: IR, dest: &PathBuf) -> Result<(), std::io::Error> { } Ok(()) } - -#[test] -fn read_works() { - let mut s = Shtola::new(); - s.source("../fixtures/simple"); - s.destination("../fixtures/dest_read"); - let r = s.build().unwrap(); - assert_eq!(r.files.len(), 1); - let keys: Vec<&PathBuf> = r.files.keys().collect(); - assert_eq!(keys[0].to_str().unwrap(), "hello.txt"); -} - -#[test] -fn clean_works() { - let mut s = Shtola::new(); - s.source("../fixtures/simple"); - s.destination("../fixtures/dest_clean"); - s.clean(true); - fs::create_dir_all("../fixtures/dest_clean").unwrap(); - fs::write("../fixtures/dest_clean/blah.foo", "").unwrap(); - s.build().unwrap(); - let fpath = PathBuf::from("../fixtures/dest_clean/blah.foo"); - assert_eq!(fpath.exists(), false); -} - -#[test] -fn write_works() { - let mut s = Shtola::new(); - s.source("../fixtures/simple"); - s.destination("../fixtures/dest_write"); - s.clean(true); - let mw = Box::new(|ir: IR| { - let mut update_hash: HashMap<PathBuf, ShFile> = HashMap::new(); - for (k, v) in &ir.files { - update_hash.insert( - k.into(), - ShFile { - frontmatter: v.frontmatter.clone(), - content: "hello".into(), - }, - ); - } - IR { - files: update_hash.union(ir.files), - ..ir - } - }); - s.register(mw); - s.build().unwrap(); - let dpath = PathBuf::from("../fixtures/dest_write/hello.txt"); - assert!(dpath.exists()); - let file = &fs::read(dpath).unwrap(); - let fstring = String::from_utf8_lossy(file); - assert_eq!(fstring, "hello"); -} - -#[test] -fn frontmatter_works() { - let mut s = Shtola::new(); - s.source("../fixtures/frontmatter"); - s.destination("../fixtures/dest_matter1"); - s.clean(true); - let r = s.build().unwrap(); - let (_, matter_file) = r.files.iter().last().unwrap(); - let frontmatter = matter_file.frontmatter[0] - .as_hash() - .unwrap() - .get(&Yaml::from_str("hello")) - .unwrap() - .as_str() - .unwrap(); - assert_eq!(frontmatter, "bro"); -} - -#[test] -fn no_frontmatter_works() { - let mut s = Shtola::new(); - s.source("../fixtures/frontmatter"); - s.destination("../fixtures/dest_matter2"); - s.clean(true); - s.frontmatter(false); - let r = s.build().unwrap(); - let (_, matter_file) = r.files.iter().last().unwrap(); - dbg!(matter_file); - assert!(matter_file.frontmatter.is_empty()); -} - -#[test] -fn ignore_works() { - let mut s = Shtola::new(); - s.source("../fixtures/ignore"); - s.destination("../fixtures/dest_ignore"); - s.ignores(&mut vec!["ignored.md".to_string()]); - s.clean(true); - let r = s.build().unwrap(); - assert_eq!(r.files.len(), 1); - let (path, _) = r.files.iter().last().unwrap(); - assert_eq!(path.to_str().unwrap(), "not_ignored.md"); -} diff --git a/shtola/src/tests.rs b/shtola/src/tests.rs @@ -0,0 +1,128 @@ +use crate::{Shtola, IR, HashMap, ShFile, Yaml}; +use crate::json::json; +use std::path::PathBuf; +use std::fs; + +#[test] +fn read_works() { + let mut s = Shtola::new(); + s.source("../fixtures/simple"); + s.destination("../fixtures/dest_read"); + let r = s.build().unwrap(); + assert_eq!(r.files.len(), 1); + let keys: Vec<&PathBuf> = r.files.keys().collect(); + assert_eq!(keys[0].to_str().unwrap(), "hello.txt"); +} + +#[test] +fn clean_works() { + let mut s = Shtola::new(); + s.source("../fixtures/simple"); + s.destination("../fixtures/dest_clean"); + s.clean(true); + fs::create_dir_all("../fixtures/dest_clean").unwrap(); + fs::write("../fixtures/dest_clean/blah.foo", "").unwrap(); + s.build().unwrap(); + let fpath = PathBuf::from("../fixtures/dest_clean/blah.foo"); + assert_eq!(fpath.exists(), false); +} + +#[test] +fn write_works() { + let mut s = Shtola::new(); + s.source("../fixtures/simple"); + s.destination("../fixtures/dest_write"); + s.clean(true); + let mw = Box::new(|ir: IR| { + let mut update_hash: HashMap<PathBuf, ShFile> = HashMap::new(); + for (k, v) in &ir.files { + update_hash.insert( + k.into(), + ShFile { + frontmatter: v.frontmatter.clone(), + content: "hello".into(), + }, + ); + } + IR { + files: update_hash.union(ir.files), + ..ir + } + }); + s.register(mw); + s.build().unwrap(); + let dpath = PathBuf::from("../fixtures/dest_write/hello.txt"); + assert!(dpath.exists()); + let file = &fs::read(dpath).unwrap(); + let fstring = String::from_utf8_lossy(file); + assert_eq!(fstring, "hello"); +} + +#[test] +fn frontmatter_works() { + let mut s = Shtola::new(); + s.source("../fixtures/frontmatter"); + s.destination("../fixtures/dest_matter1"); + s.clean(true); + let r = s.build().unwrap(); + let (_, matter_file) = r.files.iter().last().unwrap(); + let frontmatter = matter_file.frontmatter[0] + .as_hash() + .unwrap() + .get(&Yaml::from_str("hello")) + .unwrap() + .as_str() + .unwrap(); + assert_eq!(frontmatter, "bro"); +} + +#[test] +fn no_frontmatter_works() { + let mut s = Shtola::new(); + s.source("../fixtures/frontmatter"); + s.destination("../fixtures/dest_matter2"); + s.clean(true); + s.frontmatter(false); + let r = s.build().unwrap(); + let (_, matter_file) = r.files.iter().last().unwrap(); + dbg!(matter_file); + assert!(matter_file.frontmatter.is_empty()); +} + +#[test] +fn ignore_works() { + let mut s = Shtola::new(); + s.source("../fixtures/ignore"); + s.destination("../fixtures/dest_ignore"); + s.ignores(&mut vec!["ignored.md".to_string()]); + s.clean(true); + let r = s.build().unwrap(); + assert_eq!(r.files.len(), 1); + let (path, _) = r.files.iter().last().unwrap(); + assert_eq!(path.to_str().unwrap(), "not_ignored.md"); +} + + +#[test] +fn metadata_works() { + let mut s = Shtola::new(); + s.source("../fixtures/simple"); + s.destination("../fixtures/dest_meta"); + s.clean(true); + let mw1 = Box::new(|ir: IR| { + let metadata = ir.metadata.update("test".into(), json!("foo")) + .update("test2".into(), json!({"bar": "baz"})); + IR { metadata, ..ir } + }); + + let mw2 = Box::new(|ir: IR| { + let metadata = ir.metadata.update("test".into(), json!(["a", "b", "c"])); + IR { metadata, ..ir } + }); + + s.register(mw1); + s.register(mw2); + let r = s.build().unwrap(); + assert_eq!(r.metadata.get("test").unwrap(), &json!(["a", "b", "c"])); + assert_eq!(r.metadata.get("test2").unwrap(), &json!({"bar": "baz"})); +}