use std::{ ffi::OsStr, fs, path::Path, process::{Command, Stdio}, }; use walkdir::WalkDir; use crate::error::Error; pub fn run_external_command, S1: AsRef, I: IntoIterator>( cmd: S0, args: I, mute: bool, ) -> Result<(), Error> { let mut command = Command::new(cmd); command.args(args); if mute { command.stderr(Stdio::null()).stdout(Stdio::null()); } log::trace!("Run external: {:?}", command); let status = command.status()?; if status.success() { Ok(()) } else { Err(Error::ExternalCommandFailed) } } pub fn copy_dir_recursive, D: AsRef>(src: S, dst: D) -> Result<(), Error> { let src = src.as_ref(); let dst = dst.as_ref(); for entry in WalkDir::new(src).follow_links(false) { let entry = entry?; let src_path = entry.path(); let rel_path = src_path .strip_prefix(src) .map_err(|_| Error::InvalidPath(src_path.into()))?; let dst_path = dst.join(rel_path); if entry.file_type().is_dir() { fs::create_dir_all(dst_path)?; } else { log::trace!("Copy {} -> {}", src_path.display(), dst_path.display()); fs::copy(src_path, dst_path)?; } } Ok(()) }