use std::collections::BTreeSet;
use std::path::{Path, PathBuf};
use cabin_workspace::{PackageGraph, PackageSelection, SelectionMode};
pub(crate) fn package_selection_from_flags(
workspace: bool,
packages: &[String],
default_members: bool,
) -> PackageSelection {
let mode = if workspace {
SelectionMode::WholeWorkspace
} else if !packages.is_empty() {
SelectionMode::ExplicitPackages(packages.to_vec())
} else if default_members {
SelectionMode::DefaultMembers
} else {
SelectionMode::CurrentPackage
};
PackageSelection {
mode,
exclude: Vec::new(),
}
}
pub(crate) fn nested_package_excludes(
graph: &PackageGraph,
selected: &BTreeSet<usize>,
) -> Vec<PathBuf> {
let mut out: Vec<PathBuf> = Vec::new();
for (idx, pkg) in graph.packages.iter().enumerate() {
if selected.contains(&idx) {
continue;
}
out.push(pkg.manifest_dir.clone());
}
out
}
pub(crate) fn describe_packages(names: &[String]) -> String {
match names.len() {
0 => "<no package selected>".to_owned(),
1 => format!("package `{}`", names[0]),
_ => {
let joined = names
.iter()
.map(|n| format!("`{n}`"))
.collect::<Vec<_>>()
.join(", ");
format!("packages {joined}")
}
}
}
pub(crate) fn absolutize(base: &Path, path: &Path) -> PathBuf {
if path.is_absolute() {
path.to_path_buf()
} else {
base.join(path)
}
}
pub(crate) fn display_workspace_relative(workspace_root: &Path, path: &Path) -> String {
path.strip_prefix(workspace_root).map_or_else(
|_| path.to_string_lossy().into_owned(),
|rel| rel.to_string_lossy().into_owned(),
)
}