use std::{ env, fs::{self, read_to_string, File, OpenOptions}, io::Write, process::Command, }; use anyhow::{bail, Context, Result}; use crate::{cli::NeorgCommand, state::State}; pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> { match command { NeorgCommand::Task { id } => { let project = id.project(state)?; let base = dirs::data_local_dir() .expect("This should exists") .join("tskm/notes"); let path = base.join(project.get_neorg_path()?); fs::create_dir_all(path.parent().expect("This should exist"))?; { let contents = if path.exists() { read_to_string(&path) .with_context(|| format!("Failed to read file: '{}'", path.display()))? } else { File::create(&path) .with_context(|| format!("Failed to create file: '{}'", path.display()))?; String::new() }; if !contents.contains(format!("% {}", id.uuid()).as_str()) { let mut options = OpenOptions::new(); options.append(true).create(false); let mut file = options.open(&path)?; file.write_all(format!("* TITLE (% {})", id.uuid()).as_bytes()) .with_context(|| { format!("Failed to write task uuid to file: '{}'", path.display()) })?; file.flush() .with_context(|| format!("Failed to flush file: '{}'", path.display()))?; } } let editor = env::var("EDITOR").unwrap_or("nvim".to_owned()); let status = Command::new(editor) .args([ path.to_str().expect("Should be a utf-8 str"), "-c", format!("/% {}", id.uuid()).as_str(), ]) .status()?; if !status.success() { bail!("$EDITOR fail with error code: {status}"); } { let status = Command::new("git") .args(["add", "."]) .current_dir(path.parent().expect("Will exist")) .status()?; if !status.success() { bail!("Git add . failed!"); } let status = Command::new("git") .args([ "commit", "--message", format!("chore({}): Update", project.get_neorg_path()?.display()).as_str(), "--no-gpg-sign", ]) .current_dir(path.parent().expect("Will exist")) .status()?; if !status.success() { bail!("Git commit failed!"); } } { id.mark_neorg_data(state)?; } } } Ok(()) }