Skip to main content

chronicle/cli/
context.rs

1use std::path::PathBuf;
2
3use crate::cli::ContextAction;
4use crate::error::chronicle_error::IoSnafu;
5use crate::error::Result;
6use crate::hooks::{
7    delete_pending_context, read_pending_context, write_pending_context, PendingContext,
8};
9use snafu::ResultExt;
10
11pub fn run(action: ContextAction) -> Result<()> {
12    let git_dir = find_git_dir()?;
13
14    match action {
15        ContextAction::Set {
16            task,
17            reasoning,
18            dependencies,
19            tags,
20        } => {
21            let ctx = PendingContext {
22                task,
23                reasoning,
24                dependencies,
25                tags,
26            };
27            write_pending_context(&git_dir, &ctx)?;
28            eprintln!("pending context saved");
29        }
30        ContextAction::Show => match read_pending_context(&git_dir)? {
31            Some(ctx) => {
32                println!("{}", serde_json::to_string_pretty(&ctx).unwrap_or_default());
33            }
34            None => {
35                eprintln!("no pending context");
36            }
37        },
38        ContextAction::Clear => {
39            delete_pending_context(&git_dir)?;
40            eprintln!("pending context cleared");
41        }
42    }
43
44    Ok(())
45}
46
47/// Find the .git directory by running `git rev-parse --git-dir`.
48fn find_git_dir() -> Result<PathBuf> {
49    let output = std::process::Command::new("git")
50        .args(["rev-parse", "--git-dir"])
51        .output()
52        .context(IoSnafu)?;
53
54    if output.status.success() {
55        let dir = String::from_utf8_lossy(&output.stdout).trim().to_string();
56        let path = PathBuf::from(&dir);
57        if path.is_relative() {
58            let cwd = std::env::current_dir().context(IoSnafu)?;
59            Ok(cwd.join(path))
60        } else {
61            Ok(path)
62        }
63    } else {
64        let cwd = std::env::current_dir().context(IoSnafu)?;
65        Err(crate::error::chronicle_error::NotARepositorySnafu { path: cwd }.build())
66    }
67}