Skip to main content

zenith_cli/commands/workspace/
finalize.rs

1//! Logic for `zenith workspace finalize`.
2
3use std::path::Path;
4
5use zenith_session::adapter::OsFs;
6use zenith_session::{FinalizeReport, StorePaths, finalize_candidates};
7
8use crate::commands::serialize_pretty;
9use crate::commands::workspace::scratch::open_store;
10use crate::history::read_doc_id;
11
12// ── View type for JSON output ─────────────────────────────────────────────────
13
14// FinalizeReport derives Serialize in zenith-session, so we use it directly.
15
16// ── finalize ──────────────────────────────────────────────────────────────────
17
18/// Apply each rejected candidate's cleanup-policy to the scratch store and
19/// return a human-readable or JSON report.
20pub fn finalize(doc_path: &Path, json: bool) -> Result<String, String> {
21    let paths = open_store()?;
22    finalize_in(&paths, doc_path, json)
23}
24
25/// Testable variant with an explicit store root.
26pub fn finalize_in(paths: &StorePaths, doc_path: &Path, json: bool) -> Result<String, String> {
27    let doc_id = read_doc_id(doc_path)?;
28    let fs = OsFs;
29    let report = finalize_candidates(&fs, paths, &doc_id).map_err(|e| e.message)?;
30
31    if json {
32        Ok(serialize_pretty(&report))
33    } else {
34        Ok(format_report(&report))
35    }
36}
37
38// ── formatting ────────────────────────────────────────────────────────────────
39
40fn format_report(report: &FinalizeReport) -> String {
41    if report.deleted.is_empty() {
42        format!(
43            "finalized: nothing to delete, {} candidate(s) kept",
44            report.kept
45        )
46    } else {
47        format!(
48            "finalized: deleted {} candidate(s) [{}], {} kept",
49            report.deleted.len(),
50            report.deleted.join(", "),
51            report.kept,
52        )
53    }
54}