use crate::commands::{Command, CommandResult};
use crate::services::GitService;
use crate::app::{AppState, Action, reducer};
use crate::errors::CommandError;
use tracing::instrument;
pub struct ListMergedBranchesCommand {
pub base: String,
}
impl Command for ListMergedBranchesCommand {
#[instrument(skip(self, git, state), fields(base = %self.base))]
fn execute(
&self,
git: &GitService,
state: &AppState,
) -> Result<CommandResult, CommandError> {
let mut new_state = state.clone();
new_state = reducer(new_state, Action::SetOpStatus(Some(format!("listing merged into {}…", self.base))));
match git.merged_local_branches(&state.repo_path, &self.base) {
Ok(list) => {
if list.is_empty() {
new_state = reducer(new_state, Action::AppendOpLog(format!("no merged branches into {}", self.base)));
new_state = reducer(new_state, Action::SetFeedback(Some("No merged branches".into())));
} else {
new_state = reducer(new_state, Action::AppendOpLog(format!("merged into {}:", self.base)));
for b in list {
new_state = reducer(new_state, Action::AppendOpLog(format!(" {}", b)));
}
}
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("merged list error: {e}")));
new_state = reducer(new_state, Action::SetStatusError(Some(format!("merged list error: {e}"))));
}
}
new_state = reducer(new_state, Action::SetOpStatus(None));
Ok(CommandResult::StateUpdate(new_state))
}
}
pub struct PruneMergedBranchesCommand {
pub base: String,
}
impl Command for PruneMergedBranchesCommand {
#[instrument(skip(self, git, state), fields(base = %self.base))]
fn execute(
&self,
git: &GitService,
state: &AppState,
) -> Result<CommandResult, CommandError> {
let mut new_state = state.clone();
new_state = reducer(new_state, Action::SetOpStatus(Some(format!("pruning merged into {}…", self.base))));
match git.merged_local_branches(&state.repo_path, &self.base) {
Ok(list) => {
if list.is_empty() {
new_state = reducer(new_state, Action::AppendOpLog(format!("no merged branches into {}", self.base)));
new_state = reducer(new_state, Action::SetFeedback(Some("No merged branches".into())));
} else {
let mut pruned = 0;
for b in list {
match git.delete_local_branch(&state.repo_path, &b) {
Ok(_) => {
pruned += 1;
new_state = reducer(new_state, Action::AppendOpLog(format!("deleted {}", b)));
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("delete {} failed: {e}", b)));
}
}
}
new_state = reducer(new_state, Action::SetFeedback(Some(format!("Pruned {} branch(es)", pruned))));
new_state = reducer(new_state, Action::SetRefreshing(true));
}
}
Err(e) => {
new_state = reducer(new_state, Action::AppendOpLog(format!("prune error: {e}")));
new_state = reducer(new_state, Action::SetStatusError(Some(format!("prune error: {e}"))));
}
}
new_state = reducer(new_state, Action::SetOpStatus(None));
Ok(CommandResult::StateUpdate(new_state))
}
}