use std::path::Path;
use crate::fleet::{Verb, arming};
use crate::opslog::{self, OpEntry, Origin};
use super::dispatch::Deps;
use super::reply::Reply;
const ARM_STEP: &str = "arm-fleet";
const DISARM_STEP: &str = "disarm-fleet";
pub(super) fn dispatch(
deps: &Deps,
ts: &str,
workspace: &Path,
verb: &Verb,
) -> Result<Reply, String> {
match verb {
Verb::Arm { project, cap, .. } => {
let repo = deps.snapshot.project_path(project)?;
arm(deps, ts, workspace, Some((repo.as_path(), *cap)))
}
Verb::Disarm { .. } => arm(deps, ts, workspace, None),
}
}
fn arm(
deps: &Deps,
ts: &str,
workspace: &Path,
policy: Option<(&Path, usize)>,
) -> Result<Reply, String> {
let path = deps.state_root.join(crate::app::cadence::CADENCE_YAML);
let before = std::fs::read_to_string(&path).unwrap_or_default();
let key = crate::nav::ws_key(workspace);
let after = match policy {
Some((project, cap)) => arming::arm(&before, &key, &crate::nav::ws_key(project), cap)
.ok_or_else(|| {
format!(
"{}: fleet: carries an inline value; edit it by hand and try again",
crate::app::cadence::CADENCE_YAML
)
})?,
None => arming::disarm(&before, &key),
};
std::fs::create_dir_all(&deps.state_root).map_err(|e| e.to_string())?;
std::fs::write(&path, after).map_err(|e| e.to_string())?;
let step = if policy.is_some() {
ARM_STEP
} else {
DISARM_STEP
};
let done = OpEntry::step_done(
ts.to_owned(),
step,
key,
Origin::Balls,
deps.caller.client.clone(),
);
opslog::append(&deps.state_root, &done).map_err(|e| e.to_string())?;
Ok(Reply::Armed {
armed: policy.is_some(),
})
}
#[cfg(test)]
mod tests;