use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
use crate::change::admits;
use crate::delivery_repo::Project;
use crate::encoding::percent_decode;
use crate::layout::Xdg;
#[must_use]
pub(crate) fn checkout_roots(invocation_path: &Path, needed: bool) -> Vec<String> {
if needed {
Project::at(invocation_path).root_commits()
} else {
Vec::new()
}
}
#[must_use]
pub(crate) fn is_foreign(root_commit: Option<&str>, this_roots: &[String]) -> bool {
root_commit.is_some() && !admits(root_commit, this_roots)
}
#[must_use]
pub(crate) fn row_label(labels: Option<&Labels>, root_commit: Option<&str>, this_roots: &[String]) -> String {
let (Some(labels), Some(root)) = (labels, root_commit) else { return String::new() };
if is_foreign(Some(root), this_roots) {
format!(" [{}]", labels.of(root))
} else {
String::new()
}
}
pub(crate) struct Labels {
by_root: HashMap<String, String>,
}
impl Labels {
#[must_use]
fn of(&self, root: &str) -> String {
self.by_root.get(root).cloned().unwrap_or_else(|| short(root))
}
}
fn short(root: &str) -> String {
root.chars().take(8).collect()
}
#[must_use]
pub(crate) fn enrolled_labels(xdg: &Xdg) -> Labels {
let mut by_root = HashMap::new();
let Ok(entries) = fs::read_dir(xdg.clones_dir()) else {
return Labels { by_root }; };
for entry in entries.flatten() {
let Some((path, basename)) = checkout_of(&entry.file_name()) else { continue };
if !path.exists() {
continue; }
for root in Project::at(&path).root_commits() {
by_root.entry(root).or_insert_with(|| basename.clone());
}
}
Labels { by_root }
}
fn checkout_of(entry_name: &std::ffi::OsStr) -> Option<(PathBuf, String)> {
let path = PathBuf::from(percent_decode(entry_name.to_str()?)?);
let basename = path.file_name()?.to_string_lossy().into_owned();
Some((path, basename))
}
#[cfg(test)]
#[path = "scope_tests.rs"]
mod tests;