use std::process::Command;
use super::super::Local;
use crate::{Issue, local::ConsensusSinkError, sink::Sink};
pub struct Consensus;
impl Sink<Consensus> for Issue {
type Error = ConsensusSinkError;
async fn sink(&mut self, _old: Option<&Issue>) -> Result<bool, Self::Error> {
let repo_info = self.repo_info();
let owner = repo_info.owner();
let repo = repo_info.repo();
let git_id = self.git_id().expect("calling this before having had linked the issue means invalid implementation somewhere");
let data_dir = Local::issues_dir();
let data_dir_str = data_dir.to_str().ok_or_else(ConsensusSinkError::new_invalid_data_dir)?;
let add_output = Command::new("git").args(["-C", data_dir_str, "add", "-A"]).output()?;
if !add_output.status.success() {
return Err(ConsensusSinkError::new_git_add(String::from_utf8_lossy(&add_output.stderr).into_owned()));
}
let project_dir = Local::project_dir(repo_info);
if let Ok(rel) = project_dir.strip_prefix(&data_dir) {
let check_ignored = Command::new("git").args(["-C", data_dir_str, "check-ignore", "--no-index", "-v"]).arg(rel.join("**")).output()?;
if check_ignored.status.success() && !check_ignored.stdout.is_empty() {
return Err(ConsensusSinkError::new_git_ignore_rejection(String::from_utf8_lossy(&check_ignored.stdout).into_owned()));
}
}
let diff_output = Command::new("git").args(["-C", data_dir_str, "diff", "--cached", "--quiet"]).status()?;
if diff_output.success() {
return Ok(false);
}
let commit_msg = format!("sync: {owner}/{repo}#{git_id}");
let commit_output = Command::new("git").args(["-C", data_dir_str, "commit", "-m", &commit_msg]).output()?;
if !commit_output.status.success() {
return Err(ConsensusSinkError::new_git_commit(String::from_utf8_lossy(&commit_output.stderr).into_owned()));
}
Ok(true)
}
}