#[macro_use] extern crate log; mod builder; mod error; mod linker; mod peeker; use builder::build_tree; use error::Errors; use linker::link_tree; use log::LevelFilter; use peeker::peek_tree; use std::env; use std::path::PathBuf; use structopt::StructOpt; #[derive(StructOpt)] struct Opt { #[structopt(short, long)] template_dir: Option, #[structopt(short, long)] build_dir: Option, #[structopt(short, long)] link_dir: Option, #[structopt(long = "variables")] variables_path: Option, #[structopt(short, long)] print_variables: bool, #[structopt(short, parse(from_occurrences))] verbosity: u8, flags: Vec, } #[derive(Debug)] pub struct Config { template_dir: PathBuf, build_dir: PathBuf, link_dir: PathBuf, variables_path: PathBuf, flags: Vec, } #[tokio::main] async fn main() { match run().await { Ok(_) => {} Err(errors) => errors.log(), } } async fn run() -> Result<(), Errors> { let opt = Opt::from_args(); let filter_level = match opt.verbosity { 0 => LevelFilter::Warn, 1 => LevelFilter::Info, 2 => LevelFilter::Debug, _ => LevelFilter::Trace, }; pretty_env_logger::formatted_builder() .filter_level(filter_level) .init(); let xdg_dirs = xdg::BaseDirectories::with_prefix("dotfiles").unwrap(); let cfg = Config { template_dir: opt .template_dir .unwrap_or_else(|| xdg_dirs.create_config_directory("tree").expect("xdg")), build_dir: opt .build_dir .unwrap_or_else(|| xdg_dirs.create_cache_directory("").expect("xdg")), link_dir: opt .link_dir .unwrap_or_else(|| env::var("HOME").expect("$HOME").into()), variables_path: opt .variables_path .unwrap_or_else(|| xdg_dirs.get_config_file("variables.toml")), flags: opt.flags, }; if opt.print_variables { info!("peeking tree"); peek_tree(&cfg).await?; } else { info!("building tree"); build_tree(&cfg).await?; info!("linking tree"); link_tree(&cfg).await?; } Ok(()) }