use std::path::Path;
use crate::error::Result;
use crate::shell::{exec, exec_silent};
pub fn remove_worktree(path: &Path, force: bool) -> Result<()> {
let path_str = path.display().to_string();
let mut args = vec!["worktree", "remove"];
if force {
args.push("--force");
}
args.push(&path_str);
exec("git", &args, None)?;
Ok(())
}
pub fn delete_local_branch(branch: &str, force: bool) -> Result<()> {
let flag = if force { "-D" } else { "-d" };
exec("git", &["branch", flag, branch], None)?;
Ok(())
}
pub fn is_branch_merged(branch: &str, main_branches: &[String]) -> bool {
main_branches.iter().any(|main_branch| {
exec_silent(
"git",
&["merge-base", "--is-ancestor", branch, main_branch],
None,
)
.is_ok()
})
}
#[derive(Debug, Clone)]
pub struct RemoveResult {
pub path: String,
pub branch: String,
pub branch_deleted: bool,
pub error: Option<String>,
}
impl RemoveResult {
pub fn success(path: String, branch: String, branch_deleted: bool) -> Self {
Self {
path,
branch,
branch_deleted,
error: None,
}
}
pub fn failure(path: String, branch: String, error: impl Into<String>) -> Self {
Self {
path,
branch,
branch_deleted: false,
error: Some(error.into()),
}
}
pub fn is_success(&self) -> bool {
self.error.is_none()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_remove_result_success() {
let result = RemoveResult::success(
"/path/to/worktree".to_string(),
"feature/test".to_string(),
true,
);
assert!(result.is_success());
assert!(result.branch_deleted);
assert!(result.error.is_none());
}
#[test]
fn test_remove_result_failure() {
let result = RemoveResult::failure(
"/path/to/worktree".to_string(),
"feature/test".to_string(),
"worktree not found",
);
assert!(!result.is_success());
assert!(!result.branch_deleted);
assert_eq!(result.error, Some("worktree not found".to_string()));
}
#[test]
fn test_remove_result_with_empty_strings() {
let result = RemoveResult::success(String::new(), String::new(), false);
assert!(result.is_success());
assert!(result.path.is_empty());
assert!(result.branch.is_empty());
}
#[test]
fn test_remove_result_error_message_preserved() {
let error_msg = "Cannot remove worktree with uncommitted changes";
let result = RemoveResult::failure(
"/path/to/wt".to_string(),
"feature/test".to_string(),
error_msg,
);
assert!(!result.is_success());
assert_eq!(result.error, Some(error_msg.to_string()));
}
#[test]
fn test_remove_result_branch_deleted_true() {
let result = RemoveResult::success("/path".to_string(), "branch".to_string(), true);
assert!(result.branch_deleted);
}
#[test]
fn test_remove_result_branch_deleted_false() {
let result = RemoveResult::success("/path".to_string(), "branch".to_string(), false);
assert!(!result.branch_deleted);
}
}