use std::path::{Path, PathBuf};
use super::*;
use crate::workspace::Workspace;
pub(super) use crate::exec::block_on;
pub(super) use crate::fs::{CountingFs, StdFs};
pub(super) use crate::identity::{Id, Minter};
pub(super) use crate::index::FileIndex;
pub(super) fn tempdir(tag: &str) -> PathBuf {
let dir = std::env::temp_dir().join(format!("prov-history-{tag}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
dir
}
pub(super) fn write(dir: &Path, rel: &str, text: &str) {
let p = dir.join(rel);
std::fs::create_dir_all(p.parent().unwrap()).unwrap();
std::fs::write(p, text).unwrap();
}
pub(super) fn read(dir: &Path, rel: &str) -> String {
std::fs::read_to_string(dir.join(rel)).unwrap()
}
pub(super) fn ws(dir: &Path) -> Workspace<StdFs, Minter, FileIndex> {
Workspace::builder(StdFs)
.root(dir)
.identity(Minter::lazy(42))
.index(FileIndex::new(fig::Format::Yaml))
.history(crate::config::History::Manual)
.build()
}
pub(super) fn ws_history_off(dir: &Path) -> Workspace<StdFs, Minter, FileIndex> {
Workspace::builder(StdFs)
.root(dir)
.identity(Minter::lazy(42))
.index(FileIndex::new(fig::Format::Yaml))
.build()
}
pub(super) fn ws_authoring(
dir: &Path,
style: crate::document::EmbedStyle,
format: fig::Format,
) -> Workspace<StdFs, Minter, FileIndex> {
Workspace::builder(StdFs)
.root(dir)
.identity(Minter::lazy(42))
.index(FileIndex::new(format))
.history(crate::config::History::Manual)
.default_embed_format(format)
.embed_style(style)
.build()
}
pub(super) fn ws_counting(dir: &Path) -> (Workspace<CountingFs, Minter, FileIndex>, CountingFs) {
let fs = CountingFs::default();
let ws = Workspace::builder(fs.clone())
.root(dir)
.identity(Minter::lazy(42))
.index(FileIndex::new(fig::Format::Yaml))
.history(crate::config::History::Manual)
.build();
(ws, fs)
}
pub(super) fn seed(tag: &str) -> PathBuf {
let dir = tempdir(tag);
write(
&dir,
"index.md",
"---\ntitle: Home\ncontents:\n- notes/a.md\n- notes/photo.jpg.yaml\n---\nroot\n",
);
write(
&dir,
"notes/a.md",
"---\ntitle: A\npart_of: '../index.md'\n---\nalpha\n",
);
write(&dir, "notes/photo.jpg", "JPEGBYTES");
write(
&dir,
"notes/photo.jpg.yaml",
"title: Photo\npart_of: '../index.md'\ncontent: photo.jpg\n",
);
dir
}
pub(super) fn capture(dir: &Path, now: &str, label: Option<&str>) -> Captured {
block_on(ws(dir).history_capture(Path::new("index.md"), now, label)).unwrap()
}
pub(super) fn event_ids(dir: &Path) -> Vec<String> {
block_on(ws(dir).history_list(Path::new("index.md")))
.unwrap()
.into_iter()
.map(|e| e.id)
.collect()
}
pub(super) fn entry(path: &str, hash_of: &[u8]) -> FileEntry {
FileEntry {
path: PathBuf::from(path),
id: None,
hash: crate::fixity::digest(hash_of),
}
}
pub(super) fn tear(dir: &Path, rel: &str) {
let text = read(dir, rel);
let mangled = text.replacen("---\n", "---\n<<<<<<< ours\n=======\n>>>>>>> theirs\n", 1);
write(dir, rel, &mangled);
}
pub(super) fn blob_of(bytes: &[u8]) -> PathBuf {
blob_path(Path::new("history/index.md"), &crate::fixity::digest(bytes)).unwrap()
}
pub(super) fn capture_edited(dir: &Path, now: &str, label: &str, body: &str) -> String {
write(
dir,
"notes/a.md",
&format!("---\ntitle: A\npart_of: '../index.md'\n---\n{body}\n"),
);
match capture(dir, now, Some(label)) {
Captured::Written { id, .. } => id,
Captured::Unchanged { id } => panic!("expected a new event, got {id}"),
}
}
pub(super) fn relink_live(dir: &Path, contents: &[&str]) {
let list = contents
.iter()
.map(|c| format!("- {c}\n"))
.collect::<String>();
write(
dir,
"index.md",
&format!("---\ntitle: Home\nhistory: history/index.md\ncontents:\n{list}---\nroot\n"),
);
}