#![allow(dead_code)]
use std::path::{Path, PathBuf};
use std::process::Command;
pub fn forjar() -> Command {
Command::new(env!("CARGO_BIN_EXE_forjar"))
}
pub fn combined(out: &std::process::Output) -> String {
format!(
"{}{}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
)
}
pub struct Project {
pub cfg: PathBuf,
pub state: PathBuf,
pub alpha: PathBuf,
pub bravo: PathBuf,
}
pub fn project(dir: &Path) -> Project {
let alpha = dir.join("alpha.txt");
let bravo = dir.join("bravo.txt");
let cfg = dir.join("forjar.yaml");
std::fs::write(
&cfg,
format!(
"version: \"1.0\"\n\
name: partial\n\
machines:\n\
\x20 web:\n\
\x20 hostname: localhost\n\
\x20 addr: 127.0.0.1\n\
resources:\n\
\x20 alpha:\n\
\x20 type: file\n\
\x20 machine: web\n\
\x20 path: {}\n\
\x20 content: \"A\"\n\
\x20 tags: [t_alpha]\n\
\x20 resource_group: ga\n\
\x20 bravo:\n\
\x20 type: file\n\
\x20 machine: web\n\
\x20 path: {}\n\
\x20 content: \"B\"\n\
\x20 tags: [t_bravo]\n\
\x20 resource_group: gb\n",
alpha.display(),
bravo.display()
),
)
.expect("write config");
Project {
cfg,
state: dir.join("state"),
alpha,
bravo,
}
}
impl Project {
pub fn plan(&self, out: &Path, extra: &[&str]) -> std::process::Output {
forjar()
.args(["plan", "-f"])
.arg(&self.cfg)
.arg("--state-dir")
.arg(&self.state)
.args(extra)
.arg("--out")
.arg(out)
.output()
.expect("run plan")
}
pub fn save_plan(&self, out: &Path) {
let o = self.plan(out, &[]);
assert!(o.status.success(), "plan --out: {}", combined(&o));
}
pub fn apply_plan(&self, plan: &Path, extra: &[&str]) -> std::process::Output {
forjar()
.args(["apply", "-f"])
.arg(&self.cfg)
.arg("--state-dir")
.arg(&self.state)
.arg("--plan-file")
.arg(plan)
.arg("--yes")
.args(extra)
.output()
.expect("run apply")
}
pub fn apply(&self, extra: &[&str]) -> std::process::Output {
forjar()
.args(["apply", "-f"])
.arg(&self.cfg)
.arg("--state-dir")
.arg(&self.state)
.arg("--yes")
.args(extra)
.output()
.expect("run apply")
}
pub fn converged(&self) -> (bool, bool) {
(self.alpha.exists(), self.bravo.exists())
}
pub fn converge_bravo(&self) {
let out = self.apply(&["-r", "bravo"]);
assert!(out.status.success(), "seed: {}", combined(&out));
assert_eq!(self.converged(), (false, true), "partial stack");
}
}
pub fn planned(dir: &Path) -> (Project, PathBuf) {
let p = project(dir);
let plan_path = dir.join("p.json");
p.save_plan(&plan_path);
(p, plan_path)
}