use isoloom_spec::model::{Machine, Spec};
#[must_use]
pub fn init_names(name: &str, m: &Machine) -> Vec<String> {
let n = m.docker.as_ref().map_or(0, |d| d.init.len());
(1..=n).map(|i| format!("{name}-init-{i}")).collect()
}
#[must_use]
pub fn leaf_jobs(spec: &Spec) -> Vec<String> {
let waited_for = |name: &str| spec.machines.values().any(|o| o.docker.is_some() && o.depends_on.iter().any(|d| d == name));
spec.machines
.iter()
.filter(|(name, m)| m.docker.is_some() && !waited_for(name))
.flat_map(|(name, m)| init_names(name, m))
.collect()
}
#[must_use]
pub fn start_commands(compose: &str, jobs: &[String], wait_timeout: Option<u32>) -> String {
let timeout = wait_timeout.map(|t| format!(" --wait-timeout {t}")).unwrap_or_default();
if jobs.is_empty() {
return format!("{compose} up -d --build --wait{timeout}");
}
let exclude: String = jobs.iter().map(|j| format!(" -e {j}")).collect::<Vec<_>>().concat();
let attached: String = jobs
.iter()
.map(|j| format!(" && {compose} up --no-deps --exit-code-from {j} {j}"))
.collect::<Vec<_>>()
.concat();
let services = as_arguments(&format!("{compose} config --services | grep -vx{exclude}"));
format!("{{ {services}; }} && {compose} up -d --build --wait{timeout} \"$@\"{attached}")
}
#[must_use]
pub fn as_arguments(listing: &str) -> String {
format!("set --; for w in $({listing}); do set -- \"$@\" \"$w\"; done")
}