#![allow(dead_code)]
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
use tempfile::TempDir;
pub struct SmokeEnv {
pub workdir: TempDir,
pub fixture: PathBuf,
pub manifest: PathBuf,
pub cache: PathBuf,
}
impl SmokeEnv {
pub fn workdir_path(&self) -> &Path {
self.workdir.path()
}
}
fn run_git(cwd: &Path, args: &[&str]) {
let out = Command::new("git")
.current_dir(cwd)
.args(args)
.output()
.expect("git binary must be on PATH");
assert!(
out.status.success(),
"git {args:?} in {} failed: {}",
cwd.display(),
String::from_utf8_lossy(&out.stderr)
);
}
fn copy_dir_recursive(src: &Path, dst: &Path) {
std::fs::create_dir_all(dst).unwrap();
for entry in std::fs::read_dir(src).unwrap() {
let entry = entry.unwrap();
let from = entry.path();
let to = dst.join(entry.file_name());
if from.is_dir() {
copy_dir_recursive(&from, &to);
} else {
std::fs::copy(&from, &to).unwrap();
}
}
}
fn fixture_src() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("fixtures")
.join("smoke")
}
fn render_template(template_path: &Path, fixture: &Path, workdir: &Path, out: &Path) {
let raw = std::fs::read_to_string(template_path)
.unwrap_or_else(|_| panic!("read template {}", template_path.display()));
let rendered = raw
.replace("${SMOKE_FIXTURE}", &fixture.display().to_string())
.replace("${WORKDIR}", &workdir.display().to_string());
std::fs::write(out, rendered).unwrap();
}
fn git_init_node_a(node_a: &Path) {
run_git(node_a, &["init", "--initial-branch=main", "--quiet"]);
run_git(node_a, &["config", "user.email", "smoke@example.com"]);
run_git(node_a, &["config", "user.name", "Smoke"]);
run_git(node_a, &["config", "commit.gpgsign", "false"]);
run_git(node_a, &["add", "."]);
run_git(node_a, &["commit", "-m", "initial", "--quiet"]);
run_git(node_a, &["symbolic-ref", "HEAD", "refs/heads/main"]);
}
pub fn setup_smoke_fixture() -> SmokeEnv {
setup_with_template("repolith.toml.template")
}
pub fn setup_smoke_fixture_failfast() -> SmokeEnv {
setup_with_template("repolith-failfast.toml.template")
}
fn setup_with_template(template_name: &str) -> SmokeEnv {
let workdir = TempDir::new().expect("tempdir for smoke env");
let fixture = workdir.path().join("fixture");
copy_dir_recursive(&fixture_src(), &fixture);
let node_a = fixture.join("node-a");
if node_a.is_dir() {
git_init_node_a(&node_a);
}
let manifest = workdir.path().join("repolith.toml");
render_template(
&fixture_src().join(template_name),
&fixture,
workdir.path(),
&manifest,
);
let cache = workdir.path().join("cache.db");
SmokeEnv {
workdir,
fixture,
manifest,
cache,
}
}
pub fn run_repolith(env: &SmokeEnv, args: &[&str]) -> Output {
let bin = env!("CARGO_BIN_EXE_repolith");
Command::new(bin)
.arg("--manifest")
.arg(&env.manifest)
.arg("--cache-path")
.arg(&env.cache)
.args(args)
.env_remove("RUST_LOG")
.output()
.expect("spawn repolith")
}
pub fn add_commit_to_node_a(env: &SmokeEnv, msg: &str) {
let node_a = env.fixture.join("node-a");
std::fs::write(node_a.join("CHANGES.md"), format!("{msg}\n")).unwrap();
run_git(&node_a, &["add", "."]);
run_git(&node_a, &["commit", "-m", msg, "--quiet"]);
}