1use anyhow::Result;
2use serde::Serialize;
3use std::path::Path;
4
5use crate::db;
6use crate::model::TaskId;
7use crate::ops;
8
9#[derive(Serialize)]
10struct RmResult {
11 requested_ids: Vec<String>,
12 deleted_ids: Vec<String>,
13 unblocked_ids: Vec<String>,
14}
15
16pub fn run(root: &Path, ids: &[String], recursive: bool, force: bool, json: bool) -> Result<()> {
17 let store = db::open(root)?;
18
19 let resolved: Vec<TaskId> = ids
20 .iter()
21 .map(|raw| db::resolve_task_id(&store, raw, false))
22 .collect::<Result<_>>()?;
23
24 let result = ops::soft_delete(&store, &resolved, recursive)?;
25
26 if !force && !result.unblocked_ids.is_empty() {
27 let short: Vec<String> = result
28 .unblocked_ids
29 .iter()
30 .map(ToString::to_string)
31 .collect();
32 eprintln!("warning: removed blockers from {}", short.join(", "));
33 }
34
35 if json {
36 let out = RmResult {
37 requested_ids: ids.to_vec(),
38 deleted_ids: result.deleted_ids.iter().map(ToString::to_string).collect(),
39 unblocked_ids: result
40 .unblocked_ids
41 .iter()
42 .map(ToString::to_string)
43 .collect(),
44 };
45 println!("{}", serde_json::to_string(&out)?);
46 } else {
47 let c = crate::color::stdout_theme();
48 for id in result.deleted_ids {
49 println!("{}deleted{} {id}", c.green, c.reset);
50 }
51 }
52
53 Ok(())
54}