use log::debug;
use miette::{IntoDiagnostic, Result};
use workon::{get_repo, get_worktrees, WorktreeDescriptor};
use crate::cli::List;
use crate::display::{format_aligned_rows, worktree_display_row};
use crate::json::worktree_to_json;
use super::Run;
impl Run for List {
fn run(&self) -> Result<Option<WorktreeDescriptor>> {
if self.dirty && self.clean {
return Err(miette::miette!(
"Cannot specify both --dirty and --clean filters"
));
}
let repo = get_repo(None)?;
let worktrees = get_worktrees(&repo)?;
debug!("Found {} worktree(s)", worktrees.len());
let filtered: Vec<_> = worktrees
.into_iter()
.filter(|wt| self.matches_filters(wt))
.collect();
debug!("{} worktree(s) after filtering", filtered.len());
if self.json {
let json_array: Vec<_> = filtered.iter().map(worktree_to_json).collect();
let output = serde_json::to_string_pretty(&json_array).into_diagnostic()?;
println!("{}", output);
return Ok(None);
}
let root = workon::workon_root(&repo)?;
let current_dir = std::env::current_dir().into_diagnostic()?;
let rows: Vec<_> = filtered
.iter()
.filter_map(|wt| worktree_display_row(wt, root, ¤t_dir).ok())
.collect();
for line in format_aligned_rows(&rows, true) {
println!("{}", line);
}
Ok(None)
}
}
impl List {
fn matches_filters(&self, wt: &WorktreeDescriptor) -> bool {
if !self.dirty && !self.clean && !self.ahead && !self.behind && !self.gone {
return true;
}
if self.dirty && !wt.is_dirty().unwrap_or(false) {
return false;
}
if self.clean && wt.is_dirty().unwrap_or(true) {
return false;
}
if self.ahead && !wt.has_unpushed_commits().unwrap_or(false) {
return false;
}
if self.behind && !wt.is_behind_upstream().unwrap_or(false) {
return false;
}
if self.gone && !wt.has_gone_upstream().unwrap_or(false) {
return false;
}
true
}
}