use thor_core::{find_repo, list_worktrees};
use std::process::Command;
pub enum PullStatus {
Ok,
Failed(String),
Skipped,
}
pub struct PullResult {
pub branch: String,
pub status: PullStatus,
}
pub async fn pull(all: bool) -> anyhow::Result<Vec<PullResult>> {
if !all {
let output = Command::new("git")
.args(["pull", "--rebase"])
.output()?;
let branch = Command::new("git")
.args(["branch", "--show-current"])
.output()
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
.unwrap_or_else(|_| "unknown".to_string());
let status = if output.status.success() {
PullStatus::Ok
} else {
PullStatus::Failed(String::from_utf8_lossy(&output.stderr).trim().to_string())
};
return Ok(vec![PullResult { branch, status }]);
}
let repo = find_repo()?;
let worktrees = list_worktrees(&repo).await?;
let mut results = Vec::new();
for wt in &worktrees {
let branch = wt.display_name();
let has_upstream = Command::new("git")
.args(["rev-parse", "--abbrev-ref", "@{u}"])
.current_dir(&wt.path)
.output()
.map(|o| o.status.success())
.unwrap_or(false);
if !has_upstream {
results.push(PullResult { branch, status: PullStatus::Skipped });
continue;
}
let output = Command::new("git")
.args(["pull", "--rebase"])
.current_dir(&wt.path)
.output()?;
let status = if output.status.success() {
PullStatus::Ok
} else {
PullStatus::Failed(String::from_utf8_lossy(&output.stderr).trim().to_string())
};
results.push(PullResult { branch, status });
}
Ok(results)
}