use std::{ env::set_current_dir, fs::{exists, read_to_string, File}, path::{absolute, Path}, process::{exit, Stdio}, }; use action::Action; use cfg::Config; use clap::Parser; use colored::Colorize; use execute::{command_args, Execute}; use log::{debug, error, info, trace, warn}; use prelude::abspath; mod action; mod cfg; mod crates; mod logging; mod prelude; mod source; mod tags; fn main() -> Result<(), Box> { logging::setup_logger()?; info!(target: "item", "user: {}", whoami::username()); info!(target: "item", "distro: {}", whoami::distro()); let action = Action::parse(); match action { Action::Sync { config_path } => { trace!("fetching config dir... {config_path:?}"); if let Some(config_path) = abspath(&config_path.unwrap_or("~/.syncr".into())) { trace!("setting config dir as cwd... {config_path}"); set_current_dir(config_path)?; } let config = Config::parse(&abspath("./syncr.toml").unwrap())?; info!("syncing \"{}\"...", config.title.bold()); info!("updating sources..."); let mut available_sources = vec![]; for (name, source) in &config.source { debug!("checking {name}..."); if !source.available() { warn!("source \"{name}\" unavailable."); } else { info!("source \"{name}\" available!"); available_sources.push(source); } } if available_sources.len() == 0 { error!("{}", "sync impossible; no sources.".bold()); exit(1); } let oldpwd = absolute(".")?; for source in available_sources { // cd to source dir source.go_to_dir()?; for (mut path, c) in source.get_crates()? { path.pop(); set_current_dir(absolute(path)?)?; info!("Syncing crate: {}...", c.manifest.crate_info.name); c.install_packages(); if let Err(e) = c.run_actions() { error!("action failed: {e}"); } set_current_dir(&oldpwd)?; // i hate this but im lazy okay source.go_to_dir()?; } } set_current_dir(oldpwd)?; info!("Completed sync."); } _ => { println!("{action:#?}"); } } Ok(()) }