Skip to main content

opys_engine/commands/
cleanup.rs

1//! `opys cleanup` — strip struck-through (closed) references from every
2//! document. After this the closed documents have no remaining record except
3//! git history.
4
5use crate::commands::maybe_sync;
6use crate::error::Result;
7use crate::frontmatter::Frontmatter;
8use crate::{refs, Ctx};
9
10pub fn run(ctx: &Ctx) -> Result<()> {
11    let prj = ctx.open()?;
12    let (mut store, _) = ctx.load(&prj)?;
13    let mut changed = 0usize;
14    for (dkey, mut doc) in store.all_docs()? {
15        if strip_struck(&mut doc.frontmatter) {
16            store.put_doc(&prj.pcfg, Some(dkey), &doc)?;
17            changed += 1;
18        }
19    }
20    ctx.flush(&prj, store)?;
21    println!("cleanup: removed struck references from {changed} doc(s)");
22    maybe_sync(ctx, &prj);
23    Ok(())
24}
25
26fn strip_struck(fm: &mut Frontmatter) -> bool {
27    let mut changed = false;
28    for field in refs::RELATION_FIELDS {
29        let entries = refs::parse_in(fm, field);
30        let kept: Vec<_> = entries
31            .iter()
32            .filter(|(_, v)| !refs::is_struck(v))
33            .cloned()
34            .collect();
35        if kept.len() != entries.len() {
36            refs::set_in(fm, field, &kept);
37            changed = true;
38        }
39    }
40    changed
41}