use crate::publish::platform::{Os, RustTarget};
use anyhow::{Context, Result};
use std::fs;
use std::path::Path;
use std::process::Command;
pub fn copy_dir_recursive(src: &Path, dst: &Path) -> Result<()> {
for entry in fs::read_dir(src).context("reading source directory")? {
let entry = entry?;
let path = entry.path();
let file_name = entry.file_name();
let dest_path = dst.join(&file_name);
if path.is_dir() {
let name = file_name.to_string_lossy();
if name.starts_with('.') {
continue;
}
if matches!(
name.as_ref(),
"target" | "node_modules" | "__pycache__" | ".git" | "zig-cache"
) {
continue;
}
fs::create_dir_all(&dest_path)?;
copy_dir_recursive(&path, &dest_path)?;
} else {
fs::copy(&path, &dest_path)?;
}
}
Ok(())
}
pub fn copy_optional_file(workspace_root: &Path, filename: &str, dst: &Path) -> Result<()> {
let src = workspace_root.join(filename);
if src.exists() {
fs::copy(&src, dst.join(filename)).with_context(|| format!("copying {filename}"))?;
}
Ok(())
}
pub(super) fn fix_macos_dylib_id(target: &RustTarget, path: &Path, shared_lib: &str) -> Result<()> {
if target.os != Os::MacOs {
return Ok(());
}
let status = Command::new("install_name_tool")
.arg("-id")
.arg(format!("@rpath/{shared_lib}"))
.arg(path)
.status()
.with_context(|| format!("running install_name_tool for {}", path.display()))?;
if !status.success() {
anyhow::bail!("install_name_tool failed for {}", path.display());
}
Ok(())
}