use std::path::{Path, PathBuf};
use crate::config::{GuestOs, Result, TestbedError};
pub fn mirror_artifacts(
project_dir: &Path,
target_triple: &str,
os: GuestOs,
) -> Result<Vec<PathBuf>> {
let artifacts_dir = project_dir.join(".testbed").join("artifacts");
std::fs::create_dir_all(&artifacts_dir).map_err(|e| TestbedError::Qcow2Error {
message: format!("creating artifacts dir: {e}"),
})?;
let platform_dir = match os {
GuestOs::Windows => artifacts_dir.join("windows"),
GuestOs::Linux => artifacts_dir.join("linux"),
GuestOs::MacOS => artifacts_dir.join("macos"),
};
let _ = std::fs::remove_dir_all(&platform_dir); std::fs::create_dir_all(&platform_dir).map_err(|e| TestbedError::Qcow2Error {
message: format!("creating platform dir: {e}"),
})?;
let build_dir = project_dir.join("target").join(target_triple).join("release");
if !build_dir.exists() {
return Ok(Vec::new());
}
let artifacts = scan_artifacts(&build_dir, os)?;
for artifact in &artifacts {
if let Some(file_name) = artifact.file_name() {
let link_path = platform_dir.join(file_name);
#[cfg(unix)]
std::os::unix::fs::symlink(artifact, &link_path).map_err(|e| TestbedError::Qcow2Error {
message: format!("creating symlink: {e}"),
})?;
}
}
Ok(artifacts)
}
pub fn scan_artifacts(dir: &Path, os: GuestOs) -> Result<Vec<PathBuf>> {
let mut artifacts = Vec::new();
let entries = std::fs::read_dir(dir).map_err(|e| TestbedError::Qcow2Error {
message: format!("reading build dir: {e}"),
})?;
for entry in entries {
let entry = entry.map_err(|e| TestbedError::Qcow2Error {
message: format!("reading dir entry: {e}"),
})?;
let path = entry.path();
if !path.is_file() {
continue;
}
let name = entry.file_name();
let name_str = name.to_string_lossy();
match os {
GuestOs::Windows => {
if name_str.ends_with(".exe") || name_str.ends_with(".dll") {
artifacts.push(path);
}
}
GuestOs::Linux | GuestOs::MacOS => {
let has_no_ext = path.extension().is_none();
let is_so = name_str.ends_with(".so");
if has_no_ext || is_so {
artifacts.push(path);
}
}
}
}
Ok(artifacts)
}