#![allow(dead_code)]
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
pub fn script() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("scripts/ci/changed-class.sh")
}
pub fn output_of(files: &[&str]) -> String {
let mut child = Command::new("bash")
.arg(script())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("bash must run");
child
.stdin
.as_mut()
.expect("stdin")
.write_all(files.join("\n").as_bytes())
.expect("write the file list");
let out = child.wait_with_output().expect("classifier must finish");
assert!(
out.status.success(),
"the classifier exited {:?}: {}{}",
out.status.code(),
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
pub fn field(files: &[&str], key: &str) -> String {
let out = output_of(files);
let want = format!("{key}=");
let hit: Vec<&str> = out.lines().filter_map(|l| l.strip_prefix(&want)).collect();
assert_eq!(
hit.len(),
1,
"the classifier printed {} `{key}=` lines for {files:?}; exactly one is \
the contract:\n{out}",
hit.len()
);
hit[0].to_string()
}
pub fn class_of(files: &[&str]) -> String {
format!("code={}", field(files, "code"))
}
pub fn gates_of(files: &[&str]) -> String {
field(files, "gates")
}
pub fn gate_booleans(files: &[&str]) -> (String, String) {
(field(files, "gate_c"), field(files, "gate_d"))
}
pub fn assert_gates(files: &[&str], want: &str, why: &str) {
assert_eq!(
gates_of(files),
want,
"PMAT-542: {why}. A change touching {files:?} must select `{want}`. \
Selecting too little skips a release build and a surface measurement \
over a change that could move them; selecting too much is the 21.3 \
minutes this ticket exists to stop paying."
);
}
pub fn assert_code(files: &[&str], why: &str) {
assert_eq!(
class_of(files),
"code=true",
"PMAT-237: {why}. A change touching {files:?} must run every heavy job; \
reading it as harmless skips the suite over it."
);
}
pub fn assert_harmless(files: &[&str], why: &str) {
assert_eq!(
class_of(files),
"code=false",
"PMAT-237: {why}. A change touching only {files:?} cannot alter what any \
heavy job measures, and paying forty minutes for it is the waste this \
ticket exists to remove."
);
}
pub fn workflow(rel: &str) -> String {
let p = Path::new(env!("CARGO_MANIFEST_DIR")).join(rel);
std::fs::read_to_string(&p).unwrap_or_else(|e| panic!("read {p:?}: {e}"))
}