use crate::common::{repository, utils, config::{ModToml, Module}}; #[derive(Debug)] pub struct NamedModule(pub String, pub Module); impl From<&ModToml> for Vec { fn from(config: &ModToml) -> Self { config.modules.iter() .map(|v| NamedModule(v.0.clone(), v.1.clone())) .collect() } } impl ToString for NamedModule { fn to_string(&self) -> String { self.0.clone() } } fn install_mod(m: &NamedModule) { println!("Installing module {}...", m.0); 'content_iter: for entry in &m.1.content { let src = std::path::Path::new("repo").join(&entry.0); if src.is_file() { if let Err(err) = std::fs::copy(src, entry.1) { println!("Failed to copy {}:\n{}", entry.0, err); } } else { let dst = std::path::Path::new(entry.1.as_str()); if let Err(err) = std::fs::create_dir_all(dst) { println!("Failed to create directory {}:\n{}", entry.1, err); continue 'content_iter; } let pb = indicatif::ProgressBar::new(0); pb.set_style(indicatif::ProgressStyle::with_template("{spinner} [{wide_bar}] {pos:>6}/{len:6}").unwrap().progress_chars("#>-")); if let Err(err) = utils::remove_dir(dst, &m.1.ignore, &pb) { println!("Failed to delete directory:\n{}", err); continue 'content_iter; } if let Err(err) = utils::copy_dir(&src, dst, &[], &pb) { println!("Failed to copy directory:\n{}", err); } } } } fn collect_mod(m: &NamedModule) { println!("Collecting module {}...", m.0); 'content_iter: for entry in &m.1.content { let dst = std::path::Path::new("repo").join(entry.0.as_str()); let src = std::path::Path::new(entry.1.as_str()); if src.is_file() { if let Err(err) = std::fs::copy(src, dst) { println!("Failed to copy {}:\n{}", entry.1, err); } } else { let pb = indicatif::ProgressBar::new(0); pb.set_style(indicatif::ProgressStyle::with_template("{spinner} [{wide_bar}] {pos:>6}/{len:6}").unwrap().progress_chars("#>-")); if let Err(err) = utils::remove_dir(&dst, &[], &pb) { println!("Failed to delete directory:\n{}", err); continue 'content_iter; } if let Err(err) = std::fs::create_dir_all(&dst) { println!("Failed to create directory {}:\n{}", entry.0, err); continue 'content_iter; } if let Err(err) = utils::copy_dir(src, &dst, &m.1.ignore, &pb) { println!("Failed to copy source content:\n{}", err); continue 'content_iter; } } } } pub fn install(mods: &[NamedModule]) { for m in mods { install_mod(m); if let Some(on_install) = &m.1.on_install { match std::process::Command::new("sh").arg("-c").arg(on_install).status() { Ok(status) => println!("Install command exited with {status}"), Err(err) => println!("Failed to execute on install command '{on_install}' with error:\n{err}") } } } } pub fn collect(mods: &[NamedModule]) { for m in mods { collect_mod(m); } } pub fn upload String>(get_commit_msg: F) { if !repository::is_clean() { let msg = get_commit_msg(); if !repository::commit_changes(&msg) { println!("Failed to commit"); return; } } if !repository::push_repo() { println!("Failed to push to origin"); } }