use std::fs;
use std::path::{Path, PathBuf};
use super::*;
use crate::types::ErrBox;
use crate::utils;
pub fn get_plugin_dir(owner: &str, name: &str, version: &str) -> Result<PathBuf, ErrBox> {
let data_dir = utils::get_user_data_dir()?;
Ok(data_dir.join("binaries").join(owner).join(name).join(version))
}
pub async fn setup_plugin<'a>(
plugin_manifest: &'a mut PluginsManifest,
checksum_url: &utils::ChecksumUrl,
bin_dir: &Path,
) -> Result<&'a BinaryManifestItem, ErrBox> {
let plugin_file_bytes = utils::download_file(&checksum_url.url).await?;
if let Some(checksum) = &checksum_url.checksum {
utils::verify_sha256_checksum(&plugin_file_bytes, &checksum)?;
}
let plugin_file = read_plugin_file(&plugin_file_bytes)?;
let identifier = plugin_file.get_identifier();
println!(
"Installing {}/{} {}...",
plugin_file.owner, plugin_file.name, plugin_file.version
);
if let Err(err) = semver::Version::parse(&plugin_file.version) {
return err!(
"The version found in the binary manifest file was invalid. {}",
err.to_string()
);
}
plugin_manifest.set_identifier_for_url(checksum_url.url.clone(), identifier.clone());
if plugin_manifest.get_binary(&identifier).is_some() {
return Ok(plugin_manifest.get_binary(&identifier).unwrap());
}
let url = plugin_file.get_url()?;
let download_type = plugin_file.get_download_type()?;
let url_file_bytes = utils::download_file(url).await?;
utils::verify_sha256_checksum(&url_file_bytes, plugin_file.get_url_checksum()?)?;
let plugin_cache_dir_path = get_plugin_dir(&plugin_file.owner, &plugin_file.name, &plugin_file.version)?;
let _ignore = fs::remove_dir_all(&plugin_cache_dir_path);
fs::create_dir_all(&plugin_cache_dir_path)?;
let binary_path = plugin_cache_dir_path.join(plugin_file.get_binary_path()?);
match download_type {
DownloadType::Zip => utils::extract_zip(&url_file_bytes, &plugin_cache_dir_path)?,
DownloadType::Binary => fs::write(&binary_path, &url_file_bytes)?,
}
if let Some(post_install_script) = plugin_file.get_post_install_script()? {
utils::run_shell_command(&plugin_cache_dir_path, post_install_script)?;
}
let file_name = binary_path.to_string_lossy().to_string();
let item = BinaryManifestItem {
owner: plugin_file.owner.clone(),
name: plugin_file.name.clone(),
version: plugin_file.version,
created_time: utils::get_time_secs(),
file_name: file_name.clone(),
};
let identifier = item.get_identifier();
let command_name = item.get_command_name();
plugin_manifest.add_binary(item);
create_path_script(&bin_dir, &command_name)?;
Ok(plugin_manifest.get_binary(&identifier).unwrap())
}