#![allow(dead_code)]
use std::fs;
use std::path::Path;
use std::process::Command;
pub fn tool_on_path(tool: &str) -> bool {
Command::new(tool)
.arg("--version")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
pub fn run_git(dir: &Path, args: &[&str]) {
let out = Command::new("git")
.current_dir(dir)
.args(args)
.output()
.unwrap_or_else(|e| panic!("git {:?} failed to spawn: {e}", args));
assert!(
out.status.success(),
"git {:?} failed: stdout={} stderr={}",
args,
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
}
pub fn host_triple() -> String {
let out = Command::new("rustc")
.args(["-vV"])
.output()
.expect("rustc -vV must succeed (cargo is on PATH; rustc is sibling)");
let stdout = String::from_utf8_lossy(&out.stdout);
for line in stdout.lines() {
if let Some(host) = line.strip_prefix("host: ") {
return host.trim().to_string();
}
}
panic!("no `host:` line in `rustc -vV` output:\n{}", stdout);
}
pub fn bootstrap_minimal_cargo_repo(dir: &Path, crate_name: &str) {
fs::write(
dir.join("Cargo.toml"),
format!(
r#"[package]
name = "{crate_name}"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "{crate_name}"
path = "src/main.rs"
"#,
),
)
.unwrap();
fs::create_dir_all(dir.join("src")).unwrap();
fs::write(dir.join("src/main.rs"), "fn main() {}\n").unwrap();
let host = host_triple();
let yaml = format!(
r#"crates:
- name: {crate_name}
path: .
builds:
- id: {crate_name}
binary: {crate_name}
targets:
- {host}
"#,
);
fs::write(dir.join(".anodizer.yaml"), yaml).unwrap();
run_git(dir, &["init", "-q", "-b", "master"]);
run_git(dir, &["config", "user.email", "test@test.com"]);
run_git(dir, &["config", "user.name", "Test"]);
run_git(dir, &["config", "commit.gpgsign", "false"]);
run_git(dir, &["add", "-A"]);
run_git(dir, &["commit", "-q", "-m", "init"]);
}
pub fn walk_files(dir: &Path) -> Vec<(String, std::path::PathBuf)> {
fn inner(root: &Path, dir: &Path, out: &mut Vec<(String, std::path::PathBuf)>) {
let Ok(entries) = fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
inner(root, &path, out);
} else if entry.file_type().map(|t| t.is_file()).unwrap_or(false) {
let rel = path
.strip_prefix(root)
.unwrap_or(&path)
.to_string_lossy()
.replace('\\', "/");
out.push((rel, path));
}
}
}
let mut out = Vec::new();
inner(dir, dir, &mut out);
out.sort_by(|a, b| a.0.cmp(&b.0));
out
}
pub fn sha256_file(path: &Path) -> String {
use sha2::{Digest, Sha256};
let bytes = fs::read(path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()));
let mut hasher = Sha256::new();
hasher.update(&bytes);
format!("sha256:{:x}", hasher.finalize())
}