1use anyhow::Result;
2use std::path::Path;
3
4use crate::cli::DepAction;
5use crate::db;
6
7pub fn run(root: &Path, action: &DepAction, json: bool) -> Result<()> {
8 let conn = db::open(root)?;
9
10 match action {
11 DepAction::Add { child, parent } => {
12 conn.execute(
13 "INSERT OR IGNORE INTO blockers (task_id, blocker_id) VALUES (?1, ?2)",
14 [child, parent],
15 )?;
16 conn.execute(
17 "UPDATE tasks SET updated = ?1 WHERE id = ?2",
18 rusqlite::params![db::now_utc(), child],
19 )?;
20 if json {
21 println!("{}", serde_json::json!({"child": child, "blocker": parent}));
22 } else {
23 let c = crate::color::stdout_theme();
24 println!(
25 "{}{child}{} blocked by {}{parent}{}",
26 c.green, c.reset, c.yellow, c.reset
27 );
28 }
29 }
30 DepAction::Rm { child, parent } => {
31 conn.execute(
32 "DELETE FROM blockers WHERE task_id = ?1 AND blocker_id = ?2",
33 [child, parent],
34 )?;
35 conn.execute(
36 "UPDATE tasks SET updated = ?1 WHERE id = ?2",
37 rusqlite::params![db::now_utc(), child],
38 )?;
39 if !json {
40 let c = crate::color::stdout_theme();
41 println!(
42 "{}{child}{} no longer blocked by {}{parent}{}",
43 c.green, c.reset, c.yellow, c.reset
44 );
45 }
46 }
47 DepAction::Tree { id } => {
48 println!("{id}");
49 let mut stmt = conn.prepare("SELECT id FROM tasks WHERE parent = ?1 ORDER BY id")?;
50 let children: Vec<String> = stmt
51 .query_map([id], |r| r.get(0))?
52 .collect::<rusqlite::Result<_>>()?;
53 for child in &children {
54 println!(" {child}");
55 }
56 }
57 }
58
59 Ok(())
60}