97 lines
2.7 KiB
Rust
97 lines
2.7 KiB
Rust
/// Local context: execute commands locally
|
|
/// Context driver: Does nothing
|
|
use super::api::ContextDriver;
|
|
use std::io;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
pub struct LocalDriver;
|
|
|
|
impl ContextDriver for LocalDriver {
|
|
fn ensure_available(&self, src: &Path, dest_root: &str) -> io::Result<PathBuf> {
|
|
let dest_root_path = Path::new(dest_root);
|
|
let dest = dest_root_path.join(src.file_name().unwrap_or(src.as_os_str()));
|
|
|
|
if src != dest {
|
|
// Copy src inside dest_root
|
|
self.copy_path(src, &dest)?;
|
|
}
|
|
dest.canonicalize()
|
|
}
|
|
|
|
fn create_temp_dir(&self) -> io::Result<String> {
|
|
let temp_dir = tempfile::Builder::new().prefix("pkh-").tempdir()?;
|
|
Ok(temp_dir.keep().to_string_lossy().to_string())
|
|
}
|
|
|
|
fn retrieve_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
|
self.copy_path(src, dest)
|
|
}
|
|
|
|
fn list_files(&self, path: &Path) -> io::Result<Vec<PathBuf>> {
|
|
let mut entries = Vec::new();
|
|
for entry in std::fs::read_dir(path)? {
|
|
let entry = entry?;
|
|
entries.push(entry.path());
|
|
}
|
|
Ok(entries)
|
|
}
|
|
|
|
fn run(
|
|
&self,
|
|
program: &str,
|
|
args: &[String],
|
|
env: &[(String, String)],
|
|
cwd: Option<&str>,
|
|
) -> io::Result<std::process::ExitStatus> {
|
|
let mut cmd = Command::new(program);
|
|
cmd.args(args).envs(env.iter().map(|(k, v)| (k, v)));
|
|
if let Some(dir) = cwd {
|
|
cmd.current_dir(dir);
|
|
}
|
|
cmd.status()
|
|
}
|
|
|
|
fn run_output(
|
|
&self,
|
|
program: &str,
|
|
args: &[String],
|
|
env: &[(String, String)],
|
|
cwd: Option<&str>,
|
|
) -> io::Result<std::process::Output> {
|
|
let mut cmd = Command::new(program);
|
|
cmd.args(args).envs(env.iter().map(|(k, v)| (k, v)));
|
|
if let Some(dir) = cwd {
|
|
cmd.current_dir(dir);
|
|
}
|
|
cmd.output()
|
|
}
|
|
|
|
fn copy_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
|
copy_dir_recursive(src, dest)
|
|
}
|
|
|
|
fn read_file(&self, path: &Path) -> io::Result<String> {
|
|
std::fs::read_to_string(path)
|
|
}
|
|
|
|
fn write_file(&self, path: &Path, content: &str) -> io::Result<()> {
|
|
std::fs::write(path, content)
|
|
}
|
|
}
|
|
|
|
fn copy_dir_recursive(src: &Path, dest: &Path) -> io::Result<()> {
|
|
if src.is_dir() {
|
|
std::fs::create_dir_all(dest)?;
|
|
for entry in std::fs::read_dir(src)? {
|
|
let entry = entry?;
|
|
let path = entry.path();
|
|
let dest_path = dest.join(entry.file_name());
|
|
copy_dir_recursive(&path, &dest_path)?;
|
|
}
|
|
} else {
|
|
std::fs::copy(src, dest)?;
|
|
}
|
|
Ok(())
|
|
}
|