use std::collections::{BTreeMap, BTreeSet};
use std::path::Path;
use anyhow::Result;
use crate::boards::{self, BoardRef};
use crate::checkout;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Targets {
pub repositories: BTreeMap<String, BTreeSet<String>>,
pub boards: BTreeSet<BoardRef>,
pub problems: Vec<String>,
}
impl Targets {
pub fn of(prj: &wsb_prj::Prj) -> Result<Self> {
let mut targets = Self::default();
for project in prj.projects()? {
match boards::read(&project) {
Ok(declared) => targets.boards.extend(declared.boards),
Err(error) => targets
.problems
.push(format!("{}: {error:#}", project.name())),
}
let worktrees = match project.worktrees() {
Ok(worktrees) => worktrees,
Err(error) => {
targets.problems.push(format!("{}: {error}", project.name()));
continue;
}
};
for worktree in worktrees {
let place = wsb_prj::Location {
project: project.clone(),
worktree: Some(worktree.name.clone()),
};
if let Err(error) = targets.add_checkout(&worktree.path) {
targets.problems.push(format!("{place}: {error:#}"));
}
}
}
Ok(targets)
}
pub fn add_checkout(&mut self, path: &Path) -> Result<()> {
for repository in checkout::repositories(path)? {
let commits = self.repositories.entry(repository.name).or_default();
if let Some(head) = repository.head {
commits.insert(head);
}
}
Ok(())
}
pub fn board_owners(&self) -> BTreeSet<String> {
self.boards.iter().map(|board| board.owner.clone()).collect()
}
}