use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::{Path, PathBuf};
use symlink::symlink_dir;
use tempfile::{Builder, TempDir};
pub struct TestCandidate {
pub name: &'static str,
pub versions: Vec<&'static str>,
pub current_version: &'static str,
}
#[derive(Default)]
pub struct VirtualEnv {
pub cli_version: String,
pub native_version: String,
pub candidate: Option<TestCandidate>,
}
pub fn virtual_env(virtual_env: VirtualEnv) -> TempDir {
let sdkman_dir = prepare_sdkman_dir();
let var_path = Path::new("var");
write_file(
sdkman_dir.path(),
var_path,
"version",
virtual_env.cli_version,
);
write_file(
sdkman_dir.path(),
var_path,
"version_native",
virtual_env.native_version,
);
write_file(
sdkman_dir.path(),
Path::new("var"),
"candidates",
virtual_env
.candidate
.as_ref()
.map_or_else(|| "", |c| c.name)
.to_string(),
);
if let Some(candidate) = virtual_env.candidate {
for version in candidate.versions {
let location = format!("candidates/{}/{}/bin/", candidate.name, version);
let content = format!(
"\
#!/bin/bash
echo Running {} {}
",
candidate.name, version
);
write_file(
sdkman_dir.path(),
Path::new(&location),
candidate.name,
content,
);
}
let version_location = PathBuf::from(format!(
"candidates/{}/{}",
candidate.name, candidate.current_version
));
let current_link_location = PathBuf::from(format!("candidates/{}/current", candidate.name));
let absolute_version = sdkman_dir.path().join(version_location.as_path());
let absolute_current_link = sdkman_dir.path().join(current_link_location.as_path());
symlink_dir(absolute_version, absolute_current_link)
.expect("cannot create current symlink");
}
return sdkman_dir;
}
pub fn prepare_sdkman_dir() -> TempDir {
Builder::new()
.prefix(".sdkman-")
.tempdir()
.expect("could not prepare SDKMAN_DIR")
}
pub fn write_file(
temp_dir: &Path,
relative_path: &Path,
file_name: &str,
content: String,
) -> PathBuf {
let absolute_path = temp_dir.join(relative_path);
create_dir_all(absolute_path.to_owned()).expect("could not create nested dirs");
let file_path = absolute_path.join(file_name);
let mut file = File::create(&file_path).expect("could not create file");
write!(file, "{}", content.to_string()).expect("could not write to file");
file_path
}