mod common; mod config; mod refractr; use crate::refractr::Refractr; use clap::Parser; use std::path::PathBuf; use std::process; #[cfg(target_family = "unix")] use users; #[cfg(not(target_family = "unix"))] use username; #[derive(Parser)] #[command(name = "refractr")] #[command(version = option_env!("CARGO_PKG_VERSION"))] #[command(about = "An automated pull/push utility for mirroring Git repositories")] #[command(long_about = None)] struct Args { #[arg(short, long, help = "Specify a config file", default_value = get_config_default())] config: Vec, #[arg(short, long, help = "Specify the level of verbosity", action = clap::ArgAction::Count)] verbose: u8, #[arg(short = 'e', long, help = "Output a full, commented config file and exit")] create: bool, #[arg(short = 's', long, help = "Exit on push errors instead of ignoring")] strict: bool, } fn get_config_default() -> &'static str { if cfg!(windows) { "C:\\ProgramData\\refractr\\config.toml" } else { "/etc/refractr/config.toml" } } fn main() -> Result<(), String> { let args = Args::parse(); let refractr = Refractr { docker: match option_env!("REFRACTR_DOCKER") { Some(v) => match v { "true" => true, _ => false, }, None => false }, pid: process::id(), strict: args.strict, unix: cfg!(unix), verbose: args.verbose }; common::verbose(refractr.verbose, 1, format!("Level {} verbosity enabled", refractr.verbose.to_string())); common::verbose(refractr.verbose, 3, format!("Process ID: {}", refractr.pid)); common::verbose(refractr.verbose, 3, format!("Running in Docker: {}", refractr.docker)); common::verbose(refractr.verbose, 2, format!("Checking for create flag")); if args.create { common::verbose(refractr.verbose, 3, format!("Printing sample config")); let example = include_str!("example/config.toml"); println!("{}", example); Ok(()) } else { // warn to avoid root/admin if refractr.unix { if users::get_current_uid() == 0 { common::warning(format!("this program should not ran as root")); } } else { // TODO: print message for Windows } let cfgs = match config::read_config(args.config, &refractr) { Ok(cfgs) => cfgs, Err(e) => freak_out!(e) }; if refractr.verbose >= 2 { // no need to loop over configs if verbose is not at the correct level for i in &cfgs { common::verbose(refractr.verbose, 2, format!("{}", i)); } } common::verbose(refractr.verbose, 1, format!("Config file(s) read successfully")); refractr.run(cfgs) } }