init: frontmatter imports

This commit is contained in:
Johannes Kirschbauer 2024-03-20 19:11:26 +01:00
parent 3b5b6b47ca
commit 46c82bac34
No known key found for this signature in database
10 changed files with 105 additions and 3 deletions

25
pesto/Cargo.lock generated
View File

@ -628,9 +628,10 @@ dependencies = [
"serde",
"serde_json",
"serde_with",
"serde_yaml",
"serde_yaml 0.9.27",
"textwrap",
"walkdir",
"yaml-front-matter",
]
[[package]]
@ -843,6 +844,18 @@ dependencies = [
"syn 2.0.39",
]
[[package]]
name = "serde_yaml"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
"indexmap 1.9.3",
"ryu",
"serde",
"yaml-rust",
]
[[package]]
name = "serde_yaml"
version = "0.9.27"
@ -1288,6 +1301,16 @@ version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
[[package]]
name = "yaml-front-matter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a94fb32d2b438e3fddf901fbfe9eb87b34d63853ca6c6da5d2ab7e27031e0bae"
dependencies = [
"serde",
"serde_yaml 0.8.26",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"

View File

@ -23,6 +23,7 @@ expect-test = "1.4.0"
serde_with = "3.4.0"
serde_yaml = "0.9.27"
comrak = "0.20.0"
yaml-front-matter = "0.1.0"
# [dev-dependencies]

View File

@ -1,7 +1,12 @@
#[cfg(test)]
mod tests {
use serde::Serialize;
use std::{collections::HashMap, ffi::OsStr, format, fs, path::PathBuf, println, rc::Rc};
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap, ffi::OsStr, format, fs, path::PathBuf, println, process::Command,
rc::Rc,
};
use yaml_front_matter::{Document as MdDocument, YamlFrontMatter};
use crate::{
bulk::BulkProcessing,
@ -167,4 +172,57 @@ mod tests {
serde_json::to_string_pretty(&data.docs[0..10]).unwrap()
})
}
fn find_repo_root() -> Option<PathBuf> {
let output = Command::new("git")
.args(&["rev-parse", "--show-toplevel"])
.output()
.ok()?
.stdout;
let path_str = String::from_utf8(output).ok()?.trim().to_string();
Some(PathBuf::from(path_str))
}
#[test]
fn test_frontmatter() {
dir_tests("frontmatter", "md", |path| {
#[derive(Deserialize, Serialize, Debug)]
struct Meta {
#[serde(flatten)]
content: HashMap<String, serde_yaml::Value>,
}
let markdown = fs::read_to_string(&path).unwrap();
let document: MdDocument<Meta> = YamlFrontMatter::parse(&markdown).unwrap();
// Access the metadata
let metadata = document.metadata.content;
let final_import: PathBuf = if let Some(field) = metadata.get("import") {
let imported = field
.as_str()
.expect("Error: import field must be a string");
match PathBuf::from(imported).is_relative() {
true => PathBuf::from_iter(vec![
// Cannot fail because every file has a parent directory
path.parent().unwrap().to_path_buf(),
PathBuf::from(imported),
]),
false => PathBuf::from_iter(vec![
find_repo_root().expect("Could not find root directoy of repository. Make sure you have git installed and are in a git repository"),
PathBuf::from(format!(".{imported}")),
]),
}
} else {
// This should never panic
// It is only here for testing purposes
panic!("No import found");
};
let actual = fs::read_to_string(&final_import)
.expect(format!("Could not read file: {:?}", &final_import).as_str());
serde_json::to_string_pretty(&actual).unwrap()
})
}
}

View File

@ -0,0 +1 @@
"# Some imported docs"

View File

@ -0,0 +1,6 @@
---
import: /pesto/test_data/frontmatter/import.file
---
# Some docs

View File

@ -0,0 +1 @@
# Some imported docs

View File

@ -0,0 +1 @@
"# Some imported docs"

View File

@ -0,0 +1,5 @@
---
import: ./import.file
---
# Some docs

View File

@ -0,0 +1 @@
"# Some imported docs"

View File

@ -0,0 +1,5 @@
---
import: import.file
---
# Some docs