use std::collections::BTreeMap;
use std::env;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::thread;
use std::time::Duration;
use failure::format_err;
use rexpect::{session::PtyReplSession, spawn_bash};
use storage_proofs_core::parameter_cache::ParameterData;
use tempfile::tempdir;
pub struct FakeIpfsBin {
bin_path: PathBuf,
}
impl FakeIpfsBin {
pub fn new() -> FakeIpfsBin {
FakeIpfsBin {
bin_path: cargo_bin("fakeipfsadd"),
}
}
pub fn compute_checksum<P: AsRef<Path>>(&self, path: P) -> Result<String, failure::Error> {
let output = Command::new(&self.bin_path)
.arg("add")
.arg("-Q")
.arg(path.as_ref())
.output()?;
if !output.status.success() {
Err(format_err!(
"{:?} produced non-zero exit code",
&self.bin_path
))
} else {
Ok(String::from_utf8(output.stdout)?.trim().to_string())
}
}
pub fn bin_path(&self) -> &Path {
&self.bin_path
}
}
pub fn target_dir() -> PathBuf {
env::current_exe()
.ok()
.map(|mut path| {
path.pop();
if path.ends_with("deps") {
path.pop();
}
path
})
.expect("failed to get current exe path")
}
pub fn cargo_bin<S: AsRef<str>>(name: S) -> PathBuf {
target_dir().join(format!("{}{}", name.as_ref(), env::consts::EXE_SUFFIX))
}
pub fn spawn_bash_with_retries(
retries: u8,
timeout: Option<u64>,
) -> Result<PtyReplSession, rexpect::errors::Error> {
let result = spawn_bash(timeout);
if result.is_ok() || retries == 0 {
result
} else {
let sleep_d = Duration::from_millis(5000 / u64::from(retries));
eprintln!(
"failed to spawn pty: {} retries remaining - sleeping {:?}",
retries, sleep_d
);
thread::sleep(sleep_d);
spawn_bash_with_retries(retries - 1, timeout)
}
}
pub fn tmp_manifest(
opt_manifest: Option<BTreeMap<String, ParameterData>>,
) -> Result<PathBuf, failure::Error> {
let manifest_dir = tempdir()?;
let mut pbuf = manifest_dir.keep();
pbuf.push("parameters.json");
let mut file = File::create(&pbuf)?;
if let Some(map) = opt_manifest {
serde_json::to_writer(&mut file, &map)?;
}
Ok(pbuf)
}